2026-05-22 18:13:11 +08:00
|
|
|
#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"
|
2026-05-23 00:59:24 +08:00
|
|
|
#include "os_isr.h"
|
2026-05-27 23:30:31 +08:00
|
|
|
#include "cpu.h"
|
2026-05-22 18:13:11 +08:00
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
2026-05-23 00:59:24 +08:00
|
|
|
OS_STATIC_FORCE_INLINE
|
|
|
|
|
uint32_t _SysTick_Config(os_tick_t ticks)
|
2026-05-22 18:13:11 +08:00
|
|
|
{
|
|
|
|
|
|
2026-05-27 23:30:31 +08:00
|
|
|
|
|
|
|
|
NVIC->CFGR = (CPU_KEY1<<16) | (1<<1/*NESTCTRL*/) | (1<<0/*HWSTKCTRL*/); /* 关闭硬件压栈和嵌套 */
|
|
|
|
|
|
|
|
|
|
NVIC_SetPriority(SysTick_IRQn,0xf0);
|
|
|
|
|
NVIC_SetPriority(Software_IRQn,0xf0);
|
|
|
|
|
|
|
|
|
|
SysTick->CTLR=0;
|
|
|
|
|
SysTick->CNTL0=0;SysTick->CNTL1=0;SysTick->CNTL2=0;SysTick->CNTL3=0;
|
|
|
|
|
SysTick->CNTH0=0;SysTick->CNTH1=0;SysTick->CNTH2=0;SysTick->CNTH3=0;
|
|
|
|
|
SysTick->CMPLR0=(uint8_t)(ticks-1);
|
|
|
|
|
SysTick->CMPLR1=(uint8_t)((ticks-1)>>8);
|
|
|
|
|
SysTick->CMPLR2=(uint8_t)((ticks-1)>>16);
|
|
|
|
|
SysTick->CMPLR3=(uint8_t)((ticks-1)>>24);
|
|
|
|
|
SysTick->CMPHR0=0;SysTick->CMPHR1=0;SysTick->CMPHR2=0;SysTick->CMPHR3=0;
|
|
|
|
|
SysTick->CTLR=0x1;
|
|
|
|
|
|
|
|
|
|
NVIC_EnableIRQ(SysTick_IRQn);
|
|
|
|
|
NVIC_EnableIRQ(Software_IRQn);
|
2026-05-22 18:13:11 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2026-05-27 23:30:31 +08:00
|
|
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
|
|
|
|
os_uintptr_t f0;
|
|
|
|
|
os_uintptr_t f1;
|
|
|
|
|
os_uintptr_t f2;
|
|
|
|
|
os_uintptr_t f3;
|
|
|
|
|
os_uintptr_t f4;
|
|
|
|
|
os_uintptr_t f5;
|
|
|
|
|
os_uintptr_t f6;
|
|
|
|
|
os_uintptr_t f7;
|
|
|
|
|
os_uintptr_t f8;
|
|
|
|
|
os_uintptr_t f9;
|
|
|
|
|
os_uintptr_t f10;
|
|
|
|
|
os_uintptr_t f11;
|
|
|
|
|
os_uintptr_t f12;
|
|
|
|
|
os_uintptr_t f13;
|
|
|
|
|
os_uintptr_t f14;
|
|
|
|
|
os_uintptr_t f15;
|
|
|
|
|
os_uintptr_t f16;
|
|
|
|
|
os_uintptr_t f17;
|
|
|
|
|
os_uintptr_t f18;
|
|
|
|
|
os_uintptr_t f19;
|
|
|
|
|
os_uintptr_t f20;
|
|
|
|
|
os_uintptr_t f21;
|
|
|
|
|
os_uintptr_t f22;
|
|
|
|
|
os_uintptr_t f23;
|
|
|
|
|
os_uintptr_t f24;
|
|
|
|
|
os_uintptr_t f25;
|
|
|
|
|
os_uintptr_t f26;
|
|
|
|
|
os_uintptr_t f27;
|
|
|
|
|
os_uintptr_t f28;
|
|
|
|
|
os_uintptr_t f29;
|
|
|
|
|
os_uintptr_t f30;
|
|
|
|
|
os_uintptr_t f31;
|
|
|
|
|
#endif
|
|
|
|
|
os_uintptr_t mstatus; /* zero, 用于 mstatus 保存 */
|
2026-05-22 18:13:11 +08:00
|
|
|
os_uintptr_t ra; /* 返回地址 */
|
2026-05-27 23:30:31 +08:00
|
|
|
os_uintptr_t mepc; /* 栈指针, mepc */
|
2026-05-22 20:53:29 +08:00
|
|
|
os_uintptr_t x3; /* 全局指针 */
|
|
|
|
|
os_uintptr_t x4; /* 线程指针 */
|
|
|
|
|
os_uintptr_t x5; /* 临时寄存器0 */
|
|
|
|
|
os_uintptr_t x6; /* 临时寄存器1 */
|
|
|
|
|
os_uintptr_t x7; /* 临时寄存器2 */
|
|
|
|
|
os_uintptr_t x8; /* s0/fp */
|
|
|
|
|
os_uintptr_t x9; /* 保存寄存器1 */
|
2026-05-22 18:13:11 +08:00
|
|
|
os_uintptr_t a0; /* 函数参数/返回值 */
|
2026-05-22 20:53:29 +08:00
|
|
|
os_uintptr_t x11; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x12; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x13; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x14; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x15; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x16; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x17; /* 函数参数 */
|
|
|
|
|
os_uintptr_t x18; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x19; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x20; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x21; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x22; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x23; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x24; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x25; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x26; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x27; /* 保存寄存器 */
|
|
|
|
|
os_uintptr_t x28; /* 临时寄存器 */
|
|
|
|
|
os_uintptr_t x29; /* 临时寄存器 */
|
|
|
|
|
os_uintptr_t x30; /* 临时寄存器 */
|
|
|
|
|
os_uintptr_t x31; /* 临时寄存器 */
|
2026-05-22 18:13:11 +08:00
|
|
|
}os_stack_frame_t;
|
|
|
|
|
|
|
|
|
|
#define STACK_FRAME_SIZE sizeof(os_stack_frame_t)
|
2026-05-22 20:53:29 +08:00
|
|
|
#define MSTATUS_MPIE (1<<7)
|
2026-05-22 18:13:11 +08:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-22 20:53:29 +08:00
|
|
|
p_frame->mstatus = MSTATUS_MPIE;
|
2026-05-22 18:13:11 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-27 23:30:31 +08:00
|
|
|
//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);
|
|
|
|
|
//}
|
2026-05-22 18:13:11 +08:00
|
|
|
|
2026-05-27 23:30:31 +08:00
|
|
|
//os_uint_t os_port_save_disable_irq_in_isr(void){
|
|
|
|
|
// return RISCV_get_set_MSTATUS(0x1800);
|
|
|
|
|
//}
|
2026-05-22 18:13:11 +08:00
|
|
|
|
2026-05-27 23:30:31 +08:00
|
|
|
//void os_port_restore_irq_in_isr(os_uint_t level){
|
|
|
|
|
// RISCV_set_MSTATUS(level);
|
|
|
|
|
//}
|
2026-05-22 18:13:11 +08:00
|
|
|
|
|
|
|
|
void os_sched(void){
|
|
|
|
|
os_sched_in_isr();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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){
|
2026-05-27 23:30:31 +08:00
|
|
|
NVIC_SetPendingIRQ(Software_IRQn);
|
2026-05-22 18:13:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 清除上下文切换的请求
|
|
|
|
|
*/
|
|
|
|
|
void os_port_clear_context_switch_request(void){
|
2026-05-27 23:30:31 +08:00
|
|
|
NVIC_ClearPendingIRQ(Software_IRQn);
|
2026-05-22 18:13:11 +08:00
|
|
|
}
|
|
|
|
|
|
2026-05-27 23:30:31 +08:00
|
|
|
extern void os_port_context_switch_to(os_uintptr_t to);
|
2026-05-22 18:13:11 +08:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2026-05-27 23:30:31 +08:00
|
|
|
g_os_port_switch_from_sp = from_sp;
|
|
|
|
|
g_os_port_switch_to_sp = to_sp;
|
2026-05-22 18:13:11 +08:00
|
|
|
g_os_port_context_switch_flag = OS_TRUE;
|
2026-05-27 23:30:31 +08:00
|
|
|
os_critical_leave_in_isr();
|
2026-05-22 18:13:11 +08:00
|
|
|
if(from_sp==0){
|
2026-05-27 23:30:31 +08:00
|
|
|
os_port_context_switch_to((os_uintptr_t)to_sp);
|
2026-05-22 18:13:11 +08:00
|
|
|
}else{
|
|
|
|
|
os_port_send_context_switch_request();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SysTick_Handler(void) __attribute__((interrupt()));
|
|
|
|
|
void SysTick_Handler(void){
|
2026-05-27 23:30:31 +08:00
|
|
|
SysTick->CTLR=0;
|
|
|
|
|
SysTick->CNTL0=0;SysTick->CNTL1=0;SysTick->CNTL2=0;SysTick->CNTL3=0;
|
|
|
|
|
SysTick->CNTH0=0;SysTick->CNTH1=0;SysTick->CNTH2=0;SysTick->CNTH3=0;
|
|
|
|
|
SysTick->CTLR=0x1;
|
2026-05-22 18:13:11 +08:00
|
|
|
|
|
|
|
|
// 调用系统心跳处理
|
|
|
|
|
os_systick_tick();
|
|
|
|
|
}
|
|
|
|
|
|