Skip to content

Commit e7f27aa

Browse files
Merge pull request #4731 from bulislaw/fix_armc_mutexes
Boot: Make ARMC library mutexes dynamic
2 parents 6b6456f + a1736e6 commit e7f27aa

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

rtos/mbed_boot.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@
160160
*
161161
*/
162162

163+
#include <stdlib.h>
164+
163165
#include "cmsis.h"
164166
#include "mbed_rtx.h"
165167
#include "mbed_rtos_storage.h"
@@ -413,6 +415,47 @@ void __rt_entry (void) {
413415
mbed_start_main();
414416
}
415417

418+
typedef void *mutex;
419+
420+
/* ARM toolchain requires dynamically created mutexes to enforce thread safety. There's
421+
up to 8 static mutexes, protecting atexit, signalinit, stdin, stdout, stderr, stream_list,
422+
fp_trap_init and the heap. Additionally for each call to fopen one extra mutex will be
423+
created.
424+
mbed OS provides a RTX pool for 8 mutexes, to satisfy the static requirements. All
425+
additional mutexes will be allocated on the heap. We can't use the heap allocation for
426+
all the required mutexes, as the heap operations also require a mutex. We don't need to
427+
worry about freeing the allocated memory as library mutexes are only freed when the
428+
application finishes executing.
429+
*/
430+
int _mutex_initialize(mutex *m)
431+
{
432+
osMutexAttr_t attr;
433+
memset(&attr, 0, sizeof(attr));
434+
attr.name = "ARM toolchain mutex";
435+
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
436+
437+
*m = osMutexNew(&attr);
438+
if (*m != NULL) {
439+
return 1;
440+
}
441+
442+
/* Mutex pool exhausted, try using HEAP */
443+
attr.cb_size = sizeof(mbed_rtos_storage_mutex_t);
444+
attr.cb_mem = (void*)malloc(attr.cb_size);
445+
if (attr.cb_mem == NULL) {
446+
osRtxErrorNotify(osRtxErrorClibSpace, m);
447+
return 0;
448+
}
449+
450+
*m = osMutexNew(&attr);
451+
if (*m == NULL) {
452+
osRtxErrorNotify(osRtxErrorClibMutex, m);
453+
return 0;
454+
}
455+
456+
return 1;
457+
}
458+
416459
#endif /* ARMC */
417460
#elif defined (__GNUC__) /******************** GCC ********************/
418461

rtos/rtx5/TARGET_CORTEX_M/rtx_lib.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ typedef void *mutex;
597597
// Initialize mutex
598598
__USED
599599
int _mutex_initialize(mutex *m);
600-
int _mutex_initialize(mutex *m) {
600+
__WEAK int _mutex_initialize(mutex *m) {
601601
*m = osMutexNew(NULL);
602602
if (*m == NULL) {
603603
osRtxErrorNotify(osRtxErrorClibMutex, m);
@@ -609,7 +609,7 @@ int _mutex_initialize(mutex *m) {
609609
// Acquire mutex
610610
__USED
611611
void _mutex_acquire(mutex *m);
612-
void _mutex_acquire(mutex *m) {
612+
__WEAK void _mutex_acquire(mutex *m) {
613613
if (os_kernel_is_active()) {
614614
osMutexAcquire(*m, osWaitForever);
615615
}
@@ -618,7 +618,7 @@ void _mutex_acquire(mutex *m) {
618618
// Release mutex
619619
__USED
620620
void _mutex_release(mutex *m);
621-
void _mutex_release(mutex *m) {
621+
__WEAK void _mutex_release(mutex *m) {
622622
if (os_kernel_is_active()) {
623623
osMutexRelease(*m);
624624
}
@@ -627,7 +627,7 @@ void _mutex_release(mutex *m) {
627627
// Free mutex
628628
__USED
629629
void _mutex_free(mutex *m);
630-
void _mutex_free(mutex *m) {
630+
__WEAK void _mutex_free(mutex *m) {
631631
osMutexDelete(*m);
632632
}
633633

rtos/rtx5/mbed_rtx_conf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define OS_DYNAMIC_MEM_SIZE 0
4040

4141
#if defined(__CC_ARM)
42+
/* ARM toolchain uses up to 8 static mutexes, any further mutexes will be allocated on the heap. */
4243
#define OS_MUTEX_OBJ_MEM 1
4344
#define OS_MUTEX_NUM 8
4445
#endif

0 commit comments

Comments
 (0)