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 /**   IAR Multithreaded Library Support                                   */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define TX_SOURCE_CODE
24 
25 
26 /* Define IAR library for tools prior to version 8.  */
27 
28 #if (__VER__ < 8000000)
29 
30 
31 /* IAR version 7 and below.  */
32 
33 /* Include necessary system files.  */
34 
35 #include "tx_api.h"
36 #include "tx_initialize.h"
37 #include "tx_thread.h"
38 #include "tx_mutex.h"
39 
40 
41 /* This implementation requires that the following macros are defined in the
42    tx_port.h file and <yvals.h> is included with the following code segments:
43 
44 #ifdef  TX_ENABLE_IAR_LIBRARY_SUPPORT
45 #include <yvals.h>
46 #endif
47 
48 #ifdef  TX_ENABLE_IAR_LIBRARY_SUPPORT
49 #define TX_THREAD_EXTENSION_2           VOID    *tx_thread_iar_tls_pointer;
50 #else
51 #define TX_THREAD_EXTENSION_2
52 #endif
53 
54 #ifdef  TX_ENABLE_IAR_LIBRARY_SUPPORT
55 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)                      thread_ptr -> tx_thread_iar_tls_pointer =  __iar_dlib_perthread_allocate();
56 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)                      __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
57                                                                     thread_ptr -> tx_thread_iar_tls_pointer =  TX_NULL;
58 #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION               __iar_dlib_perthread_access(0);
59 #else
60 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)
61 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)
62 #endif
63 
64     This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
65     application.
66 
67     Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
68 */
69 
70 #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
71 
72 #include <yvals.h>
73 
74 
75 #if _MULTI_THREAD
76 
77 TX_MUTEX    __tx_iar_system_lock_mutexes[_MAX_LOCK];
78 UINT        __tx_iar_system_lock_next_free_mutex =  0;
79 
80 
81 /* Define error counters, just for debug purposes.  */
82 
83 UINT        __tx_iar_system_lock_no_mutexes;
84 UINT        __tx_iar_system_lock_internal_errors;
85 UINT        __tx_iar_system_lock_isr_caller;
86 
87 
88 /* Define the TLS access function for the IAR library.  */
89 
__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY * symbp)90 void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
91 {
92 
93 char _DLIB_TLS_MEMORY   *p = 0;
94 
95     /* Is there a current thread?  */
96     if (_tx_thread_current_ptr)
97       p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer;
98     else
99       p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD");
100     p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
101     return (void _DLIB_TLS_MEMORY *) p;
102 }
103 
104 
105 /* Define mutexes for IAR library.  */
106 
__iar_system_Mtxinit(__iar_Rmtx * m)107 void __iar_system_Mtxinit(__iar_Rmtx *m)
108 {
109 
110 UINT        i;
111 UINT        status;
112 TX_MUTEX    *mutex_ptr;
113 
114 
115     /* First, find a free mutex in the list.  */
116     for (i = 0; i < _MAX_LOCK; i++)
117     {
118 
119         /* Setup a pointer to the start of the next free mutex.  */
120         mutex_ptr =  &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
121 
122         /* Check for wrap-around on the next free mutex.  */
123         if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
124         {
125 
126             /* Yes, set the free index back to 0.  */
127             __tx_iar_system_lock_next_free_mutex =  0;
128         }
129 
130         /* Is this mutex free?  */
131         if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
132         {
133 
134             /* Yes, this mutex is free, get out of the loop!  */
135             break;
136         }
137     }
138 
139     /* Determine if a free mutex was found.   */
140     if (i >= _MAX_LOCK)
141     {
142 
143         /* Error!  No more free mutexes!  */
144 
145         /* Increment the no mutexes error counter.  */
146         __tx_iar_system_lock_no_mutexes++;
147 
148         /* Set return pointer to NULL.  */
149         *m =  TX_NULL;
150 
151         /* Return.  */
152         return;
153     }
154 
155     /* Now create the ThreadX mutex for the IAR library.  */
156     status =  _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
157 
158     /* Determine if the creation was successful.  */
159     if (status == TX_SUCCESS)
160     {
161 
162         /* Yes, successful creation, return mutex pointer.  */
163         *m =  (VOID *) mutex_ptr;
164     }
165     else
166     {
167 
168         /* Increment the internal error counter.  */
169         __tx_iar_system_lock_internal_errors++;
170 
171         /* Return a NULL pointer to indicate an error.  */
172         *m =  TX_NULL;
173     }
174 }
175 
__iar_system_Mtxdst(__iar_Rmtx * m)176 void __iar_system_Mtxdst(__iar_Rmtx *m)
177 {
178 
179     /* Simply delete the mutex.  */
180     _tx_mutex_delete((TX_MUTEX *) *m);
181 }
182 
__iar_system_Mtxlock(__iar_Rmtx * m)183 void __iar_system_Mtxlock(__iar_Rmtx *m)
184 {
185 
186 UINT    status;
187 
188 
189     /* Determine the caller's context. Mutex locks are only available from initialization and
190        threads.  */
191     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
192     {
193 
194         /* Get the mutex.  */
195         status =  _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
196 
197         /* Check the status of the mutex release.  */
198         if (status)
199         {
200 
201             /* Internal error, increment the counter.  */
202             __tx_iar_system_lock_internal_errors++;
203         }
204     }
205     else
206     {
207 
208         /* Increment the ISR caller error.  */
209         __tx_iar_system_lock_isr_caller++;
210     }
211 }
212 
__iar_system_Mtxunlock(__iar_Rmtx * m)213 void __iar_system_Mtxunlock(__iar_Rmtx *m)
214 {
215 
216 UINT    status;
217 
218 
219     /* Determine the caller's context. Mutex unlocks are only available from initialization and
220        threads.  */
221     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
222     {
223 
224         /* Release the mutex.  */
225         status =  _tx_mutex_put((TX_MUTEX *) *m);
226 
227         /* Check the status of the mutex release.  */
228         if (status)
229         {
230 
231             /* Internal error, increment the counter.  */
232             __tx_iar_system_lock_internal_errors++;
233         }
234     }
235     else
236     {
237 
238         /* Increment the ISR caller error.  */
239         __tx_iar_system_lock_isr_caller++;
240     }
241 }
242 
243 
244 #if _DLIB_FILE_DESCRIPTOR
245 
246 TX_MUTEX    __tx_iar_file_lock_mutexes[_MAX_FLOCK];
247 UINT        __tx_iar_file_lock_next_free_mutex =  0;
248 
249 
250 /* Define error counters, just for debug purposes.  */
251 
252 UINT        __tx_iar_file_lock_no_mutexes;
253 UINT        __tx_iar_file_lock_internal_errors;
254 UINT        __tx_iar_file_lock_isr_caller;
255 
256 
__iar_file_Mtxinit(__iar_Rmtx * m)257 void __iar_file_Mtxinit(__iar_Rmtx *m)
258 {
259 
260 UINT        i;
261 UINT        status;
262 TX_MUTEX    *mutex_ptr;
263 
264 
265     /* First, find a free mutex in the list.  */
266     for (i = 0; i < _MAX_FLOCK; i++)
267     {
268 
269         /* Setup a pointer to the start of the next free mutex.  */
270         mutex_ptr =  &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
271 
272         /* Check for wrap-around on the next free mutex.  */
273         if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
274         {
275 
276             /* Yes, set the free index back to 0.  */
277             __tx_iar_file_lock_next_free_mutex =  0;
278         }
279 
280         /* Is this mutex free?  */
281         if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
282         {
283 
284             /* Yes, this mutex is free, get out of the loop!  */
285             break;
286         }
287     }
288 
289     /* Determine if a free mutex was found.   */
290     if (i >= _MAX_LOCK)
291     {
292 
293         /* Error!  No more free mutexes!  */
294 
295         /* Increment the no mutexes error counter.  */
296         __tx_iar_file_lock_no_mutexes++;
297 
298         /* Set return pointer to NULL.  */
299         *m =  TX_NULL;
300 
301         /* Return.  */
302         return;
303     }
304 
305     /* Now create the ThreadX mutex for the IAR library.  */
306     status =  _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
307 
308     /* Determine if the creation was successful.  */
309     if (status == TX_SUCCESS)
310     {
311 
312         /* Yes, successful creation, return mutex pointer.  */
313         *m =  (VOID *) mutex_ptr;
314     }
315     else
316     {
317 
318         /* Increment the internal error counter.  */
319         __tx_iar_file_lock_internal_errors++;
320 
321         /* Return a NULL pointer to indicate an error.  */
322         *m =  TX_NULL;
323     }
324 }
325 
__iar_file_Mtxdst(__iar_Rmtx * m)326 void __iar_file_Mtxdst(__iar_Rmtx *m)
327 {
328 
329     /* Simply delete the mutex.  */
330     _tx_mutex_delete((TX_MUTEX *) *m);
331 }
332 
__iar_file_Mtxlock(__iar_Rmtx * m)333 void __iar_file_Mtxlock(__iar_Rmtx *m)
334 {
335 
336 UINT    status;
337 
338 
339     /* Determine the caller's context. Mutex locks are only available from initialization and
340        threads.  */
341     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
342     {
343 
344         /* Get the mutex.  */
345         status =  _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
346 
347         /* Check the status of the mutex release.  */
348         if (status)
349         {
350 
351             /* Internal error, increment the counter.  */
352             __tx_iar_file_lock_internal_errors++;
353         }
354     }
355     else
356     {
357 
358         /* Increment the ISR caller error.  */
359         __tx_iar_file_lock_isr_caller++;
360     }
361 }
362 
__iar_file_Mtxunlock(__iar_Rmtx * m)363 void __iar_file_Mtxunlock(__iar_Rmtx *m)
364 {
365 
366 UINT    status;
367 
368 
369     /* Determine the caller's context. Mutex unlocks are only available from initialization and
370        threads.  */
371     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
372     {
373 
374         /* Release the mutex.  */
375         status =  _tx_mutex_put((TX_MUTEX *) *m);
376 
377         /* Check the status of the mutex release.  */
378         if (status)
379         {
380 
381             /* Internal error, increment the counter.  */
382             __tx_iar_file_lock_internal_errors++;
383         }
384     }
385     else
386     {
387 
388         /* Increment the ISR caller error.  */
389         __tx_iar_file_lock_isr_caller++;
390     }
391 }
392 #endif  /* _DLIB_FILE_DESCRIPTOR */
393 
394 #endif  /* _MULTI_THREAD  */
395 
396 #endif  /* TX_ENABLE_IAR_LIBRARY_SUPPORT  */
397 
398 #else   /* IAR version 8 and above.  */
399 
400 
401 /* Include necessary system files.  */
402 
403 #include "tx_api.h"
404 #include "tx_initialize.h"
405 #include "tx_thread.h"
406 #include "tx_mutex.h"
407 
408 /* This implementation requires that the following macros are defined in the
409    tx_port.h file and <yvals.h> is included with the following code segments:
410 
411 #ifdef  TX_ENABLE_IAR_LIBRARY_SUPPORT
412 #include <yvals.h>
413 #endif
414 
415 #ifdef  TX_ENABLE_IAR_LIBRARY_SUPPORT
416 #define TX_THREAD_EXTENSION_2           VOID    *tx_thread_iar_tls_pointer;
417 #else
418 #define TX_THREAD_EXTENSION_2
419 #endif
420 
421 #ifdef  TX_ENABLE_IAR_LIBRARY_SUPPORT
422 void    *_tx_iar_create_per_thread_tls_area(void);
423 void    _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
424 void    __iar_Initlocks(void);
425 
426 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)                      thread_ptr -> tx_thread_iar_tls_pointer =  __iar_dlib_perthread_allocate();
427 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)                      do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
428                                                                         thread_ptr -> tx_thread_iar_tls_pointer =  TX_NULL; } while(0);
429 #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION               do {__iar_Initlocks();} while(0);
430 #else
431 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)
432 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)
433 #endif
434 
435     This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
436     application.
437 
438     Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
439 */
440 
441 #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
442 
443 #include <DLib_threads.h>
444 
445 
446 void * __aeabi_read_tp();
447 
448 void* _tx_iar_create_per_thread_tls_area();
449 void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
450 
451 #pragma section="__iar_tls$$DATA"
452 
453 /* Define the TLS access function for the IAR library.  */
__aeabi_read_tp(void)454 void * __aeabi_read_tp(void)
455 {
456   void *p = 0;
457   TX_THREAD *thread_ptr = _tx_thread_current_ptr;
458   if (thread_ptr)
459   {
460     p = thread_ptr->tx_thread_iar_tls_pointer;
461   }
462   else
463   {
464     p = __section_begin("__iar_tls$$DATA");
465   }
466   return p;
467 }
468 
469 /* Define the TLS creation and destruction to use malloc/free.  */
470 
_tx_iar_create_per_thread_tls_area()471 void* _tx_iar_create_per_thread_tls_area()
472 {
473   UINT tls_size = __iar_tls_size();
474 
475   /* Get memory for TLS.  */
476   void *p = malloc(tls_size);
477 
478   /* Initialize TLS-area and run constructors for objects in TLS */
479   __iar_tls_init(p);
480   return p;
481 }
482 
_tx_iar_destroy_per_thread_tls_area(void * tls_ptr)483 void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr)
484 {
485   /* Destroy objects living in TLS */
486   __call_thread_dtors();
487   free(tls_ptr);
488 }
489 
490 #ifndef _MAX_LOCK
491 #define _MAX_LOCK 4
492 #endif
493 
494 static TX_MUTEX    __tx_iar_system_lock_mutexes[_MAX_LOCK];
495 static UINT        __tx_iar_system_lock_next_free_mutex =  0;
496 
497 
498 /* Define error counters, just for debug purposes.  */
499 
500 UINT        __tx_iar_system_lock_no_mutexes;
501 UINT        __tx_iar_system_lock_internal_errors;
502 UINT        __tx_iar_system_lock_isr_caller;
503 
504 
505 /* Define mutexes for IAR library.  */
506 
__iar_system_Mtxinit(__iar_Rmtx * m)507 void __iar_system_Mtxinit(__iar_Rmtx *m)
508 {
509 
510 UINT        i;
511 UINT        status;
512 TX_MUTEX    *mutex_ptr;
513 
514 
515     /* First, find a free mutex in the list.  */
516     for (i = 0; i < _MAX_LOCK; i++)
517     {
518 
519         /* Setup a pointer to the start of the next free mutex.  */
520         mutex_ptr =  &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++];
521 
522         /* Check for wrap-around on the next free mutex.  */
523         if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
524         {
525 
526             /* Yes, set the free index back to 0.  */
527             __tx_iar_system_lock_next_free_mutex =  0;
528         }
529 
530         /* Is this mutex free?  */
531         if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
532         {
533 
534             /* Yes, this mutex is free, get out of the loop!  */
535             break;
536         }
537     }
538 
539     /* Determine if a free mutex was found.   */
540     if (i >= _MAX_LOCK)
541     {
542 
543         /* Error!  No more free mutexes!  */
544 
545         /* Increment the no mutexes error counter.  */
546         __tx_iar_system_lock_no_mutexes++;
547 
548         /* Set return pointer to NULL.  */
549         *m =  TX_NULL;
550 
551         /* Return.  */
552         return;
553     }
554 
555     /* Now create the ThreadX mutex for the IAR library.  */
556     status =  _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
557 
558     /* Determine if the creation was successful.  */
559     if (status == TX_SUCCESS)
560     {
561 
562         /* Yes, successful creation, return mutex pointer.  */
563         *m =  (VOID *) mutex_ptr;
564     }
565     else
566     {
567 
568         /* Increment the internal error counter.  */
569         __tx_iar_system_lock_internal_errors++;
570 
571         /* Return a NULL pointer to indicate an error.  */
572         *m =  TX_NULL;
573     }
574 }
575 
__iar_system_Mtxdst(__iar_Rmtx * m)576 void __iar_system_Mtxdst(__iar_Rmtx *m)
577 {
578 
579     /* Simply delete the mutex.  */
580     _tx_mutex_delete((TX_MUTEX *) *m);
581 }
582 
__iar_system_Mtxlock(__iar_Rmtx * m)583 void __iar_system_Mtxlock(__iar_Rmtx *m)
584 {
585   if (*m)
586   {
587     UINT    status;
588 
589     /* Determine the caller's context. Mutex locks are only available from initialization and
590        threads.  */
591     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
592     {
593 
594         /* Get the mutex.  */
595         status =  _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
596 
597         /* Check the status of the mutex release.  */
598         if (status)
599         {
600 
601             /* Internal error, increment the counter.  */
602             __tx_iar_system_lock_internal_errors++;
603         }
604     }
605     else
606     {
607 
608         /* Increment the ISR caller error.  */
609         __tx_iar_system_lock_isr_caller++;
610     }
611   }
612 }
613 
__iar_system_Mtxunlock(__iar_Rmtx * m)614 void __iar_system_Mtxunlock(__iar_Rmtx *m)
615 {
616   if (*m)
617   {
618     UINT    status;
619 
620     /* Determine the caller's context. Mutex unlocks are only available from initialization and
621        threads.  */
622     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
623     {
624 
625         /* Release the mutex.  */
626         status =  _tx_mutex_put((TX_MUTEX *) *m);
627 
628         /* Check the status of the mutex release.  */
629         if (status)
630         {
631 
632             /* Internal error, increment the counter.  */
633             __tx_iar_system_lock_internal_errors++;
634         }
635     }
636     else
637     {
638 
639         /* Increment the ISR caller error.  */
640         __tx_iar_system_lock_isr_caller++;
641     }
642   }
643 }
644 
645 
646 #if _DLIB_FILE_DESCRIPTOR
647 
648 #include <stdio.h>                        /* Added to get access to FOPEN_MAX */
649 #ifndef _MAX_FLOCK
650 #define _MAX_FLOCK FOPEN_MAX              /* Define _MAX_FLOCK as the maximum number of open files */
651 #endif
652 
653 
654 TX_MUTEX    __tx_iar_file_lock_mutexes[_MAX_FLOCK];
655 UINT        __tx_iar_file_lock_next_free_mutex =  0;
656 
657 
658 /* Define error counters, just for debug purposes.  */
659 
660 UINT        __tx_iar_file_lock_no_mutexes;
661 UINT        __tx_iar_file_lock_internal_errors;
662 UINT        __tx_iar_file_lock_isr_caller;
663 
664 
__iar_file_Mtxinit(__iar_Rmtx * m)665 void __iar_file_Mtxinit(__iar_Rmtx *m)
666 {
667 
668 UINT        i;
669 UINT        status;
670 TX_MUTEX    *mutex_ptr;
671 
672 
673     /* First, find a free mutex in the list.  */
674     for (i = 0; i < _MAX_FLOCK; i++)
675     {
676 
677         /* Setup a pointer to the start of the next free mutex.  */
678         mutex_ptr =  &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++];
679 
680         /* Check for wrap-around on the next free mutex.  */
681         if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
682         {
683 
684             /* Yes, set the free index back to 0.  */
685             __tx_iar_file_lock_next_free_mutex =  0;
686         }
687 
688         /* Is this mutex free?  */
689         if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
690         {
691 
692             /* Yes, this mutex is free, get out of the loop!  */
693             break;
694         }
695     }
696 
697     /* Determine if a free mutex was found.   */
698     if (i >= _MAX_LOCK)
699     {
700 
701         /* Error!  No more free mutexes!  */
702 
703         /* Increment the no mutexes error counter.  */
704         __tx_iar_file_lock_no_mutexes++;
705 
706         /* Set return pointer to NULL.  */
707         *m =  TX_NULL;
708 
709         /* Return.  */
710         return;
711     }
712 
713     /* Now create the ThreadX mutex for the IAR library.  */
714     status =  _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
715 
716     /* Determine if the creation was successful.  */
717     if (status == TX_SUCCESS)
718     {
719 
720         /* Yes, successful creation, return mutex pointer.  */
721         *m =  (VOID *) mutex_ptr;
722     }
723     else
724     {
725 
726         /* Increment the internal error counter.  */
727         __tx_iar_file_lock_internal_errors++;
728 
729         /* Return a NULL pointer to indicate an error.  */
730         *m =  TX_NULL;
731     }
732 }
733 
__iar_file_Mtxdst(__iar_Rmtx * m)734 void __iar_file_Mtxdst(__iar_Rmtx *m)
735 {
736 
737     /* Simply delete the mutex.  */
738     _tx_mutex_delete((TX_MUTEX *) *m);
739 }
740 
__iar_file_Mtxlock(__iar_Rmtx * m)741 void __iar_file_Mtxlock(__iar_Rmtx *m)
742 {
743 
744 UINT    status;
745 
746 
747     /* Determine the caller's context. Mutex locks are only available from initialization and
748        threads.  */
749     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
750     {
751 
752         /* Get the mutex.  */
753         status =  _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
754 
755         /* Check the status of the mutex release.  */
756         if (status)
757         {
758 
759             /* Internal error, increment the counter.  */
760             __tx_iar_file_lock_internal_errors++;
761         }
762     }
763     else
764     {
765 
766         /* Increment the ISR caller error.  */
767         __tx_iar_file_lock_isr_caller++;
768     }
769 }
770 
__iar_file_Mtxunlock(__iar_Rmtx * m)771 void __iar_file_Mtxunlock(__iar_Rmtx *m)
772 {
773 
774 UINT    status;
775 
776 
777     /* Determine the caller's context. Mutex unlocks are only available from initialization and
778        threads.  */
779     if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
780     {
781 
782         /* Release the mutex.  */
783         status =  _tx_mutex_put((TX_MUTEX *) *m);
784 
785         /* Check the status of the mutex release.  */
786         if (status)
787         {
788 
789             /* Internal error, increment the counter.  */
790             __tx_iar_file_lock_internal_errors++;
791         }
792     }
793     else
794     {
795 
796         /* Increment the ISR caller error.  */
797         __tx_iar_file_lock_isr_caller++;
798     }
799 }
800 #endif  /* _DLIB_FILE_DESCRIPTOR */
801 
802 #endif  /* TX_ENABLE_IAR_LIBRARY_SUPPORT  */
803 
804 #endif /* IAR version 8 and above.  */
805