aboutsummaryrefslogtreecommitdiffstats
path: root/ports
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-03-18 16:31:24 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-03-18 16:31:24 +0000
commit7eb7630d937ea87275bafee866e9fd6aaea61902 (patch)
tree99a64877c089bb03ea8f57f30411178cc56198ee /ports
parent5bcaee51a3533c2b1af50c610cff5827ce9b5bcb (diff)
downloadChibiOS-7eb7630d937ea87275bafee866e9fd6aaea61902.tar.gz
ChibiOS-7eb7630d937ea87275bafee866e9fd6aaea61902.tar.bz2
ChibiOS-7eb7630d937ea87275bafee866e9fd6aaea61902.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@241 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'ports')
-rw-r--r--ports/ARMCM3/chcore.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/ports/ARMCM3/chcore.c b/ports/ARMCM3/chcore.c
index 7ef8f8daf..e54d52542 100644
--- a/ports/ARMCM3/chcore.c
+++ b/ports/ARMCM3/chcore.c
@@ -70,6 +70,32 @@ void threadstart(void) {
void *retaddr;
+/*
+ * Software-generated interrupt, it must have the lowest possible priority so
+ * it is executed last in the interrupts tail-chain.
+ */
+void PendSVVector(void) {
+
+ chSysLock();
+
+ if (!chSchRescRequiredI()) {
+
+ chSysUnlock();
+ return;
+ }
+
+ asm volatile ("mrs r0, PSP \n\t" \
+ "ldr r1, =retaddr \n\t" \
+ "ldr r2, [r0, #18] \n\t" \
+ "str r2, [r1] \n\t" \
+ "ldr r1, =threadswitch \n\t" \
+ "str r1, [r0, #18] ");
+}
+
+/*
+ * This code is execute in thread mode when exiting from an ISR routine that
+ * requires rescheduling.
+ */
__attribute__((naked, weak))
void threadswitch(void) {
@@ -78,11 +104,9 @@ void threadswitch(void) {
"mrs r0, XPSR \n\t" \
"push {r0} \n\t" \
"ldr r0, =retaddr \n\t" \
- "str r0, [sp, #28] ");
-
- chSchDoRescheduleI();
-
- asm volatile ("pop {r0} \n\t" \
+ "str r0, [sp, #28] \n\t" \
+ "b chSchDoRescheduleI \n\t" \
+ "pop {r0} \n\t" \
"msr XPSR, r0 \n\t" \
"pop {r0-r3, r12, lr} \n\t" \
"cpsie i \n\t" \