Files
RTOS/CPU/QingKeV3/os_port.c
T

199 lines
6.6 KiB
C
Raw Normal View History

#include "os_port.h"
#include "os_stack.h"
#include "os_macros.h"
#include "os_align.h"
#include "os_compiler.h"
#include "os_systick.h"
#include "os_sched.h"
#include "qkv3.h"
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#define SysTick_IRQn 12
#define Software_IRQn 14
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
static uint32_t _SysTick_Config(os_tick_t ticks)
{
QKV3_PFIC->CFGR=0xFA050003; /* 关闭硬件压栈和嵌套 */
/*
位段值含义:
Bit [31:16] :0xFA05 - 解锁密钥 (Key)。为了防止误触发,修改中断全局配置通常需要写入固定的“钥匙”值。
Bit[1] :1(来自0x3) - 硬件压栈使能 (HPE)。开启后,硬件会自动保存寄存器状态,大幅提升中断响应速度。
Bit[0] :1(来自0x3) - 嵌套中断使能 (NEST)。允许高优先级中断打断低优先级中断。
*/
QKV3_NVIC_SetPriority(SysTick_IRQn,0xf0);
QKV3_NVIC_SetPriority(Software_IRQn,0xf0);
QKV3_SysTick->CTLR=0;
QKV3_SysTick->CNTL0=0;QKV3_SysTick->CNTL1=0;QKV3_SysTick->CNTL2=0;QKV3_SysTick->CNTL3=0;
QKV3_SysTick->CNTH0=0;QKV3_SysTick->CNTH1=0;QKV3_SysTick->CNTH2=0;QKV3_SysTick->CNTH3=0;
QKV3_SysTick->CMPLR0=(uint8_t)(ticks-1);
QKV3_SysTick->CMPLR1=(uint8_t)((ticks-1)>>8);
QKV3_SysTick->CMPLR2=(uint8_t)((ticks-1)>>16);
QKV3_SysTick->CMPLR3=(uint8_t)((ticks-1)>>24);
QKV3_SysTick->CMPHR0=0;QKV3_SysTick->CMPHR1=0;QKV3_SysTick->CMPHR2=0;QKV3_SysTick->CMPHR3=0;
QKV3_SysTick->CTLR=0x1;
QKV3_NVIC_EnableIRQ(SysTick_IRQn);
QKV3_NVIC_EnableIRQ(Software_IRQn);
return 0;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct {
os_uintptr_t mepc; /* zero, 用于 epc 保存 */
os_uintptr_t ra; /* 返回地址 */
os_uintptr_t mstatus; /* 栈指针, 用于mstatus */
os_uintptr_t gp; /* 全局指针 */
os_uintptr_t tp; /* 线程指针 */
os_uintptr_t t0; /* 临时寄存器0 */
os_uintptr_t t1; /* 临时寄存器1 */
os_uintptr_t t2; /* 临时寄存器2 */
os_uintptr_t s0; /* s0/fp */
os_uintptr_t s1; /* 保存寄存器1 */
os_uintptr_t a0; /* 函数参数/返回值 */
os_uintptr_t a1; /* 函数参数 */
os_uintptr_t a2; /* 函数参数 */
os_uintptr_t a3; /* 函数参数 */
os_uintptr_t a4; /* 函数参数 */
os_uintptr_t a5; /* 函数参数 */
os_uintptr_t a6; /* 函数参数 */
os_uintptr_t a7; /* 函数参数 */
os_uintptr_t s2; /* 保存寄存器 */
os_uintptr_t s3; /* 保存寄存器 */
os_uintptr_t s4; /* 保存寄存器 */
os_uintptr_t s5; /* 保存寄存器 */
os_uintptr_t s6; /* 保存寄存器 */
os_uintptr_t s7; /* 保存寄存器 */
os_uintptr_t s8; /* 保存寄存器 */
os_uintptr_t s9; /* 保存寄存器 */
os_uintptr_t s10; /* 保存寄存器 */
os_uintptr_t s11; /* 保存寄存器 */
os_uintptr_t t3; /* 临时寄存器 */
os_uintptr_t t4; /* 临时寄存器 */
os_uintptr_t t5; /* 临时寄存器 */
os_uintptr_t t6; /* 临时寄存器 */
}os_stack_frame_t;
#define STACK_FRAME_SIZE sizeof(os_stack_frame_t)
os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
, void* stack_base, os_size_t stack_size, void(*exit_entry)(void)){
os_uintptr_t stack_max = (os_uintptr_t)((uint8_t *) stack_base + stack_size);
os_uintptr_t real_max = OS_ALIGN_DOWN(stack_max, OS_ALIGN_SIZE); /* 实际栈顶的位置,对齐后的位置 */
stack_size -= (stack_max - real_max); /* 实际栈大小 */
os_stack_frame_t* p_frame = (os_stack_frame_t*)(real_max - STACK_FRAME_SIZE);
for(os_size_t i=0; i<STACK_FRAME_SIZE/sizeof(os_uintptr_t); i++){
((os_uintptr_t*)(p_frame))[i] = 0x5ac0ffee;
}
p_frame->mepc = (os_uintptr_t)entry;
p_frame->a0 = (os_uintptr_t)param;
p_frame->ra = (os_uintptr_t)exit_entry;
os_stack_t stack;
stack.min = (os_uintptr_t)stack_base;
stack.max = (os_uintptr_t)real_max;
stack.type = kOsStackType_MaxToMin;
stack.sp = p_frame;
return stack;
}
void os_port_disable_irq(void){
RISCV_disable_irq();
}
void os_port_enable_irq(void){
RISCV_enable_irq();
}
os_uint_t os_port_save_disable_irq(void){
return os_port_save_disable_irq_in_isr();
}
void os_port_restore_irq(os_uint_t level){
os_port_restore_irq_in_isr(level);
}
os_uint_t os_port_save_disable_irq_in_isr(void){
os_uint_t level = RISCV_get_MSTATUS();
RISCV_set_MSTATUS(0x1800);
return level;
}
void os_port_restore_irq_in_isr(os_uint_t level){
RISCV_set_MSTATUS(level);
}
void os_sched(void){
os_sched_in_isr();
}
extern volatile os_uint_t SystemCoreClock;
OS_WEAK
void os_port_init(void){
}
OS_WEAK
void os_port_startup(void){
_SysTick_Config(SystemCoreClock/8/OS_CFG_TICKS_PER_SECOND);
}
/*
* 发出上下文切换的请求
*/
void os_port_send_context_switch_request(void){
QKV3_NVIC_SetPendingIRQ(Software_IRQn);
}
/*
* 清除上下文切换的请求
*/
void os_port_clear_context_switch_request(void){
QKV3_NVIC_ClearPendingIRQ(Software_IRQn);
}
extern void os_port_context_restore(os_uintptr_t to);
OS_USED
void os_port_context_switch(void* from_sp, void* to_sp){
os_critical_enter_in_isr();
if(g_os_port_context_switch_flag==OS_TRUE){
os_critical_leave_in_isr();
return;
}
g_os_port_context_switch_flag = OS_TRUE;
if(from_sp==0){
g_os_port_switch_to_sp = to_sp;
os_critical_leave_in_isr();
os_port_context_restore((os_uintptr_t)to_sp);
}else{
g_os_port_switch_from_sp = from_sp;
g_os_port_switch_to_sp = to_sp;
os_critical_leave_in_isr();
os_port_send_context_switch_request();
}
}
void SysTick_Handler(void) __attribute__((interrupt()));
void SysTick_Handler(void){
QKV3_SysTick->CTLR=0;
QKV3_SysTick->CNTL0=0;QKV3_SysTick->CNTL1=0;QKV3_SysTick->CNTL2=0;QKV3_SysTick->CNTL3=0;
QKV3_SysTick->CNTH0=0;QKV3_SysTick->CNTH1=0;QKV3_SysTick->CNTH2=0;QKV3_SysTick->CNTH3=0;
QKV3_SysTick->CTLR=0x1;
// 调用系统心跳处理
os_systick_tick();
}