Skip to content

Commit 3e7b5ed

Browse files
committed
Fixed rtx calls when inside critical sections
Before, rtx calls would hard fault in critical sections when an svc instruction was attempted with interrupts disabled. Required changes: - Added check for CPSR I bit in cortex A rtx - Added check for PRIMASK in cortex M rtx - Modified critical sections in cortex M rtx to be recursive (already recursive in cortex A)
1 parent e9c556d commit 3e7b5ed

File tree

3 files changed

+90
-44
lines changed

3 files changed

+90
-44
lines changed

rtos/rtx/TARGET_CORTEX_A/rt_CMSIS.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,11 @@ static __inline char __get_mode(void) {
543543
}
544544

545545
static __inline char __exceptional_mode(void) {
546+
// Interrupts disabled
547+
if (__get_CPSR() & 0x80) {
548+
return 1;
549+
}
550+
546551
switch(__get_mode()) {
547552
case MODE_USR:
548553
case MODE_SYS:

rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ uint32_t svcKernelSysTick (void) {
552552

553553
/// Initialize the RTOS Kernel for creating objects
554554
osStatus osKernelInitialize (void) {
555-
if (__get_IPSR() != 0U) {
555+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
556556
return osErrorISR; // Not allowed in ISR
557557
}
558558
if ((__get_CONTROL() & 1U) == 0U) { // Privileged mode
@@ -566,7 +566,7 @@ osStatus osKernelInitialize (void) {
566566
osStatus osKernelStart (void) {
567567
uint32_t stack[8];
568568

569-
if (__get_IPSR() != 0U) {
569+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
570570
return osErrorISR; // Not allowed in ISR
571571
}
572572

@@ -607,7 +607,7 @@ osStatus osKernelStart (void) {
607607

608608
/// Check if the RTOS kernel is already started
609609
int32_t osKernelRunning (void) {
610-
if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
610+
if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) {
611611
// in ISR or Privileged
612612
return (int32_t)os_running;
613613
} else {
@@ -617,7 +617,7 @@ int32_t osKernelRunning (void) {
617617

618618
/// Get the RTOS kernel system timer counter
619619
uint32_t osKernelSysTick (void) {
620-
if (__get_IPSR() != 0U) { return 0U; } // Not allowed in ISR
620+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { return 0U; } // Not allowed in ISR
621621
return __svcKernelSysTick();
622622
}
623623

@@ -867,7 +867,7 @@ osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) {
867867
return osThreadContextCreate(thread_def, argument, NULL);
868868
}
869869
osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context) {
870-
if (__get_IPSR() != 0U) {
870+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
871871
return NULL; // Not allowed in ISR
872872
}
873873
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -885,7 +885,7 @@ osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argumen
885885

886886
/// Return the thread ID of the current running thread
887887
osThreadId osThreadGetId (void) {
888-
if (__get_IPSR() != 0U) {
888+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
889889
return NULL; // Not allowed in ISR
890890
}
891891
return __svcThreadGetId();
@@ -894,7 +894,7 @@ osThreadId osThreadGetId (void) {
894894
/// Terminate execution of a thread and remove it from ActiveThreads
895895
osStatus osThreadTerminate (osThreadId thread_id) {
896896
osStatus status;
897-
if (__get_IPSR() != 0U) {
897+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
898898
return osErrorISR; // Not allowed in ISR
899899
}
900900
osMutexWait(osMutexId_osThreadMutex, osWaitForever);
@@ -907,23 +907,23 @@ osStatus osThreadTerminate (osThreadId thread_id) {
907907

908908
/// Pass control to next thread that is in state READY
909909
osStatus osThreadYield (void) {
910-
if (__get_IPSR() != 0U) {
910+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
911911
return osErrorISR; // Not allowed in ISR
912912
}
913913
return __svcThreadYield();
914914
}
915915

916916
/// Change priority of an active thread
917917
osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
918-
if (__get_IPSR() != 0U) {
918+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
919919
return osErrorISR; // Not allowed in ISR
920920
}
921921
return __svcThreadSetPriority(thread_id, priority);
922922
}
923923

924924
/// Get current priority of an active thread
925925
osPriority osThreadGetPriority (osThreadId thread_id) {
926-
if (__get_IPSR() != 0U) {
926+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
927927
return osPriorityError; // Not allowed in ISR
928928
}
929929
return __svcThreadGetPriority(thread_id);
@@ -948,7 +948,7 @@ __NO_RETURN void osThreadExit (void) {
948948
uint8_t osThreadGetState (osThreadId thread_id) {
949949
P_TCB ptcb;
950950

951-
if (__get_IPSR() != 0U) return osErrorISR; // Not allowed in ISR
951+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) return osErrorISR; // Not allowed in ISR
952952

953953
ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
954954
if (ptcb == NULL) return INACTIVE;
@@ -1040,7 +1040,7 @@ os_InRegs osEvent_type svcWait (uint32_t millisec) {
10401040

10411041
/// Wait for Timeout (Time Delay)
10421042
osStatus osDelay (uint32_t millisec) {
1043-
if (__get_IPSR() != 0U) {
1043+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
10441044
return osErrorISR; // Not allowed in ISR
10451045
}
10461046
return __svcDelay(millisec);
@@ -1054,7 +1054,7 @@ os_InRegs osEvent osWait (uint32_t millisec) {
10541054
ret.status = osErrorOS;
10551055
return ret;
10561056
#else
1057-
if (__get_IPSR() != 0U) { // Not allowed in ISR
1057+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // Not allowed in ISR
10581058
ret.status = osErrorISR;
10591059
return ret;
10601060
}
@@ -1337,7 +1337,7 @@ void sysUserTimerUpdate (uint32_t sleep_time) {
13371337

13381338
/// Create timer
13391339
osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
1340-
if (__get_IPSR() != 0U) {
1340+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
13411341
return NULL; // Not allowed in ISR
13421342
}
13431343
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1350,23 +1350,23 @@ osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void
13501350

13511351
/// Start or restart timer
13521352
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
1353-
if (__get_IPSR() != 0U) {
1353+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
13541354
return osErrorISR; // Not allowed in ISR
13551355
}
13561356
return __svcTimerStart(timer_id, millisec);
13571357
}
13581358

13591359
/// Stop timer
13601360
osStatus osTimerStop (osTimerId timer_id) {
1361-
if (__get_IPSR() != 0U) {
1361+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
13621362
return osErrorISR; // Not allowed in ISR
13631363
}
13641364
return __svcTimerStop(timer_id);
13651365
}
13661366

13671367
/// Delete timer
13681368
osStatus osTimerDelete (osTimerId timer_id) {
1369-
if (__get_IPSR() != 0U) {
1369+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
13701370
return osErrorISR; // Not allowed in ISR
13711371
}
13721372
return __svcTimerDelete(timer_id);
@@ -1503,7 +1503,7 @@ int32_t isrSignalSet (osThreadId thread_id, int32_t signals) {
15031503

15041504
/// Set the specified Signal Flags of an active thread
15051505
int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
1506-
if (__get_IPSR() != 0U) { // in ISR
1506+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
15071507
return isrSignalSet(thread_id, signals);
15081508
} else { // in Thread
15091509
return __svcSignalSet(thread_id, signals);
@@ -1512,7 +1512,7 @@ int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
15121512

15131513
/// Clear the specified Signal Flags of an active thread
15141514
int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
1515-
if (__get_IPSR() != 0U) {
1515+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
15161516
return (int32_t)0x80000000U; // Not allowed in ISR
15171517
}
15181518
return __svcSignalClear(thread_id, signals);
@@ -1522,7 +1522,7 @@ int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
15221522
os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
15231523
osEvent ret;
15241524

1525-
if (__get_IPSR() != 0U) { // Not allowed in ISR
1525+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // Not allowed in ISR
15261526
ret.status = osErrorISR;
15271527
return ret;
15281528
}
@@ -1634,7 +1634,7 @@ osStatus svcMutexDelete (osMutexId mutex_id) {
16341634

16351635
/// Create and Initialize a Mutex object
16361636
osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
1637-
if (__get_IPSR() != 0U) {
1637+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
16381638
return NULL; // Not allowed in ISR
16391639
}
16401640
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1647,23 +1647,23 @@ osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
16471647

16481648
/// Wait until a Mutex becomes available
16491649
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
1650-
if (__get_IPSR() != 0U) {
1650+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
16511651
return osErrorISR; // Not allowed in ISR
16521652
}
16531653
return __svcMutexWait(mutex_id, millisec);
16541654
}
16551655

16561656
/// Release a Mutex that was obtained with osMutexWait
16571657
osStatus osMutexRelease (osMutexId mutex_id) {
1658-
if (__get_IPSR() != 0U) {
1658+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
16591659
return osErrorISR; // Not allowed in ISR
16601660
}
16611661
return __svcMutexRelease(mutex_id);
16621662
}
16631663

16641664
/// Delete a Mutex that was created by osMutexCreate
16651665
osStatus osMutexDelete (osMutexId mutex_id) {
1666-
if (__get_IPSR() != 0U) {
1666+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
16671667
return osErrorISR; // Not allowed in ISR
16681668
}
16691669
return __svcMutexDelete(mutex_id);
@@ -1801,7 +1801,7 @@ osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) {
18011801

18021802
/// Create and Initialize a Semaphore object
18031803
osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
1804-
if (__get_IPSR() != 0U) {
1804+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
18051805
return NULL; // Not allowed in ISR
18061806
}
18071807
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1814,24 +1814,24 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t
18141814

18151815
/// Wait until a Semaphore becomes available
18161816
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
1817-
if (__get_IPSR() != 0U) {
1817+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
18181818
return -1; // Not allowed in ISR
18191819
}
18201820
return __svcSemaphoreWait(semaphore_id, millisec);
18211821
}
18221822

18231823
/// Release a Semaphore
18241824
osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
1825-
if (__get_IPSR() != 0U) { // in ISR
1825+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
18261826
return isrSemaphoreRelease(semaphore_id);
1827-
} else { // in Thread
1827+
} else { // in Thread
18281828
return __svcSemaphoreRelease(semaphore_id);
18291829
}
18301830
}
18311831

18321832
/// Delete a Semaphore that was created by osSemaphoreCreate
18331833
osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
1834-
if (__get_IPSR() != 0U) {
1834+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
18351835
return osErrorISR; // Not allowed in ISR
18361836
}
18371837
return __svcSemaphoreDelete(semaphore_id);
@@ -1914,7 +1914,7 @@ osStatus sysPoolFree (osPoolId pool_id, void *block) {
19141914

19151915
/// Create and Initialize memory pool
19161916
osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
1917-
if (__get_IPSR() != 0U) {
1917+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
19181918
return NULL; // Not allowed in ISR
19191919
}
19201920
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -1927,7 +1927,7 @@ osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
19271927

19281928
/// Allocate a memory block from a memory pool
19291929
void *osPoolAlloc (osPoolId pool_id) {
1930-
if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
1930+
if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
19311931
return sysPoolAlloc(pool_id);
19321932
} else { // in Thread
19331933
return __sysPoolAlloc(pool_id);
@@ -1938,7 +1938,7 @@ void *osPoolAlloc (osPoolId pool_id) {
19381938
void *osPoolCAlloc (osPoolId pool_id) {
19391939
void *mem;
19401940

1941-
if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
1941+
if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
19421942
mem = sysPoolAlloc(pool_id);
19431943
} else { // in Thread
19441944
mem = __sysPoolAlloc(pool_id);
@@ -1951,7 +1951,7 @@ void *osPoolCAlloc (osPoolId pool_id) {
19511951

19521952
/// Return an allocated memory block back to a specific memory pool
19531953
osStatus osPoolFree (osPoolId pool_id, void *block) {
1954-
if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
1954+
if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged
19551955
return sysPoolFree(pool_id, block);
19561956
} else { // in Thread
19571957
return __sysPoolFree(pool_id, block);
@@ -2091,7 +2091,7 @@ os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) {
20912091

20922092
/// Create and Initialize Message Queue
20932093
osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
2094-
if (__get_IPSR() != 0U) {
2094+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
20952095
return NULL; // Not allowed in ISR
20962096
}
20972097
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -2104,7 +2104,7 @@ osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId threa
21042104

21052105
/// Put a Message to a Queue
21062106
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
2107-
if (__get_IPSR() != 0U) { // in ISR
2107+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
21082108
return isrMessagePut(queue_id, info, millisec);
21092109
} else { // in Thread
21102110
return __svcMessagePut(queue_id, info, millisec);
@@ -2113,7 +2113,7 @@ osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec)
21132113

21142114
/// Get a Message or Wait for a Message from a Queue
21152115
os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
2116-
if (__get_IPSR() != 0U) { // in ISR
2116+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
21172117
return isrMessageGet(queue_id, millisec);
21182118
} else { // in Thread
21192119
return __svcMessageGet(queue_id, millisec);
@@ -2250,7 +2250,7 @@ osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
22502250

22512251
/// Create and Initialize mail queue
22522252
osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
2253-
if (__get_IPSR() != 0U) {
2253+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) {
22542254
return NULL; // Not allowed in ISR
22552255
}
22562256
if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) {
@@ -2263,7 +2263,7 @@ osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
22632263

22642264
/// Allocate a memory block from a mail
22652265
void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
2266-
if (__get_IPSR() != 0U) { // in ISR
2266+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
22672267
return sysMailAlloc(queue_id, millisec, 1U);
22682268
} else { // in Thread
22692269
return __sysMailAlloc(queue_id, millisec, 0U);
@@ -2275,7 +2275,7 @@ void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
22752275
void *pool;
22762276
void *mem;
22772277

2278-
if (__get_IPSR() != 0U) { // in ISR
2278+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
22792279
mem = sysMailAlloc(queue_id, millisec, 1U);
22802280
} else { // in Thread
22812281
mem = __sysMailAlloc(queue_id, millisec, 0U);
@@ -2290,7 +2290,7 @@ void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
22902290

22912291
/// Free a memory block from a mail
22922292
osStatus osMailFree (osMailQId queue_id, void *mail) {
2293-
if (__get_IPSR() != 0U) { // in ISR
2293+
if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR
22942294
return sysMailFree(queue_id, mail, 1U);
22952295
} else { // in Thread
22962296
return __sysMailFree(queue_id, mail, 0U);

0 commit comments

Comments
 (0)