From f1ae9df82658d2e29402c931b098336909f772a3 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 15 Apr 2008 15:42:34 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@266 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32F103-GCC/board.c | 5 +- ports/ARMCM3/chcore.c | 113 +++++++++++++++++++---------- ports/ARMCM3/chcore.h | 32 ++++---- ports/ARMCM3/nvic.h | 16 ++-- 4 files changed, 101 insertions(+), 65 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) { +__attribute__((naked)) +void SVCallVector(Thread *otp, Thread *ntp) { - 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" \ - "cpsie i \n\t" \ - "pop {pc} "); +#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" \ + "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)