/* * stm32f4xx_ctx.c * * Created on: Oct 1, 2015 * Author: tkl */ #include #include "stm32f4xx.h" #include "stack.h" #include "queue.h" #include "thread.h" #include "stm32f4xx_ctx.h" #ifdef __NVIC_PRIO_BITS /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) #define portNVIC_SYSPRI2_REG (*((volatile uint32_t *)0xe000ed20)) #define portNVIC_PENDSV_PRI (((uint32_t)configKERNEL_INTERRUPT_PRIORITY) << 16UL) #define portNVIC_SYSTICK_PRI (((uint32_t)configKERNEL_INTERRUPT_PRIORITY) << 24UL) extern volatile struct thread_context *current_thread; void start_first_task(void) __attribute__ ((naked)); void PendSV_Handler(void) __attribute__ ((naked)); void SVC_Handler(void) __attribute__ ((naked)); void start_first_task(void) { portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; __asm volatile("ldr r0, =0xE000ED08"); __asm volatile("ldr r0, [r0]"); __asm volatile("ldr r0, [r0]"); __asm volatile("msr msp, r0"); __asm volatile("cpsie i"); __asm volatile("cpsie f"); __asm volatile("dsb"); __asm volatile("isb"); __asm volatile("svc 0"); __asm volatile("nop"); } void arch_schedule(void) { *((volatile unsigned long *) 0xe000ed04) = 0x10000000; } #define MAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - __NVIC_PRIO_BITS) ) void PendSV_Handler (void) { __asm volatile("mrs r0, psp"); __asm volatile("isb"); __asm volatile("ldr r3, =current_thread"); __asm volatile("ldr r2, [r3]"); __asm volatile("tst r14, #0x10"); __asm volatile("it eq"); __asm volatile("vstmdbeq r0!, {s16-s31}"); __asm volatile("stmdb r0!, {r4-r11, r14}"); __asm volatile("str r0, [r2]"); __asm volatile("stmdb sp!, {r3}"); __asm volatile("mov r0, %0"::"i"(MAX_SYSCALL_INTERRUPT_PRIORITY)); __asm volatile("msr basepri, r0"); __asm volatile("dsb"); __asm volatile("isb"); __asm volatile("bl thread_switch_context"); __asm volatile("mov r0, #0"); __asm volatile("msr basepri, r0"); __asm volatile("ldmia sp!, {r3}"); __asm volatile("ldr r1, [r3]"); __asm volatile("ldr r0, [r1]"); __asm volatile("ldmia r0!, {r4-r11, r14}"); __asm volatile("tst r14, #0x10"); __asm volatile("it eq"); __asm volatile("vldmiaeq r0!, {s16-s31}"); __asm volatile("msr psp, r0"); __asm volatile("isb"); __asm volatile("bx r14"); } void SVC_Handler(void) { __asm volatile("ldr r3, =current_thread"); __asm volatile("ldr r1, [r3]"); __asm volatile("ldr r0, [r1]"); __asm volatile("ldmia r0!, {r4-r11, r14}"); __asm volatile("msr psp, r0"); __asm volatile("isb"); __asm volatile("mov r0, #0"); __asm volatile("msr basepri, r0"); __asm volatile("bx r14"); }