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_initialize.h"
27 #include "tx_thread.h"
28 #include "tx_timer.h"
29 #include "tx_queue.h"
30 #include "tx_event_flags.h"
31 #include "tx_semaphore.h"
32 #include "tx_mutex.h"
33 #include "tx_block_pool.h"
34 #include "tx_byte_pool.h"
35 #include "txm_module.h"
36 #include "txm_module_manager_util.h"
37
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _txm_module_manager_object_pointer_get_extended PORTABLE C */
44 /* 6.1 */
45 /* AUTHOR */
46 /* */
47 /* Scott Larson, Microsoft Corporation */
48 /* */
49 /* DESCRIPTION */
50 /* */
51 /* This function retrieves the object pointer of a particular type */
52 /* with a particular name. If the object is not found, an error is */
53 /* returned. Otherwise, if the object is found, the address of that */
54 /* object is placed in object_ptr. */
55 /* */
56 /* INPUT */
57 /* */
58 /* object_type Type of object, as follows: */
59 /* */
60 /* TXM_BLOCK_POOL_OBJECT */
61 /* TXM_BYTE_POOL_OBJECT */
62 /* TXM_EVENT_FLAGS_OBJECT */
63 /* TXM_MUTEX_OBJECT */
64 /* TXM_QUEUE_OBJECT */
65 /* TXM_SEMAPHORE_OBJECT */
66 /* TXM_THREAD_OBJECT */
67 /* TXM_TIMER_OBJECT */
68 /* search_name Name to search for */
69 /* search_name_length Length of the name excluding */
70 /* null-terminator */
71 /* object_ptr Pointer to the object */
72 /* */
73 /* OUTPUT */
74 /* */
75 /* TX_SUCCESS Successful completion */
76 /* TX_PTR_ERROR Invalid name or object ptr */
77 /* TX_OPTION_ERROR Invalid option type */
78 /* TX_NO_INSTANCE Object not found */
79 /* */
80 /* CALLS */
81 /* */
82 /* _txm_module_manager_object_name_compare */
83 /* String compare routine */
84 /* [_txm_module_manager_*_object_pointer_get] */
85 /* Optional external component */
86 /* object pointer get */
87 /* */
88 /* CALLED BY */
89 /* */
90 /* Application code */
91 /* */
92 /* RELEASE HISTORY */
93 /* */
94 /* DATE NAME DESCRIPTION */
95 /* */
96 /* 09-30-2020 Scott Larson Initial Version 6.1 */
97 /* */
98 /**************************************************************************/
_txm_module_manager_object_pointer_get_extended(UINT object_type,CHAR * search_name,UINT search_name_length,VOID ** object_ptr)99 UINT _txm_module_manager_object_pointer_get_extended(UINT object_type, CHAR *search_name, UINT search_name_length, VOID **object_ptr)
100 {
101
102 TX_INTERRUPT_SAVE_AREA
103
104 TX_THREAD *thread_ptr;
105 TX_TIMER *timer_ptr;
106 TX_QUEUE *queue_ptr;
107 TX_EVENT_FLAGS_GROUP *events_ptr;
108 TX_SEMAPHORE *semaphore_ptr;
109 TX_MUTEX *mutex_ptr;
110 TX_BLOCK_POOL *block_pool_ptr;
111 TX_BYTE_POOL *byte_pool_ptr;
112 ULONG i;
113 UINT status;
114 TXM_MODULE_INSTANCE *module_instance;
115
116
117 /* Determine if the name or object pointer are NULL. */
118 if ((search_name == TX_NULL) || (object_ptr == TX_NULL))
119 {
120
121 /* Return error! */
122 return(TX_PTR_ERROR);
123 }
124
125 /* Default status to not found. */
126 status = TX_NO_INSTANCE;
127
128 /* Set the return value to NULL. */
129 *object_ptr = TX_NULL;
130
131 /* Disable interrupts. */
132 TX_DISABLE
133
134 /* Temporarily disable preemption. This will keep other threads from creating and deleting threads. */
135 _tx_thread_preempt_disable++;
136
137 /* Restore interrupts. */
138 TX_RESTORE
139
140 /* Process relative to the object type. */
141 switch(object_type)
142 {
143
144 /* Determine if a thread object is requested. */
145 case TXM_THREAD_OBJECT:
146 {
147
148 /* Loop to find the first matching thread. */
149 i = 0;
150 thread_ptr = _tx_thread_created_ptr;
151 while (i < _tx_thread_created_count)
152 {
153
154 /* Do we have a match? */
155 if (_txm_module_manager_object_name_compare(search_name, search_name_length, thread_ptr -> tx_thread_name))
156 {
157
158 /* Yes, we found it - return the necessary info! */
159 *object_ptr = (VOID *) thread_ptr;
160
161 /* Set the the status to success! */
162 status = TX_SUCCESS;
163 break;
164 }
165
166 /* Increment the counter. */
167 i++;
168
169 /* Move to next thread. */
170 thread_ptr = thread_ptr -> tx_thread_created_next;
171 }
172 break;
173 }
174
175 /* Determine if a timer object is requested. */
176 case TXM_TIMER_OBJECT:
177 {
178
179 /* Loop to find the first matching timer. */
180 i = 0;
181 timer_ptr = _tx_timer_created_ptr;
182 while (i < _tx_timer_created_count)
183 {
184
185 /* Do we have a match? */
186 if (_txm_module_manager_object_name_compare(search_name, search_name_length, timer_ptr -> tx_timer_name))
187 {
188
189 /* Yes, we found it - return the necessary info! */
190 *object_ptr = (VOID *) timer_ptr;
191
192 /* Set the the status to success! */
193 status = TX_SUCCESS;
194 break;
195 }
196
197 /* Increment the counter. */
198 i++;
199
200 /* Move to next timer. */
201 timer_ptr = timer_ptr -> tx_timer_created_next;
202 }
203 break;
204 }
205
206 /* Determine if a queue object is requested. */
207 case TXM_QUEUE_OBJECT:
208 {
209
210 /* Loop to find the first matching queue. */
211 i = 0;
212 queue_ptr = _tx_queue_created_ptr;
213 while (i < _tx_queue_created_count)
214 {
215
216 /* Do we have a match? */
217 if (_txm_module_manager_object_name_compare(search_name, search_name_length, queue_ptr -> tx_queue_name))
218 {
219
220 /* Yes, we found it - return the necessary info! */
221 *object_ptr = (VOID *) queue_ptr;
222
223 /* Set the the status to success! */
224 status = TX_SUCCESS;
225 break;
226 }
227
228 /* Increment the counter. */
229 i++;
230
231 /* Move to next queue. */
232 queue_ptr = queue_ptr -> tx_queue_created_next;
233 }
234 break;
235 }
236
237 /* Determine if a event flags object is requested. */
238 case TXM_EVENT_FLAGS_OBJECT:
239 {
240
241 /* Loop to find the first matching event flags group. */
242 i = 0;
243 events_ptr = _tx_event_flags_created_ptr;
244 while (i < _tx_event_flags_created_count)
245 {
246
247 /* Do we have a match? */
248 if (_txm_module_manager_object_name_compare(search_name, search_name_length, events_ptr -> tx_event_flags_group_name))
249 {
250
251 /* Yes, we found it - return the necessary info! */
252 *object_ptr = (VOID *) events_ptr;
253
254 /* Set the the status to success! */
255 status = TX_SUCCESS;
256 break;
257 }
258
259 /* Increment the counter. */
260 i++;
261
262 /* Move to next event flags group. */
263 events_ptr = events_ptr -> tx_event_flags_group_created_next;
264 }
265 break;
266 }
267
268 /* Determine if a semaphore object is requested. */
269 case TXM_SEMAPHORE_OBJECT:
270 {
271
272 /* Loop to find the first matching semaphore. */
273 i = 0;
274 semaphore_ptr = _tx_semaphore_created_ptr;
275 while (i < _tx_semaphore_created_count)
276 {
277
278 /* Do we have a match? */
279 if (_txm_module_manager_object_name_compare(search_name, search_name_length, semaphore_ptr -> tx_semaphore_name))
280 {
281
282 /* Yes, we found it - return the necessary info! */
283 *object_ptr = (VOID *) semaphore_ptr;
284
285 /* Set the the status to success! */
286 status = TX_SUCCESS;
287 break;
288 }
289
290 /* Increment the counter. */
291 i++;
292
293 /* Move to next semaphore. */
294 semaphore_ptr = semaphore_ptr -> tx_semaphore_created_next;
295 }
296 break;
297 }
298
299 /* Determine if a mutex object is requested. */
300 case TXM_MUTEX_OBJECT:
301 {
302
303 /* Loop to find the first matching mutex. */
304 i = 0;
305 mutex_ptr = _tx_mutex_created_ptr;
306 while (i < _tx_mutex_created_count)
307 {
308
309 /* Do we have a match? */
310 if (_txm_module_manager_object_name_compare(search_name, search_name_length, mutex_ptr -> tx_mutex_name))
311 {
312
313 /* Yes, we found it - return the necessary info! */
314 *object_ptr = (VOID *) mutex_ptr;
315
316 /* Set the the status to success! */
317 status = TX_SUCCESS;
318 break;
319 }
320
321 /* Increment the counter. */
322 i++;
323
324 /* Move to next mutex. */
325 mutex_ptr = mutex_ptr -> tx_mutex_created_next;
326 }
327 break;
328 }
329
330 /* Determine if a block pool object is requested. */
331 case TXM_BLOCK_POOL_OBJECT:
332 {
333
334 /* Get the module instance. */
335 module_instance = _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
336
337 /* Is a module making this request? */
338 if (module_instance != TX_NULL)
339 {
340
341 /* Is memory protection enabled? */
342 if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
343 {
344
345 /* Modules with memory protection can only access block pools they created. */
346 status = TXM_MODULE_INVALID;
347 break;
348 }
349 }
350
351 /* Loop to find the first matching block pool. */
352 i = 0;
353 block_pool_ptr = _tx_block_pool_created_ptr;
354 while (i < _tx_block_pool_created_count)
355 {
356
357 /* Do we have a match? */
358 if (_txm_module_manager_object_name_compare(search_name, search_name_length, block_pool_ptr -> tx_block_pool_name))
359 {
360
361 /* Yes, we found it - return the necessary info! */
362 *object_ptr = (VOID *) block_pool_ptr;
363
364 /* Set the the status to success! */
365 status = TX_SUCCESS;
366 break;
367 }
368
369 /* Increment the counter. */
370 i++;
371
372 /* Move to next block pool. */
373 block_pool_ptr = block_pool_ptr -> tx_block_pool_created_next;
374 }
375 break;
376 }
377
378 /* Determine if a byte pool object is requested. */
379 case TXM_BYTE_POOL_OBJECT:
380 {
381
382 /* Get the module instance. */
383 module_instance = _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
384
385 /* Is a module making this request? */
386 if (module_instance != TX_NULL)
387 {
388
389 /* Is memory protection enabled? */
390 if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
391 {
392
393 /* Modules with memory protection can only access block pools they created. */
394 status = TXM_MODULE_INVALID;
395 break;
396 }
397 }
398
399 /* Loop to find the first matching byte pool. */
400 i = 0;
401 byte_pool_ptr = _tx_byte_pool_created_ptr;
402 while (i < _tx_byte_pool_created_count)
403 {
404
405 /* Do we have a match? */
406 if (_txm_module_manager_object_name_compare(search_name, search_name_length, byte_pool_ptr -> tx_byte_pool_name))
407 {
408
409 /* Yes, we found it - return the necessary info! */
410 *object_ptr = (VOID *) byte_pool_ptr;
411
412 /* Set the the status to success! */
413 status = TX_SUCCESS;
414 break;
415 }
416
417 /* Increment the counter. */
418 i++;
419
420 /* Move to next byte pool. */
421 byte_pool_ptr = byte_pool_ptr -> tx_byte_pool_created_next;
422 }
423 break;
424 }
425
426 default:
427
428 /* Invalid object ID. */
429 status = TX_OPTION_ERROR;
430
431 /* External Object pointer get. */
432
433 #ifdef TXM_MODULE_ENABLE_NETX
434
435 /* Determine if there is a NetX object get request. */
436 if ((object_type >= TXM_NETX_OBJECTS_START) && (object_type < TXM_NETX_OBJECTS_END))
437 {
438
439 /* Call the NetX module object get function. */
440 status = _txm_module_manager_netx_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
441 }
442 #endif
443
444 #ifdef TXM_MODULE_ENABLE_NETXDUO
445
446 /* Determine if there is a NetX Duo object get request. */
447 if ((object_type >= TXM_NETXDUO_OBJECTS_START) && (object_type < TXM_NETXDUO_OBJECTS_END))
448 {
449
450 /* Call the NetX Duo module object get function. */
451 status = _txm_module_manager_netxduo_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
452 }
453 #endif
454
455 #ifdef TXM_MODULE_ENABLE_FILEX
456
457 /* Determine if there is a FileX object get request. */
458 if ((object_type >= TXM_FILEX_OBJECTS_START) && (object_type < TXM_FILEX_OBJECTS_END))
459 {
460
461 /* Call the FileX module object get function. */
462 status = _txm_module_manager_filex_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
463 }
464 #endif
465
466
467 #ifdef TXM_MODULE_ENABLE_GUIX
468
469 /* Determine if there is a GUIX object get request. */
470 if ((object_type >= TXM_GUIX_OBJECTS_START) && (object_type < TXM_GUIX_OBJECTS_END))
471 {
472
473 /* Call the GUIX module object get function. */
474 status = _txm_module_manager_guix_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
475 }
476 #endif
477
478 #ifdef TXM_MODULE_ENABLE_USBX
479
480 /* Determine if there is a USBX object get request. */
481 if ((object_type >= TXM_USBX_OBJECTS_START) && (object_type < TXM_USBX_OBJECTS_END))
482 {
483
484 /* Call the USBX object get function. */
485 status = _txm_module_manager_usbx_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
486 }
487 #endif
488
489 break;
490 }
491
492 /* Disable interrupts. */
493 TX_DISABLE
494
495 /* Enable preemption again. */
496 _tx_thread_preempt_disable--;
497
498 /* Restore interrupts. */
499 TX_RESTORE
500
501 /* Check for preemption. */
502 _tx_thread_system_preempt_check();
503
504 /* Return success. */
505 return(status);
506 }
507