Skip to content

Commit 027843a

Browse files
authored
Merge pull request #4389 from c1728p9/assert_mutex_not_in_isr
Assert that mutexes and prints are not use in interrupt or critical context
2 parents 533e6f0 + 737c5a9 commit 027843a

File tree

12 files changed

+147
-21
lines changed

12 files changed

+147
-21
lines changed

TESTS/storage_abstraction/.mbedignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*

features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ static uint8_t sys_irq_disable_counter;
1313
static mbed_rtos_storage_mutex_t critical_mutex;
1414
static const osMutexAttr_t critical_mutex_attr = {
1515
.name = "nanostack_critical_mutex",
16-
.attr_bits = osMutexRecursive,
16+
.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
1717
.cb_mem = &critical_mutex,
1818
.cb_size = sizeof critical_mutex,
1919
};

features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static osThreadId_t event_thread_id;
3030
static mbed_rtos_storage_mutex_t event_mutex;
3131
static const osMutexAttr_t event_mutex_attr = {
3232
.name = "nanostack_event_mutex",
33-
.attr_bits = osMutexRecursive,
33+
.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
3434
.cb_mem = &event_mutex,
3535
.cb_size = sizeof event_mutex,
3636
};

platform/mbed_critical.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ bool core_util_are_interrupts_enabled(void)
3737
#endif
3838
}
3939

