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