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