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