40+
bool core_util_is_isr_active(void)
41+
{
42+
#if defined(__CORTEX_A9)
43+
switch(__get_CPSR() & 0x1FU) {
44+
case MODE_USR:
45+
case MODE_SYS:
46+
return false;
47+
case MODE_SVC:
48+
default:
49+
return true;
50+
}
51+
#else
52+
return (__get_IPSR() != 0U);
53+
#endif
54+
}
55+
4056
MBED_WEAK void core_util_critical_section_enter(void)
4157
{
4258
bool interrupts_disabled = !core_util_are_interrupts_enabled();

platform/mbed_critical.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ extern "C" {
4141
*/
4242
bool core_util_are_interrupts_enabled(void);
4343

44+
/** Determine if this code is executing from an interrupt
45+
*
46+
* This function can be called to determine if the code is running on interrupt context.
47+
* @note
48+
* NOTE:
49+
* This function works for both cortex-A and cortex-M, although the underlyng implementation
50+
* differs.
51+
* @return true if in an isr, false otherwise
52+
*/
53+
bool core_util_is_isr_active(void);
54+
4455
/** Mark the start of a critical section
4556
*
4657
* This function should be called to mark the start of a critical section of code.

platform/mbed_error.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@
2323
#include <stdio.h>
2424
#endif
2525

26+
static uint8_t error_in_progress = 0;
27+
2628
WEAK void error(const char* format, ...) {
29+
30+
// Prevent recursion if error is called again
31+
if (error_in_progress) {
32+
return;
33+
}
34+
error_in_progress = 1;
35+
2736
#ifndef NDEBUG
2837
va_list arg;
2938
va_start(arg, format);

platform/mbed_retarget.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "platform/PlatformMutex.h"
2424
#include "platform/mbed_error.h"
2525
#include "platform/mbed_stats.h"
26+
#include "platform/mbed_critical.h"
2627
#if MBED_CONF_FILESYSTEM_PRESENT
2728
#include "filesystem/FileSystem.h"
2829
#include "filesystem/File.h"
@@ -309,6 +310,12 @@ extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsign
309310
#endif
310311
int n; // n is the number of bytes written
311312

313+
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
314+
if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
315+
error("Error - writing to a file in an ISR or critical section\r\n");
316+
}
317+
#endif
318+
312319
if (fh < 3) {
313320
#if DEVICE_SERIAL
314321
if (!stdio_uart_inited) init_serial();
@@ -353,6 +360,12 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int
353360
#endif
354361
int n; // n is the number of bytes read
355362

363+
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
364+
if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
365+
error("Error - reading from a file in an ISR or critical section\r\n");
366+
}
367+
#endif
368+
356369
if (fh < 3) {
357370
// only read a character at a time from stdin
358371
#if DEVICE_SERIAL
@@ -1033,3 +1046,67 @@ void operator delete[](void *ptr)
10331046
free(ptr);
10341047
}
10351048
}
1049+
1050+
#if defined(MBED_CONF_RTOS_PRESENT) && defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
1051+
1052+
static const char* error_msg(int32_t status)
1053+
{
1054+
switch (status) {
1055+
case osError:
1056+
return "Unspecified RTOS error";
1057+
case osErrorTimeout:
1058+
return "Operation not completed within the timeout period";
1059+
case osErrorResource:
1060+
return "Resource not available";
1061+
case osErrorParameter:
1062+
return "Parameter error";
1063+
case osErrorNoMemory:
1064+
return "System is out of memory";
1065+
case osErrorISR:
1066+
return "Not allowed in ISR context";
1067+
default:
1068+
return "Unknown";
1069+
}
1070+
}
1071+
1072+
extern "C" void EvrRtxKernelError (int32_t status)
1073+
{
1074+
error("Kernel error %i: %s\r\n", status, error_msg(status));
1075+
}
1076+
1077+
extern "C" void EvrRtxThreadError (osThreadId_t thread_id, int32_t status)
1078+
{
1079+
error("Thread %p error %i: %s\r\n", thread_id, status, error_msg(status));
1080+
}
1081+
1082+
extern "C" void EvrRtxTimerError (osTimerId_t timer_id, int32_t status)
1083+
{
1084+
error("Timer %p error %i: %s\r\n", timer_id, status, error_msg(status));
1085+
}
1086+
1087+
extern "C" void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status)
1088+
{
1089+
error("Event %p error %i: %s\r\n", ef_id, status, error_msg(status));
1090+
}
1091+
1092+
extern "C" void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status)
1093+
{
1094+
error("Mutex %p error %i: %s\r\n", mutex_id, status, error_msg(status));
1095+
}
1096+
1097+
extern "C" void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status)
1098+
{
1099+
error("Semaphore %p error %i\r\n", semaphore_id, status);
1100+
}
1101+
1102+
extern "C" void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status)
1103+
{
1104+
error("Memory Pool %p error %i\r\n", mp_id, status);
1105+
}
1106+
1107+
extern "C" void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status)
1108+
{
1109+
error("Message Queue %p error %i\r\n", mq_id, status);
1110+
}
1111+
1112+
#endif

rtos/Mutex.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void Mutex::constructor(const char *name)
4444
_attr.name = name ? name : "aplication_unnamed_mutex";
4545
_attr.cb_mem = &_obj_mem;
4646
_attr.cb_size = sizeof(_obj_mem);
47-
_attr.attr_bits = osMutexRecursive;
47+
_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
4848
_id = osMutexNew(&_attr);
4949
MBED_ASSERT(_id);
5050
}

rtos/Thread.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ osStatus Thread::start(Callback<void()> task) {
103103
}
104104

105105
osStatus Thread::terminate() {
106-
osStatus_t ret;
106+
osStatus_t ret = osOK;
107107
_mutex.lock();
108108

109109
// Set the Thread's tid to NULL and
@@ -112,11 +112,11 @@ osStatus Thread::terminate() {
112112
osThreadId_t local_id = _tid;
113113
_join_sem.release();
114114
_tid = (osThreadId_t)NULL;
115-
_finished = true;
115+
if (!_finished) {
116+
_finished = true;
117+
ret = osThreadTerminate(local_id);
118+
}
116119
_mutex.unlock();
117-
118-
ret = osThreadTerminate(local_id);
119-
120120
return ret;
121121
}
122122

@@ -352,8 +352,8 @@ void Thread::_thunk(void * thread_ptr)
352352
t->_mutex.lock();
353353
t->_tid = (osThreadId)NULL;
354354
t->_finished = true;
355-
t->_mutex.unlock();
356355
t->_join_sem.release();
356+
// rtos will release the mutex automatically
357357
}
358358

359359
}

rtos/mbed_boot.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ void $Sub$$__cpp_initialize__aeabi_(void)
363363
void pre_main()
364364
{
365365
singleton_mutex_attr.name = "singleton_mutex";
366-
singleton_mutex_attr.attr_bits = osMutexRecursive;
366+
singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
367367
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
368368
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
369369
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
@@ -383,7 +383,7 @@ extern int main(int argc, char* argv[]);
383383
void pre_main (void)
384384
{
385385
singleton_mutex_attr.name = "singleton_mutex";
386-
singleton_mutex_attr.attr_bits = osMutexRecursive;
386+
singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
387387
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
388388
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
389389
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
@@ -440,19 +440,19 @@ int __wrap_main(void) {
440440
void pre_main(void)
441441
{
442442
singleton_mutex_attr.name = "singleton_mutex";
443-
singleton_mutex_attr.attr_bits = osMutexRecursive;
443+
singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
444444
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
445445
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
446446
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
447447

448448
malloc_mutex_attr.name = "malloc_mutex";
449-
malloc_mutex_attr.attr_bits = osMutexRecursive;
449+
malloc_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
450450
malloc_mutex_attr.cb_size = sizeof(malloc_mutex_obj);
451451
malloc_mutex_attr.cb_mem = &malloc_mutex_obj;
452452
malloc_mutex_id = osMutexNew(&malloc_mutex_attr);
453453

454454
env_mutex_attr.name = "env_mutex";
455-
env_mutex_attr.attr_bits = osMutexRecursive;
455+
env_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
456456
env_mutex_attr.cb_size = sizeof(env_mutex_obj);
457457
env_mutex_attr.cb_mem = &env_mutex_obj;
458458
env_mutex_id = osMutexNew(&env_mutex_attr);
@@ -526,7 +526,7 @@ static uint8_t low_level_init_needed;
526526
void pre_main(void)
527527
{
528528
singleton_mutex_attr.name = "singleton_mutex";
529-
singleton_mutex_attr.attr_bits = osMutexRecursive;
529+
singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
530530
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
531531
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
532532
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
@@ -583,7 +583,7 @@ void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */
583583
attr.name = "system_mutex";
584584
attr.cb_mem = &std_mutex_sys[index];
585585
attr.cb_size = sizeof(std_mutex_sys[index]);
586-
attr.attr_bits = osMutexRecursive;
586+
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
587587
std_mutex_id_sys[index] = osMutexNew(&attr);
588588
*mutex = (__iar_Rmtx*)&std_mutex_id_sys[index];
589589
return;
@@ -619,7 +619,7 @@ void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */
619619
attr.name = "file_mutex";
620620
attr.cb_mem = &std_mutex_file[index];
621621
attr.cb_size = sizeof(std_mutex_file[index]);
622-
attr.attr_bits = osMutexRecursive;
622+
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
623623
std_mutex_id_file[index] = osMutexNew(&attr);
624624
*mutex = (__iar_Rmtx*)&std_mutex_id_file[index];
625625
return;

rtos/mbed_rtos_storage.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#ifndef MBED_RTOS_STORAGE_H
2323
#define MBED_RTOS_STORAGE_H
2424

25+
#ifdef __cplusplus
26+
extern "C" {
27+
#endif
28+
2529
/** \addtogroup rtos */
2630
/** @{*/
2731

@@ -47,6 +51,10 @@ typedef os_event_flags_t mbed_rtos_storage_event_flags_t;
4751
typedef os_message_t mbed_rtos_storage_message_t;
4852
typedef os_timer_t mbed_rtos_storage_timer_t;
4953

54+
#ifdef __cplusplus
55+
}
56+
#endif
57+
5058
#endif
5159

5260
/** @}*/

tools/profiles/debug.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
66
"-ffunction-sections", "-fdata-sections", "-funsigned-char",
77
"-MMD", "-fno-delete-null-pointer-checks",
8-
"-fomit-frame-pointer", "-O0", "-g3", "-DMBED_DEBUG"],
8+
"-fomit-frame-pointer", "-O0", "-g3", "-DMBED_DEBUG",
9+
"-DMBED_TRAP_ERRORS_ENABLED=1"],
910
"asm": ["-x", "assembler-with-cpp"],
1011
"c": ["-std=gnu99"],
1112
"cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"],
@@ -17,7 +18,8 @@
1718
"ARM": {
1819
"common": ["-c", "--gnu", "-Otime", "--split_sections",
1920
"--apcs=interwork", "--brief_diagnostics", "--restrict",
20-
"--multibyte_chars", "-O0", "-g", "-DMBED_DEBUG"],
21+
"--multibyte_chars", "-O0", "-g", "-DMBED_DEBUG",
22+
"-DMBED_TRAP_ERRORS_ENABLED=1"],
2123
"asm": [],
2224
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
2325
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
@@ -27,7 +29,8 @@
2729
"common": ["-c", "--gnu", "-Otime", "--split_sections",
2830
"--apcs=interwork", "--brief_diagnostics", "--restrict",
2931
"--multibyte_chars", "-O0", "-D__MICROLIB", "-g",
30-
"--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DMBED_DEBUG"],
32+
"--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DMBED_DEBUG",
33+
"-DMBED_TRAP_ERRORS_ENABLED=1"],
3134
"asm": [],
3235
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
3336
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
@@ -36,7 +39,8 @@
3639
"IAR": {
3740
"common": [
3841
"--no_wrap_diagnostics", "-e",
39-
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-On", "-r", "-DMBED_DEBUG"],
42+
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-On", "-r", "-DMBED_DEBUG",
43+
"-DMBED_TRAP_ERRORS_ENABLED=1"],
4044
"asm": [],
4145
"c": ["--vla"],
4246
"cxx": ["--guard_calls", "--no_static_destruction"],

0 commit comments

Comments
 (0)