Skip to content

Commit aa25b1d

Browse files
author
Cruz Monrreal
authored
Merge pull request #6973 from OpenNuvoton/nuvoton_armc6_thread_safe
Support thread-safety with ARMC6
2 parents ec5018d + 8071409 commit aa25b1d

File tree

2 files changed

+87
-3
lines changed

2 files changed

+87
-3
lines changed

rtos/TARGET_CORTEX/mbed_boot.c

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

426+
/* Move all code here from RTX code base (rtx_lib.c) and do some modifications:
427+
*
428+
* 1. _mutex_initialize/_mutex_free are re-implemented to meet Mbed.
429+
* 2. All _mutex_* functions are declared with '__USED' to avoid excluded by linker.
430+
*/
431+
#if defined(RTX_NO_MULTITHREAD_CLIB)
432+
433+
#define LIBSPACE_SIZE 96
434+
435+
//lint -esym(714,__user_perthread_libspace,_mutex_*) "Referenced by C library"
436+
//lint -esym(765,__user_perthread_libspace,_mutex_*) "Global scope"
437+
//lint -esym(9003, os_libspace*) "variables 'os_libspace*' defined at module scope"
438+
439+
// Memory for libspace
440+
static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/4] \
441+
__attribute__((section(".bss.os.libspace")));
442+
443+
// Thread IDs for libspace
444+
static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \
445+
__attribute__((section(".bss.os.libspace")));
446+
447+
// Check if Kernel has been started
448+
static uint32_t os_kernel_is_active (void) {
449+
static uint8_t os_kernel_active = 0U;
450+
451+
if (os_kernel_active == 0U) {
452+
if (osKernelGetState() > osKernelReady) {
453+
os_kernel_active = 1U;
454+
}
455+
}
456+
return (uint32_t)os_kernel_active;
457+
}
458+
459+
// Provide libspace for current thread
460+
void *__user_perthread_libspace (void) {
461+
osThreadId_t id;
462+
uint32_t n;
463+
464+
if (os_kernel_is_active() != 0U) {
465+
id = osThreadGetId();
466+
for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) {
467+
if (os_libspace_id[n] == NULL) {
468+
os_libspace_id[n] = id;
469+
}
470+
if (os_libspace_id[n] == id) {
471+
break;
472+
}
473+
}
474+
if (n == (uint32_t)OS_THREAD_LIBSPACE_NUM) {
475+
(void)osRtxErrorNotify(osRtxErrorClibSpace, id);
476+
}
477+
} else {
478+
n = OS_THREAD_LIBSPACE_NUM;
479+
}
480+
481+
//lint -e{9087} "cast between pointers to different object types"
482+
return (void *)&os_libspace[n][0];
483+
}
484+
426485
/* ARM toolchain requires dynamically created mutexes to enforce thread safety. There's
427486
up to 8 static mutexes, protecting atexit, signalinit, stdin, stdout, stderr, stream_list,
428487
fp_trap_init and the heap. Additionally for each call to fopen one extra mutex will be
@@ -438,8 +497,13 @@ typedef void *mutex;
438497
#define OS_MUTEX_STATIC_NUM 8
439498
mutex _static_mutexes[OS_MUTEX_STATIC_NUM] = {NULL};
440499
mbed_rtos_storage_mutex_t _static_mutexes_mem[OS_MUTEX_STATIC_NUM] = {NULL};
441-
442-
int _mutex_initialize(mutex *m)
500+
501+
//lint -save "Function prototypes defined in C library"
502+
//lint -e970 "Use of 'int' outside of a typedef"
503+
//lint -e818 "Pointer 'm' could be declared as pointing to const"
504+
505+
/* Initialize mutex */
506+
__USED int _mutex_initialize(mutex *m)
443507
{
444508
osMutexAttr_t attr;
445509
memset(&attr, 0, sizeof(attr));
@@ -485,7 +549,22 @@ int _mutex_initialize(mutex *m)
485549
return 1;
486550
}
487551

488-
void _mutex_free(mutex *m) {
552+
/* Acquire mutex */
553+
__USED void _mutex_acquire(mutex *m) {
554+
if (os_kernel_is_active() != 0U) {
555+
(void)osMutexAcquire(*m, osWaitForever);
556+
}
557+
}
558+
559+
/* Release mutex */
560+
__USED void _mutex_release(mutex *m) {
561+
if (os_kernel_is_active() != 0U) {
562+
(void)osMutexRelease(*m);
563+
}
564+
}
565+
566+
/* Free mutex */
567+
__USED void _mutex_free(mutex *m) {
489568
mutex *slot = NULL;
490569
core_util_critical_section_enter();
491570
for (int i = 0; i < OS_MUTEX_STATIC_NUM; i++) {
@@ -507,6 +586,7 @@ void _mutex_free(mutex *m) {
507586

508587
}
509588

589+
#endif /* RTX_NO_MULTITHREAD_CLIB */
510590
#endif /* ARMC */
511591
#elif defined (__GNUC__) /******************** GCC ********************/
512592

rtos/TARGET_CORTEX/mbed_rtx_conf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,8 @@
7070
#define OS_IDLE_THREAD_TZ_MOD_ID 1
7171
#define OS_TIMER_THREAD_TZ_MOD_ID 1
7272

73+
// Don't adopt default multi-thread support for ARM/ARMC6 toolchains from RTX code base.
74+
// Provide Mbed-specific instead.
75+
#define RTX_NO_MULTITHREAD_CLIB
76+
7377
#endif /* MBED_RTX_CONF_H */

0 commit comments

Comments
 (0)