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