Skip to content

Commit afc0a28

Browse files
committed
Support thread-safety with ARMC6
1. Define RTX_NO_MULTITHREAD_CLIB to provide Mbed-specific multi-thread support for ARM/ARMC6 2. All overridden _mutex_xxx functions are declared with __USED to avoid excluded by linker NOTE: Microlib doesn't support multi-thread
1 parent ba5b5a3 commit afc0a28

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

rtos/TARGET_CORTEX/mbed_boot.c

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,60 @@ void __rt_entry (void) {
423423
mbed_start_main();
424424
}
425425

426+
#if defined(RTX_NO_MULTITHREAD_CLIB)
427+
428+
#define LIBSPACE_SIZE 96
429+
430+
//lint -esym(714,__user_perthread_libspace,_mutex_*) "Referenced by C library"
431+
//lint -esym(765,__user_perthread_libspace,_mutex_*) "Global scope"
432+
//lint -esym(9003, os_libspace*) "variables 'os_libspace*' defined at module scope"
433+
434+
// Memory for libspace
435+
static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/4] \
436+
__attribute__((section(".bss.os.libspace")));
437+
438+
// Thread IDs for libspace
439+
static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \
440+
__attribute__((section(".bss.os.libspace")));
441+
442+
// Check if Kernel has been started
443+
static uint32_t os_kernel_is_active (void) {
444+
static uint8_t os_kernel_active = 0U;
445+
446+
if (os_kernel_active == 0U) {
447+
if (osKernelGetState() > osKernelReady) {
448+
os_kernel_active = 1U;
449+
}
450+
}
451+
return (uint32_t)os_kernel_active;
452+
}
453+
454+
// Provide libspace for current thread
455+
void *__user_perthread_libspace (void) {
456+
osThreadId_t id;
457+
uint32_t n;
458+
459+
if (os_kernel_is_active() != 0U) {
460+
id = osThreadGetId();
461+
for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) {
462+
if (os_libspace_id[n] == NULL) {
463+
os_libspace_id[n] = id;
464+
}
465+
if (os_libspace_id[n] == id) {
466+
break;
467+
}
468+
}
469+
if (n == (uint32_t)OS_THREAD_LIBSPACE_NUM) {
470+
(void)osRtxErrorNotify(osRtxErrorClibSpace, id);
471+
}
472+
} else {
473+
n = OS_THREAD_LIBSPACE_NUM;
474+
}
475+
476+
//lint -e{9087} "cast between pointers to different object types"
477+
return (void *)&os_libspace[n][0];
478+
}
479+
426480
/* ARM toolchain requires dynamically created mutexes to enforce thread safety. There's
427481
up to 8 static mutexes, protecting atexit, signalinit, stdin, stdout, stderr, stream_list,
428482
fp_trap_init and the heap. Additionally for each call to fopen one extra mutex will be
@@ -438,8 +492,13 @@ typedef void *mutex;
438492
#define OS_MUTEX_STATIC_NUM 8
439493
mutex _static_mutexes[OS_MUTEX_STATIC_NUM] = {NULL};
440494
mbed_rtos_storage_mutex_t _static_mutexes_mem[OS_MUTEX_STATIC_NUM] = {NULL};
441-
442-
int _mutex_initialize(mutex *m)
495+
496+
//lint -save "Function prototypes defined in C library"
497+
//lint -e970 "Use of 'int' outside of a typedef"
498+
//lint -e818 "Pointer 'm' could be declared as pointing to const"
499+
500+
/* Initialize mutex */
501+
__USED int _mutex_initialize(mutex *m)
443502
{
444503
osMutexAttr_t attr;
445504
memset(&attr, 0, sizeof(attr));
@@ -485,7 +544,22 @@ int _mutex_initialize(mutex *m)
485544
return 1;
486545
}
487546

488-
void _mutex_free(mutex *m) {
547+
/* Acquire mutex */
548+
__USED void _mutex_acquire(mutex *m) {
549+
if (os_kernel_is_active() != 0U) {
550+
(void)osMutexAcquire(*m, osWaitForever);
551+
}
552+
}
553+
554+
/* Release mutex */
555+
__USED void _mutex_release(mutex *m) {
556+
if (os_kernel_is_active() != 0U) {
557+
(void)osMutexRelease(*m);
558+
}
559+
}
560+
561+
/* Free mutex */
562+
__USED void _mutex_free(mutex *m) {
489563
mutex *slot = NULL;
490564
core_util_critical_section_enter();
491565
for (int i = 0; i < OS_MUTEX_STATIC_NUM; i++) {
@@ -507,6 +581,7 @@ void _mutex_free(mutex *m) {
507581

508582
}
509583

584+
#endif /* RTX_NO_MULTITHREAD_CLIB */
510585
#endif /* ARMC */
511586
#elif defined (__GNUC__) /******************** GCC ********************/
512587

rtos/TARGET_CORTEX/rtx5/RTX/Config/RTX_Config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@
404404
#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM
405405
#endif
406406

407+
408+
// Don't adopt default multi-thread support for ARM/ARMC6 toolchains from RTX code base.
409+
// Provide Mbed-specific instead.
410+
#define RTX_NO_MULTITHREAD_CLIB
411+
407412
//------------- <<< end of configuration section >>> ---------------------------
408413

409414
#endif // RTX_CONFIG_H_

0 commit comments

Comments
 (0)