1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** ThreadX Component */
17 /** */
18 /** Module Manager */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define TX_SOURCE_CODE
24
25 #include "tx_api.h"
26 #include "tx_mutex.h"
27 #include "tx_queue.h"
28 #include "tx_thread.h"
29 #include "txm_module.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _txm_module_manager_start PORTABLE C */
37 /* 6.1.3 */
38 /* AUTHOR */
39 /* */
40 /* Scott Larson, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function starts execution of the specified module. */
45 /* */
46 /* INPUT */
47 /* */
48 /* module_instance Module instance pointer */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* status Completion status */
53 /* */
54 /* CALLS */
55 /* */
56 /* _txm_module_manager_thread_create Module thread create */
57 /* _tx_mutex_get Get protection mutex */
58 /* _tx_mutex_put Release protection mutex */
59 /* _tx_queue_create Create module callback queue */
60 /* _tx_queue_delete Delete module callback queue */
61 /* _tx_thread_resume Resume start thread */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* Application code */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 09-30-2020 Scott Larson Initial Version 6.1 */
72 /* 12-31-2020 Scott Larson Modified comment(s), */
73 /* resulting in version 6.1.3 */
74 /* */
75 /**************************************************************************/
_txm_module_manager_start(TXM_MODULE_INSTANCE * module_instance)76 UINT _txm_module_manager_start(TXM_MODULE_INSTANCE *module_instance)
77 {
78
79 UINT status;
80
81
82 /* Determine if the module manager has not been initialized yet. */
83 if (_txm_module_manager_ready != TX_TRUE)
84 {
85
86 /* Module manager has not been initialized. */
87 return(TX_NOT_AVAILABLE);
88 }
89
90 /* Determine if the module is valid. */
91 if (module_instance == TX_NULL)
92 {
93
94 /* Invalid module pointer. */
95 return(TX_PTR_ERROR);
96 }
97
98 /* Get module manager protection mutex. */
99 _tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
100
101 /* Determine if the module instance is valid. */
102 if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
103 {
104
105 /* Release the protection mutex. */
106 _tx_mutex_put(&_txm_module_manager_mutex);
107
108 /* Invalid module pointer. */
109 return(TX_PTR_ERROR);
110 }
111
112 /* Determine if the module instance is in the loaded state. */
113 if ((module_instance -> txm_module_instance_state != TXM_MODULE_LOADED) && (module_instance -> txm_module_instance_state != TXM_MODULE_STOPPED))
114 {
115
116 /* Release the protection mutex. */
117 _tx_mutex_put(&_txm_module_manager_mutex);
118
119 /* Return error if the module is not ready. */
120 return(TX_START_ERROR);
121 }
122
123 /* Check the priorities of the start/stop and callback request threads. */
124 if (module_instance -> txm_module_instance_start_stop_priority < module_instance -> txm_module_instance_maximum_priority ||
125 module_instance -> txm_module_instance_callback_priority < module_instance -> txm_module_instance_maximum_priority)
126 {
127
128 /* Release the protection mutex. */
129 _tx_mutex_put(&_txm_module_manager_mutex);
130
131 /* At least one thread has an invalid priority. */
132 return(TX_PRIORITY_ERROR);
133 }
134
135 /* Create the module's callback request queue. */
136 status = _tx_queue_create(&(module_instance -> txm_module_instance_callback_request_queue), "Module Callback Request Queue", (sizeof(TXM_MODULE_CALLBACK_MESSAGE)/sizeof(ULONG)),
137 module_instance -> txm_module_instance_callback_request_queue_area, sizeof(module_instance -> txm_module_instance_callback_request_queue_area));
138
139 /* Determine if there was an error. */
140 if (status)
141 {
142
143 /* Release the protection mutex. */
144 _tx_mutex_put(&_txm_module_manager_mutex);
145
146 /* Return error if the module is not ready. */
147 return(TX_START_ERROR);
148 }
149
150 /* Create the module start thread. */
151 status = _txm_module_manager_thread_create(&(module_instance -> txm_module_instance_start_stop_thread),
152 "Module Start Thread",
153 module_instance -> txm_module_instance_shell_entry_function,
154 module_instance -> txm_module_instance_start_thread_entry,
155 module_instance -> txm_module_instance_application_module_id,
156 module_instance -> txm_module_instance_start_stop_stack_start_address,
157 module_instance -> txm_module_instance_start_stop_stack_size,
158 (UINT) module_instance -> txm_module_instance_start_stop_priority,
159 (UINT) module_instance -> txm_module_instance_start_stop_priority,
160 TXM_MODULE_TIME_SLICE,
161 TX_DONT_START,
162 sizeof(TX_THREAD),
163 module_instance);
164
165 /* Determine if the thread create was successful. */
166 if (status != TX_SUCCESS)
167 {
168
169 /* Delete the callback notification queue. */
170 _tx_queue_delete(&(module_instance -> txm_module_instance_callback_request_queue));
171
172 /* Release the protection mutex. */
173 _tx_mutex_put(&_txm_module_manager_mutex);
174
175 /* Return the error status. */
176 return(status);
177 }
178
179 /* Create the module callback thread. */
180 status = _txm_module_manager_thread_create(&(module_instance -> txm_module_instance_callback_request_thread),
181 "Module Callback Request Thread",
182 module_instance -> txm_module_instance_shell_entry_function,
183 module_instance -> txm_module_instance_callback_request_thread_entry,
184 module_instance -> txm_module_instance_application_module_id,
185 module_instance -> txm_module_instance_callback_stack_start_address,
186 module_instance -> txm_module_instance_callback_stack_size,
187 (UINT) module_instance -> txm_module_instance_callback_priority,
188 (UINT) module_instance -> txm_module_instance_callback_priority,
189 TX_NO_TIME_SLICE,
190 TX_DONT_START,
191 sizeof(TX_THREAD),
192 module_instance);
193
194 /* Determine if the thread create was successful. */
195 if (status != TX_SUCCESS)
196 {
197
198 /* Terminate the start thread. */
199 _tx_thread_terminate(&(module_instance -> txm_module_instance_start_stop_thread));
200
201 /* Delete the start thread. */
202 _tx_thread_delete(&(module_instance -> txm_module_instance_start_stop_thread));
203
204 /* Delete the callback notification queue. */
205 _tx_queue_delete(&(module_instance -> txm_module_instance_callback_request_queue));
206
207 /* Release the protection mutex. */
208 _tx_mutex_put(&_txm_module_manager_mutex);
209
210 /* Return the error status. */
211 return(status);
212 }
213
214
215 /* Set the module state to started. */
216 module_instance -> txm_module_instance_state = TXM_MODULE_STARTED;
217
218 /* Release the protection mutex. */
219 _tx_mutex_put(&_txm_module_manager_mutex);
220
221 /* Resume the module's start thread. */
222 _tx_thread_resume(&(module_instance -> txm_module_instance_start_stop_thread));
223
224 /* Return success. */
225 return(TX_SUCCESS);
226 }
227
228