summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cortex-m0/task.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c
index b067e25f62..95b758abb8 100644
--- a/core/cortex-m0/task.c
+++ b/core/cortex-m0/task.c
@@ -329,6 +329,13 @@ static uint32_t __wait_evt(int timeout_us, task_id_t resched)
ASSERT(ret == EC_SUCCESS);
}
while (!(evt = atomic_read_clear(&tsk->events))) {
+ /*
+ * We need to ensure that the execution priority is actually
+ * decreased after the "cpsie i" in the atomic operation above
+ * else the "svc" in the __schedule call below will trigger
+ * a HardFault. Use a barrier to force it at that point.
+ */
+ asm volatile("isb");
/* Remove ourself and get the next task in the scheduler */
__schedule(1, resched);
resched = TASK_ID_IDLE;
@@ -354,10 +361,19 @@ uint32_t task_set_event(task_id_t tskid, uint32_t event, int wait)
need_resched_or_profiling = 1;
#endif
} else {
- if (wait)
+ if (wait) {
return __wait_evt(-1, tskid);
- else
+ } else {
+ /*
+ * We need to ensure that the execution priority is
+ * actually decreased after the "cpsie i" in the atomic
+ * operation above else the "svc" in the __schedule
+ * call below will trigger a HardFault.
+ * Use a barrier to force it at that point.
+ */
+ asm volatile("isb");
__schedule(0, tskid);
+ }
}
return 0;