100 lines
2.9 KiB
Plaintext
100 lines
2.9 KiB
Plaintext
|
/*
|
||
|
* stm32f4xx_ctx.c
|
||
|
*
|
||
|
* Created on: Oct 1, 2015
|
||
|
* Author: tkl
|
||
|
*/
|
||
|
#include <stdbool.h>
|
||
|
|
||
|
#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");
|
||
|
}
|