Skip to content

Commit e453b5e

Browse files
authored
Merge pull request #2391 from geky/fix-rtos-critical-sections
[rtos] Fix irq-safe rtx calls when inside critical sections
2 parents f0c00bf + 3e7b5ed commit e453b5e

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)