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