aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-04-15 15:42:34 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-04-15 15:42:34 +0000
commitf1ae9df82658d2e29402c931b098336909f772a3 (patch)
tree672a0dc6cf8025ee7eb69af905f724f02671a912
parent2da330780e25ff1a1df4e18277bb2230437be5d5 (diff)
downloadChibiOS-f1ae9df82658d2e29402c931b098336909f772a3.tar.gz
ChibiOS-f1ae9df82658d2e29402c931b098336909f772a3.tar.bz2
ChibiOS-f1ae9df82658d2e29402c931b098336909f772a3.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@266 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--demos/ARMCM3-STM32F103-GCC/board.c5
-rw-r--r--ports/ARMCM3/chcore.c115
-rw-r--r--ports/ARMCM3/chcore.h32
-rw-r--r--ports/ARMCM3/nvic.h16
4 files changed, 102 insertions, 66 deletions
diff --git a/demos/ARMCM3-STM32F103-GCC/board.c b/demos/ARMCM3-STM32F103-GCC/board.c
index 38a8e177c..f10269aa6 100644
--- a/demos/ARMCM3-STM32F103-GCC/board.c
+++ b/demos/ARMCM3-STM32F103-GCC/board.c
@@ -81,11 +81,12 @@ void hwinit(void) {
* NVIC/SCB initialization.
*/
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0x3); // PRIGROUP 4:0 (4:4).
+ SCB_SHPR(2) = 0xF0 << 16; // PendSV at lowest priority.
/*
* SysTick initialization.
*/
- SCB_SHPR(2) = 0x80 << 24; // SysTick at priority 8:0.
+ SCB_SHPR(2) |= 0x40 << 24; // SysTick at priority 4:0.
ST_RVR = SYSCLK / (8000000 / CH_FREQUENCY) - 1;
ST_CVR = 0;
ST_CSR = ENABLE_ON_BITS | TICKINT_ENABLED_BITS | CLKSOURCE_EXT_BITS;
@@ -93,5 +94,5 @@ void hwinit(void) {
/*
* Other subsystems initialization.
*/
- InitSerial(0xA0, 0xA0, 0xA0);
+ InitSerial(0x80, 0x80, 0x80);
}
diff --git a/ports/ARMCM3/chcore.c b/ports/ARMCM3/chcore.c
index 4f4019706..25df8413f 100644
--- a/ports/ARMCM3/chcore.c
+++ b/ports/ARMCM3/chcore.c
@@ -23,15 +23,18 @@
/*
* System idle thread loop.
*/
+__attribute__((weak))
void _IdleThread(void *p) {
while (TRUE) {
+// asm volatile ("wfi");
}
}
/*
* System console message (not implemented).
*/
+__attribute__((weak))
void chSysPuts(char *msg) {
}
@@ -39,15 +42,10 @@ void chSysPuts(char *msg) {
* Context switch.
*/
void chSysSwitchI(Thread *otp, Thread *ntp) {
- register struct intctx * volatile sp asm("sp"); /* Don't ask... */
-#ifdef CH_CURRP_REGISTER_CACHE
- asm ("" : : : "r4", "r5", "r6", "r8", "r9", "r10", "r11", "lr");
-#else
- asm ("" : : : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "lr");
-#endif
- otp->p_ctx.r13 = sp;
- sp = ntp->p_ctx.r13;
+ asm volatile ("cpsie i \n\t" \
+ "svc #0 \n\t" \
+ "cpsid i ");
}
/*
@@ -64,10 +62,10 @@ void chSysHalt(void) {
__attribute__((naked, weak))
void threadstart(void) {
- chSysUnlock();
- asm volatile ("mov r0, r5 \n\t" \
- "blx r4 \n\t" \
- "bl chThdExit ");
+ asm volatile ("cpsie i \n\t" \
+ "blx r1 \n\t" \
+ "bl chThdExit \n\t" \
+ "bl chSysHalt ");
}
/*
@@ -93,40 +91,75 @@ void *retaddr;
void chSysIRQExitI(void) {
chSysLock();
- if (SCB_ICSR & ICSR_RETTOBASE_MASK) {
- if (chSchRescRequiredI()) {
-
- asm volatile ("mrs r0, PSP \n\t" \
- "ldr r2, [r0, #24] \n\t" \
- "ldr r1, =retaddr \n\t" \
- "str r2, [r1] \n\t" \
- "ldr r1, =threadswitch \n\t" \
- "str r1, [r0, #24] ");
- return; /* Note, returns *without* re-enabling interrupts.*/
- }
+
+ if ((SCB_ICSR & ICSR_RETTOBASE) && chSchRescRequiredI()) {
+ SCB_ICSR = ICSR_PENDSVSET;
}
+
chSysUnlock();
}
/*
- * This code is executed in thread mode when exiting from an ISR routine that
- * requires rescheduling.
+ * System invoked context switch.
*/
-__attribute__((naked, weak))
-void threadswitch(void) {
-
- asm volatile ("sub sp, sp, #4 \n\t" \
- "push {r0-r3, r12, lr} \n\t" \
- "mrs r0, XPSR \n\t" \
- "push {r0} \n\t" \
- "ldr r0, =retaddr \n\t" \
- "ldr r0, [r0] \n\t" \
- "orr r0, r0, #1 \n\t" \
- "str r0, [sp, #28] \n\t" \
- "bl chSchDoRescheduleI \n\t" \
- "pop {r0} \n\t" \
- "msr XPSR, r0 \n\t" \
- "pop {r0-r3, r12, lr} \n\t" \
+__attribute__((naked))
+void SVCallVector(Thread *otp, Thread *ntp) {
+
+#ifdef CH_CURRP_REGISTER_CACHE
+ asm volatile ("mrs r12, PSP \n\t" \
+ "stmdb r12!, {r4-6,r8-r11, lr} \n\t" \
+ "str r12, [r0, #16] \n\t" \
+ "ldr r12, [r1, #16] \n\t" \
+ "ldmia r12!, {r4-6,r8-r11, lr} \n\t" \
+ "msr PSP, r12 \n\t" \
+ "bx lr ");
+#else
+ asm volatile ("mrs r12, PSP \n\t" \
+ "stmdb r12!, {r4-r11, lr} \n\t" \
+ "str r12, [r0, #16] \n\t" \
+ "ldr r12, [r1, #16] \n\t" \
+ "ldmia r12!, {r4-r11, lr} \n\t" \
+ "msr PSP, r12 \n\t" \
+ "bx lr ");
+#endif
+}
+
+/*
+ * Preemption invoked context switch.
+ */
+__attribute__((naked))
+void PendSVVector(void) {
+ Thread *otp;
+ register struct intctx *sp_thd asm("r12");
+
+ asm volatile ("cpsid i \n\t" \
+ "mrs %0, PSP" : "=r" (sp_thd) : );
+#ifdef CH_CURRP_REGISTER_CACHE
+ asm volatile ("stmdb %0!, {r4-r6,r8-r11, lr}" :
+ "=r" (sp_thd) :
+ "r" (sp_thd));
+#else
+ asm volatile ("stmdb %0!, {r4-r11, lr}" :
+ "=r" (sp_thd) :
+ "r" (sp_thd));
+#endif
+
+ (otp = currp)->p_ctx.r13 = sp_thd;
+ chSchReadyI(otp);
+ (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR;
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#ifdef CH_USE_TRACE
+ chDbgTrace(otp, currp);
+#endif
+
+ sp_thd = currp->p_ctx.r13;
+
+#ifdef CH_CURRP_REGISTER_CACHE
+ asm volatile ("ldmia %0!, {r4-r6,r8-r11, lr}" : : "r" (sp_thd));
+#else
+ asm volatile ("ldmia %0!, {r4-r11, lr}" : : "r" (sp_thd));
+#endif
+ asm volatile ("msr PSP, %0 \n\t" \
"cpsie i \n\t" \
- "pop {pc} ");
+ "bx lr" : : "r" (sp_thd));
}
diff --git a/ports/ARMCM3/chcore.h b/ports/ARMCM3/chcore.h
index 0ff988189..ccb070228 100644
--- a/ports/ARMCM3/chcore.h
+++ b/ports/ARMCM3/chcore.h
@@ -23,17 +23,9 @@
typedef void *regarm;
/*
- * Interrupt saved context.
+ * Interrupt saved context, empty in this architecture.
*/
struct extctx {
- regarm xpsr;
- regarm r0;
- regarm r1;
- regarm r2;
- regarm r3;
- regarm r12;
- regarm lr;
- regarm pc;
};
/*
@@ -50,7 +42,15 @@ struct intctx {
regarm r9;
regarm r10;
regarm r11;
- regarm lr;
+ regarm lr_exc;
+ regarm r0;
+ regarm r1;
+ regarm r2;
+ regarm r3;
+ regarm r12;
+ regarm lr_thd;
+ regarm pc;
+ regarm xpsr;
};
/*
@@ -68,15 +68,17 @@ typedef struct {
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
wsize - \
sizeof(struct intctx)); \
- tp->p_ctx.r13->r4 = pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->lr = threadstart; \
+ tp->p_ctx.r13->r0 = arg; \
+ tp->p_ctx.r13->r1 = pf; \
+ tp->p_ctx.r13->lr_exc = (regarm)0xFFFFFFFD; \
+ tp->p_ctx.r13->pc = threadstart; \
+ tp->p_ctx.r13->xpsr = (regarm)0x01000000; \
}
#define chSysLock() asm("cpsid i")
#define chSysUnlock() asm("cpsie i")
-#define INT_REQUIRED_STACK 0x10
+#define INT_REQUIRED_STACK 0
#define StackAlign(n) ((((n) - 1) | 3) + 1)
#define UserStackSize(n) StackAlign(sizeof(Thread) + \
sizeof(struct intctx) + \
@@ -88,7 +90,7 @@ typedef struct {
#define chSysIRQEnterI()
/* It should be 8.*/
-#define IDLE_THREAD_STACK_SIZE 16
+#define IDLE_THREAD_STACK_SIZE 0
void _IdleThread(void *p) __attribute__((noreturn));
void chSysHalt(void);
diff --git a/ports/ARMCM3/nvic.h b/ports/ARMCM3/nvic.h
index 746a8b740..0cb4cc36b 100644
--- a/ports/ARMCM3/nvic.h
+++ b/ports/ARMCM3/nvic.h
@@ -114,15 +114,15 @@ typedef struct {
#define SCB_AFSR (SCBBase->AFSR)
#define ICSR_VECTACTIVE_MASK (0x1FF << 0)
-#define ICSR_RETTOBASE_MASK (0x1 << 11)
+#define ICSR_RETTOBASE (0x1 << 11)
#define ICSR_VECTPENDING_MASK (0x1FF << 12)
-#define ICSR_ISRPENDING_MASK (0x1 << 22)
-#define ICSR_ISRPREEMPT_MASK (0x1 << 23)
-#define ICSR_PENDSTCLR_MASK (0x1 << 25)
-#define ICSR_PENDSTSET_MASK (0x1 << 26)
-#define ICSR_PENDSVCLR_MASK (0x1 << 27)
-#define ICSR_PENDSVSET_MASK (0x1 << 28)
-#define ICSR_NMIPENDSET_MASK (0x1 << 31)
+#define ICSR_ISRPENDING (0x1 << 22)
+#define ICSR_ISRPREEMPT (0x1 << 23)
+#define ICSR_PENDSTCLR (0x1 << 25)
+#define ICSR_PENDSTSET (0x1 << 26)
+#define ICSR_PENDSVCLR (0x1 << 27)
+#define ICSR_PENDSVSET (0x1 << 28)
+#define ICSR_NMIPENDSET (0x1 << 31)
#define AIRCR_VECTKEY 0x05FA0000
#define AIRCR_PRIGROUP_MASK (0x7 << 8)