移植到 CH32V10x 既 QingKeV3 系列 MCU 上

This commit is contained in:
2026-05-22 18:13:11 +08:00
parent bdfd09eca8
commit 80e32d4fb8
14 changed files with 1194 additions and 7 deletions
+1
View File
@@ -5,6 +5,7 @@
#define OS_STATIC_FORCE_INLINE static inline __attribute__((always_inline)) #define OS_STATIC_FORCE_INLINE static inline __attribute__((always_inline))
#define OS_ALIGNED(x) __attribute__((aligned(x))) #define OS_ALIGNED(x) __attribute__((aligned(x)))
#define OS_WEAK __attribute__((weak)) #define OS_WEAK __attribute__((weak))
#define OS_USED __attribute__((used))
#define OS_PACKED_STRUCT(x) struct __attribute__((packed)) x #define OS_PACKED_STRUCT(x) struct __attribute__((packed)) x
#define OS_SECTION(n) __attribute__((section(#n))) #define OS_SECTION(n) __attribute__((section(#n)))
#define OS_NORETURN __attribute__((noreturn)) #define OS_NORETURN __attribute__((noreturn))
+5 -3
View File
@@ -213,6 +213,11 @@ void os_sched(void){
} }
} }
void SysTick_Handler(void){
os_systick_tick();
}
void SVC_Handler_C(os_uintptr_t* svc_args){ void SVC_Handler_C(os_uintptr_t* svc_args){
// 读取系统调用号:它存储在原本的 PC 指令前两个字节 // 读取系统调用号:它存储在原本的 PC 指令前两个字节
uint8_t svc_number = ((uint8_t *)svc_args[6])[-2]; uint8_t svc_number = ((uint8_t *)svc_args[6])[-2];
@@ -241,7 +246,4 @@ void SVC_Handler_C(os_uintptr_t* svc_args){
} }
} }
void SysTick_Handler(void){
os_systick_tick();
}
+10
View File
@@ -0,0 +1,10 @@
#include <os_loopdelay.h>
#if defined (__GNUC__) /*!< GNU Compiler */
__attribute__((naked))
void os_loop_delay(unsigned long ulCount){
__asm(" add a0, a0, -1 \n"
" bne x0, a0, os_loop_delay \n"
" ret ");
}
#endif /* __CC_ARM */
+34
View File
@@ -0,0 +1,34 @@
#ifndef INCLUDED_OS_LOOPDELAY_H
#define INCLUDED_OS_LOOPDELAY_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#define OS_LOOP_DELAY_US(n) (n * SystemCoreClock/3000000)
#define OS_LOOP_DELAY_MS(n) (n * SystemCoreClock/3000)
#define OS_LOOP_DELAY_S(n) (n * SystemCoreClock/3)
/*
72Mhz时钟时,当ulCount为1时,函数耗时3个时钟,延时=3*1/72us=1/24us
SystemCoreClock=72000000
us级延时,延时n微秒
LoopDelay(n*(SystemCoreClock/3000000));
ms级延时,延时n毫秒
LoopDelay(n*(SystemCoreClock/3000));
m级延时,延时n秒
LoopDelay(n*(SystemCoreClock/3));
*/
void os_loop_delay(unsigned long ulCount);
#define OS_LoopDelayUS(n) os_loop_delay(OS_LOOP_DELAY_US(n))
#define OS_LoopDelayMS(n) os_loop_delay(OS_LOOP_DELAY_MS(n))
#define OS_LoopDelayS(n) os_loop_delay(OS_LOOP_DELAY_S(n))
#endif /*INCLUDED_OS_LOOPDELAY_H*/
+198
View File
@@ -0,0 +1,198 @@
#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();
}
+173
View File
@@ -0,0 +1,173 @@
.section .text.SW_Handler,"ax",@progbits
.global SW_Handler
.p2align 2 /* 4 bytes align */
.func
SW_Handler:
/* save all from thread context */
addi sp, sp, -32 * 4
sw x5, 5 * 4(sp) /* t0, 使 */
csrr t0, mstatus /* mstatus */
sw t0, 2 * 4(sp) /* x2 */
li t0,0x1800 /* M-Mode */
csrw mstatus, t0
csrr t0, mepc /* mepc x0 */
sw t0, 0 * 4(sp)
sw x1, 1 * 4(sp) /* return address */
sw x4, 4 * 4(sp) /* tp */
sw x6, 6 * 4(sp)
sw x7, 7 * 4(sp)
sw x8, 8 * 4(sp)
sw x9, 9 * 4(sp)
sw x10, 10 * 4(sp)
sw x11, 11 * 4(sp)
sw x12, 12 * 4(sp)
sw x13, 13 * 4(sp)
sw x14, 14 * 4(sp)
sw x15, 15 * 4(sp)
sw x16, 16 * 4(sp)
sw x17, 17 * 4(sp)
sw x18, 18 * 4(sp)
sw x19, 19 * 4(sp)
sw x20, 20 * 4(sp)
sw x21, 21 * 4(sp)
sw x22, 22 * 4(sp)
sw x23, 23 * 4(sp)
sw x24, 24 * 4(sp)
sw x25, 25 * 4(sp)
sw x26, 26 * 4(sp)
sw x27, 27 * 4(sp)
sw x28, 28 * 4(sp)
sw x29, 29 * 4(sp)
sw x30, 30 * 4(sp)
sw x31, 31 * 4(sp)
la s0, g_os_port_switch_from_sp /* */
lw s1, 0(s0)
sw sp, 0(s1)
/* ---------- 收尾工作 ---------- */
jal os_port_on_switch_success
/* ---------- 切换到新任务 ---------- */
la s0, g_os_port_switch_to_sp /* */
lw s1, 0(s0)
lw sp, 0(s1)
lw t0, 0 * 4(sp) /* mepc */
csrw mepc, t0 /* t0 mepc */
lw x1, 1 * 4(sp) /* return address */
lw t0, 2*4(sp) /* mstatus */
csrs mstatus, t0 /* MPIE = 1 */
lw x4, 4 * 4(sp) /* */
lw x5, 5 * 4(sp)
lw x6, 6 * 4(sp)
lw x7, 7 * 4(sp)
lw x8, 8 * 4(sp)
lw x9, 9 * 4(sp)
lw x10, 10 * 4(sp)
lw x11, 11 * 4(sp)
lw x12, 12 * 4(sp)
lw x13, 13 * 4(sp)
lw x14, 14 * 4(sp)
lw x15, 15 * 4(sp)
lw x16, 16 * 4(sp)
lw x17, 17 * 4(sp)
lw x18, 18 * 4(sp)
lw x19, 19 * 4(sp)
lw x20, 20 * 4(sp)
lw x21, 21 * 4(sp)
lw x22, 22 * 4(sp)
lw x23, 23 * 4(sp)
lw x24, 24 * 4(sp)
lw x25, 25 * 4(sp)
lw x26, 26 * 4(sp)
lw x27, 27 * 4(sp)
lw x28, 28 * 4(sp)
lw x29, 29 * 4(sp)
lw x30, 30 * 4(sp)
lw x31, 31 * 4(sp)
addi sp, sp, 32 * 4 /* */
mret
.endfunc
/*
* void os_port_context_restore(os_uintptr_t to);
* a0 --> to
* a1 --> to_thread
*/
.section .text.os_port_context_restore,"ax",@progbits
.globl os_port_context_restore
.func
.p2align 2 /* 4 bytes align */
os_port_context_restore:
/* first save interrupt stack */
la t0, _eusrstack
addi t0, t0, -512
csrw mscratch,t0
/* keep machine mode */
li t0, 0x1800
csrw mstatus, t0
/* ---------- 收尾工作 ---------- */
jal os_port_on_switch_success
/* ---- Load target sp ---- */
lw sp, (a0) /* to sp */
/* resw ra to mepc */
lw a0, 0 * 4(sp)
csrw mepc, a0
lw x1, 1 * 4(sp) /* */
lw x4, 4 * 4(sp)
lw x5, 5 * 4(sp)
lw x6, 6 * 4(sp)
lw x7, 7 * 4(sp)
lw x8, 8 * 4(sp)
lw x9, 9 * 4(sp)
lw x10, 10 * 4(sp)
lw x11, 11 * 4(sp)
lw x12, 12 * 4(sp)
lw x13, 13 * 4(sp)
lw x14, 14 * 4(sp)
lw x15, 15 * 4(sp)
lw x16, 16 * 4(sp)
lw x17, 17 * 4(sp)
lw x18, 18 * 4(sp)
lw x19, 19 * 4(sp)
lw x20, 20 * 4(sp)
lw x21, 21 * 4(sp)
lw x22, 22 * 4(sp)
lw x23, 23 * 4(sp)
lw x24, 24 * 4(sp)
lw x25, 25 * 4(sp)
lw x26, 26 * 4(sp)
lw x27, 27 * 4(sp)
lw x28, 28 * 4(sp)
lw x29, 29 * 4(sp)
lw x30, 30 * 4(sp)
lw x31, 31 * 4(sp)
lw t0, 2*4(sp)
csrs mstatus, t0
addi sp, sp, 32 * 4
mret
.endfunc
.end
+1
View File
@@ -0,0 +1 @@
#include <qkv3.h>
+226
View File
@@ -0,0 +1,226 @@
#ifndef INCLUDED_QKV3_H
#define INCLUDED_QKV3_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
#ifndef INCLUDED_RISCV_H
#include <riscv.h>
#endif /*INCLUDED_RISCV_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#ifdef __cplusplus
#define __I volatile /* defines 'read only' permissions */
#else
#define __I volatile const /* defines 'read only' permissions */
#endif
#define __O volatile /* defines 'write only' permissions */
#define __IO volatile /* defines 'read / write' permissions */
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#define QKV3_PFIC ((QKV3_PFIC_Type *) 0xE000E000 )
#define QKV3_NVIC QKV3_PFIC
#define QKV3_NVIC_KEY1 ((uint32_t)0xFA050000)
#define QKV3_NVIC_KEY2 ((uint32_t)0xBCAF0000)
#define QKV3_NVIC_KEY3 ((uint32_t)0xBEEF0000)
#define QKV3_SysTick ((QKV3_SysTick_Type *) 0xE000F000)
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef enum {QKV3_NoREADY = 0, QKV3_READY = !QKV3_NoREADY} QKV3_ErrorStatus;
typedef enum {QKV3_DISABLE = 0, QKV3_ENABLE = !QKV3_DISABLE} QKV3_FunctionalState;
typedef enum {QKV3_RESET = 0, QKV3_SET = !QKV3_RESET} QKV3_FlagStatus, QKV3_ITStatus;
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
typedef struct{
__I uint32_t ISR[8];
__I uint32_t IPR[8];
__IO uint32_t ITHRESDR;
__IO uint32_t VTFBADDRR;
__IO uint32_t CFGR;
__I uint32_t GISR;
uint8_t RESERVED0[0x10];
__IO uint32_t VTFADDRR[4];
uint8_t RESERVED1[0x90];
__O uint32_t IENR[8];
uint8_t RESERVED2[0x60];
__O uint32_t IRER[8];
uint8_t RESERVED3[0x60];
__O uint32_t IPSR[8];
uint8_t RESERVED4[0x60];
__O uint32_t IPRR[8];
uint8_t RESERVED5[0x60];
__IO uint32_t IACTR[8];
uint8_t RESERVED6[0xE0];
__IO uint8_t IPRIOR[256];
uint8_t RESERVED7[0x810];
__IO uint32_t SCTLR;
}QKV3_PFIC_Type;
/* memory mapped structure for SysTick */
typedef struct
{
__IO uint32_t CTLR;
__IO uint8_t CNTL0;
__IO uint8_t CNTL1;
__IO uint8_t CNTL2;
__IO uint8_t CNTL3;
__IO uint8_t CNTH0;
__IO uint8_t CNTH1;
__IO uint8_t CNTH2;
__IO uint8_t CNTH3;
__IO uint8_t CMPLR0;
__IO uint8_t CMPLR1;
__IO uint8_t CMPLR2;
__IO uint8_t CMPLR3;
__IO uint8_t CMPHR0;
__IO uint8_t CMPHR1;
__IO uint8_t CMPHR2;
__IO uint8_t CMPHR3;
}QKV3_SysTick_Type;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_EnableIRQ(uint32_t IRQn)
{
QKV3_NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_DisableIRQ(uint32_t IRQn)
{
uint32_t t;
t = QKV3_NVIC->ITHRESDR;
QKV3_NVIC->ITHRESDR = 0x10;
QKV3_NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
QKV3_NVIC->ITHRESDR = t;
}
OS_STATIC_FORCE_INLINE
uint32_t QKV3_NVIC_GetStatusIRQ(uint32_t IRQn)
{
return((uint32_t) ((QKV3_NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
OS_STATIC_FORCE_INLINE
uint32_t QKV3_NVIC_GetPendingIRQ(uint32_t IRQn)
{
return((uint32_t) ((QKV3_NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_SetPendingIRQ(uint32_t IRQn)
{
QKV3_NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_ClearPendingIRQ(uint32_t IRQn)
{
QKV3_NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
OS_STATIC_FORCE_INLINE
uint32_t QKV3_NVIC_GetActive(uint32_t IRQn)
{
return((uint32_t)((QKV3_NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_SetPriority(uint32_t IRQn, uint8_t priority)
{
QKV3_NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
}
OS_STATIC_FORCE_INLINE
void QKV3_WFI(void)
{
QKV3_NVIC->SCTLR &= ~(1<<3); // wfi
asm volatile ("wfi");
}
OS_STATIC_FORCE_INLINE
void QKV3_SEV(void)
{
QKV3_NVIC->SCTLR |= (1<<3)|(1<<5);
}
OS_STATIC_FORCE_INLINE
void QKV3_WFE(void)
{
QKV3_NVIC->SCTLR |= (1<<3);
asm volatile ("wfi");
}
OS_STATIC_FORCE_INLINE
void QKV3__WFE(void)
{
QKV3_SEV();
QKV3_WFE();
QKV3_WFE();
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_SetFastIRQ(uint32_t addr, uint32_t IRQn, uint8_t num)
{
if(num > 3) return ;
QKV3_NVIC->VTFBADDRR = addr;
QKV3_NVIC->VTFADDRR[num] = ((uint32_t)IRQn<<24)|(addr&0xfffff);
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_SystemReset(void)
{
QKV3_NVIC->CFGR = QKV3_NVIC_KEY3|(1<<7);
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_HaltPushCfg(QKV3_FunctionalState NewState)
{
if (NewState != QKV3_DISABLE)
{
QKV3_NVIC->CFGR = QKV3_NVIC_KEY1;
}
else
{
QKV3_NVIC->CFGR = QKV3_NVIC_KEY1|(1<<0);
}
}
OS_STATIC_FORCE_INLINE
void QKV3_NVIC_INTNestCfg(QKV3_FunctionalState NewState)
{
if (NewState != QKV3_DISABLE)
{
QKV3_NVIC->CFGR = QKV3_NVIC_KEY1;
}
else
{
QKV3_NVIC->CFGR = QKV3_NVIC_KEY1|(1<<1);
}
}
#endif /*INCLUDED_QKV3_H*/
+278
View File
@@ -0,0 +1,278 @@
#include <riscv.h>
#define __ASM __asm /* asm keyword for GNU Compiler */
#define __INLINE inline /* inline keyword for GNU Compiler */
/*********************************************************************
* @fn RISCV_get_MSTATUS
*
* @brief Return the Machine Status Register
*
* @return mstatus value
*/
uint32_t RISCV_get_MSTATUS(void)
{
uint32_t result;
__ASM volatile("csrr %0," "mstatus": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MSTATUS
*
* @brief Set the Machine Status Register
*
* @param value - set mstatus value
*
* @return none
*/
void RISCV_set_MSTATUS(uint32_t value)
{
__ASM volatile("csrw mstatus, %0" : : "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MISA
*
* @brief Return the Machine ISA Register
*
* @return misa value
*/
uint32_t RISCV_get_MISA(void)
{
uint32_t result;
__ASM volatile("csrr %0,""misa" : "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MISA
*
* @brief Set the Machine ISA Register
*
* @param value - set misa value
*
* @return none
*/
void RISCV_set_MISA(uint32_t value)
{
__ASM volatile("csrw misa, %0" : : "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MTVEC
*
* @brief Return the Machine Trap-Vector Base-Address Register
*
* @return mtvec value
*/
uint32_t RISCV_get_MTVEC(void)
{
uint32_t result;
__ASM volatile("csrr %0," "mtvec": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MTVEC
*
* @brief Set the Machine Trap-Vector Base-Address Register
*
* @param value - set mtvec value
*
* @return none
*/
void RISCV_set_MTVEC(uint32_t value)
{
__ASM volatile("csrw mtvec, %0":: "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MSCRATCH
*
* @brief Return the Machine Seratch Register
*
* @return mscratch value
*/
uint32_t RISCV_get_MSCRATCH(void)
{
uint32_t result;
__ASM volatile("csrr %0," "mscratch" : "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MSCRATCH
*
* @brief Set the Machine Seratch Register
*
* @param value - set mscratch value
*
* @return none
*/
void RISCV_set_MSCRATCH(uint32_t value)
{
__ASM volatile("csrw mscratch, %0" : : "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MEPC
*
* @brief Return the Machine Exception Program Register
*
* @return mepc value
*/
uint32_t RISCV_get_MEPC(void)
{
uint32_t result;
__ASM volatile("csrr %0," "mepc" : "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MEPC
*
* @brief Set the Machine Exception Program Register
*
* @return mepc value
*/
void RISCV_set_MEPC(uint32_t value)
{
__ASM volatile("csrw mepc, %0" : : "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MCAUSE
*
* @brief Return the Machine Cause Register
*
* @return mcause value
*/
uint32_t RISCV_get_MCAUSE(void)
{
uint32_t result;
__ASM volatile("csrr %0," "mcause": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MEPC
*
* @brief Set the Machine Cause Register
*
* @return mcause value
*/
void RISCV_set_MCAUSE(uint32_t value)
{
__ASM volatile("csrw mcause, %0":: "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MTVAL
*
* @brief Return the Machine Trap Value Register
*
* @return mtval value
*/
uint32_t RISCV_get_MTVAL(void)
{
uint32_t result;
__ASM volatile("csrr %0," "mtval" : "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_set_MTVAL
*
* @brief Set the Machine Trap Value Register
*
* @return mtval value
*/
void RISCV_set_MTVAL(uint32_t value)
{
__ASM volatile("csrw mtval, %0":: "r"(value));
}
/*********************************************************************
* @fn RISCV_get_MVENDORID
*
* @brief Return Vendor ID Register
*
* @return mvendorid value
*/
uint32_t RISCV_get_MVENDORID(void)
{
uint32_t result;
__ASM volatile("csrr %0,""mvendorid": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_get_MARCHID
*
* @brief Return Machine Architecture ID Register
*
* @return marchid value
*/
uint32_t RISCV_get_MARCHID(void)
{
uint32_t result;
__ASM volatile("csrr %0,""marchid": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_get_MIMPID
*
* @brief Return Machine Implementation ID Register
*
* @return mimpid value
*/
uint32_t RISCV_get_MIMPID(void)
{
uint32_t result;
__ASM volatile("csrr %0,""mimpid": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_get_MHARTID
*
* @brief Return Hart ID Register
*
* @return mhartid value
*/
uint32_t RISCV_get_MHARTID(void)
{
uint32_t result;
__ASM volatile("csrr %0,""mhartid": "=r"(result));
return (result);
}
/*********************************************************************
* @fn RISCV_get_SP
*
* @brief Return SP Register
*
* @return SP value
*/
uint32_t RISCV_get_SP(void)
{
uint32_t result;
__ASM volatile("mv %0,""sp": "=r"(result):);
return (result);
}
+239
View File
@@ -0,0 +1,239 @@
#ifndef INCLUDED_RISCV_H
#define INCLUDED_RISCV_H
#ifndef INCLUDED_OS_TYPES_H
#include <os_types.h>
#endif /*INCLUDED_OS_TYPES_H*/
#ifndef INCLUDED_OS_COMPILER_H
#include <os_compiler.h>
#endif /*INCLUDED_OS_COMPILER_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void RISCV_enable_irq()
{
__asm volatile ("csrs mstatus, %0" : : "r" (0x88) );
}
OS_STATIC_FORCE_INLINE
void RISCV_disable_irq()
{
__asm volatile ("csrc mstatus, %0" : : "r" (0x88) );
}
OS_STATIC_FORCE_INLINE
void RISCV_NOP()
{
__asm volatile ("nop");
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
/*********************************************************************
* @fn __AMOADD_W
*
* @brief Atomic Add with 32bit value
* Atomically ADD 32bit value with value in memory using amoadd.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be ADDed
*
* @return return memory value + add value
*/
OS_STATIC_FORCE_INLINE
int32_t RISCV_AMOADD_W(volatile int32_t *addr, int32_t value)
{
int32_t result;
__asm volatile ("amoadd.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/*********************************************************************
* @fn __AMOAND_W
*
* @brief Atomic And with 32bit value
* Atomically AND 32bit value with value in memory using amoand.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be ANDed
*
* @return return memory value & and value
*/
OS_STATIC_FORCE_INLINE
int32_t RISCV_AMOAND_W(volatile int32_t *addr, int32_t value)
{
int32_t result;
__asm volatile ("amoand.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/*********************************************************************
* @fn __AMOMAX_W
*
* @brief Atomic signed MAX with 32bit value
* Atomically signed max compare 32bit value with value in memory using amomax.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be compared
*
* @return return the bigger value
*/
OS_STATIC_FORCE_INLINE
int32_t RISCV_AMOMAX_W(volatile int32_t *addr, int32_t value)
{
int32_t result;
__asm volatile ("amomax.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
OS_STATIC_FORCE_INLINE
uint32_t RISCV_AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
{
uint32_t result;
__asm volatile ("amomaxu.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/*********************************************************************
* @fn __AMOMIN_W
*
* @brief Atomic signed MIN with 32bit value
* Atomically signed min compare 32bit value with value in memory using amomin.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be compared
*
* @return return the smaller value
*/
OS_STATIC_FORCE_INLINE
int32_t RISCV_AMOMIN_W(volatile int32_t *addr, int32_t value)
{
int32_t result;
__asm volatile ("amomin.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/*********************************************************************
* @fn __AMOMINU_W
*
* @brief Atomic unsigned MIN with 32bit value
* Atomically unsigned min compare 32bit value with value in memory using amominu.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be compared
*
* @return return the smaller value
*/
OS_STATIC_FORCE_INLINE
uint32_t RISCV_AMOMINU_W(volatile uint32_t *addr, uint32_t value)
{
uint32_t result;
__asm volatile ("amominu.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/*********************************************************************
* @fn __AMOOR_W
*
* @brief Atomic OR with 32bit value
* Atomically OR 32bit value with value in memory using amoor.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be ORed
*
* @return return memory value | and value
*/
OS_STATIC_FORCE_INLINE
int32_t RISCV_AMOOR_W(volatile int32_t *addr, int32_t value)
{
int32_t result;
__asm volatile ("amoor.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/*********************************************************************
* @fn __AMOSWAP_W
*
* @brief Atomically swap new 32bit value into memory using amoswap.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* newval - New value to be stored into the address
*
* @return return the original value in memory
*/
OS_STATIC_FORCE_INLINE
uint32_t RISCV_AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
{
uint32_t result;
__asm volatile ("amoswap.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(newval) : "memory");
return result;
}
/*********************************************************************
* @fn __AMOXOR_W
*
* @brief Atomic XOR with 32bit value
* Atomically XOR 32bit value with value in memory using amoxor.d.
*
* @param addr - Address pointer to data, address need to be 4byte aligned
* value - value to be XORed
*
* @return return memory value ^ and value
*/
OS_STATIC_FORCE_INLINE
int32_t RISCV_AMOXOR_W(volatile int32_t *addr, int32_t value)
{
int32_t result;
__asm volatile ("amoxor.w %0, %2, %1" : \
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
return *addr;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
extern uint32_t RISCV_get_MSTATUS(void);
extern void RISCV_set_MSTATUS(uint32_t value);
extern uint32_t RISCV_get_MISA(void);
extern void RISCV_set_MISA(uint32_t value);
extern uint32_t RISCV_get_MTVEC(void);
extern void RISCV_set_MTVEC(uint32_t value);
extern uint32_t RISCV_get_MSCRATCH(void);
extern void RISCV_set_MSCRATCH(uint32_t value);
extern uint32_t RISCV_get_MEPC(void);
extern void RISCV_set_MEPC(uint32_t value);
extern uint32_t RISCV_get_MCAUSE(void);
extern void RISCV_set_MCAUSE(uint32_t value);
extern uint32_t RISCV_get_MTVAL(void);
extern void RISCV_set_MTVAL(uint32_t value);
extern uint32_t RISCV_get_MVENDORID(void);
extern uint32_t RISCV_get_MARCHID(void);
extern uint32_t RISCV_get_MIMPID(void);
extern uint32_t RISCV_get_MHARTID(void);
extern uint32_t RISCV_get_SP(void);
#endif /*INCLUDED_RISCV_H*/
+12
View File
@@ -5,6 +5,10 @@
#include "os_types.h" #include "os_types.h"
#endif /* INCLUDED_OS_TYPES_H */ #endif /* INCLUDED_OS_TYPES_H */
#ifndef INCLUDED_OS_ALIGN_H
#include <os_align.h>
#endif /*INCLUDED_OS_ALIGN_H*/
#ifndef INCLUDED_OS_COMPILER_H #ifndef INCLUDED_OS_COMPILER_H
#include "os_compiler.h" #include "os_compiler.h"
#endif /* INCLUDED_OS_COMPILER_H */ #endif /* INCLUDED_OS_COMPILER_H */
@@ -13,6 +17,10 @@
#include "os_macros.h" #include "os_macros.h"
#endif /* INCLUDED_OS_MACROS_H */ #endif /* INCLUDED_OS_MACROS_H */
#ifndef INCLUDED_OS_ENDIAN_H
#include <os_endian.h>
#endif /*INCLUDED_OS_ENDIAN_H*/
#ifndef INCLUDED_OS_SCHED_H #ifndef INCLUDED_OS_SCHED_H
#include <os_sched.h> #include <os_sched.h>
#endif /*INCLUDED_OS_SCHED_H*/ #endif /*INCLUDED_OS_SCHED_H*/
@@ -57,6 +65,10 @@
#include <os_fairlock.h> #include <os_fairlock.h>
#endif /*INCLUDED_OS_FAIRLOCK_H*/ #endif /*INCLUDED_OS_FAIRLOCK_H*/
#ifndef INCLUDED_OS_IDLE_H
#include <os_idle.h>
#endif /*INCLUDED_OS_IDLE_H*/
/* ==================================================================================================== */ /* ==================================================================================================== */
+12
View File
@@ -44,4 +44,16 @@
#define OS_CFG_DEVICE_MAX 10 #define OS_CFG_DEVICE_MAX 10
#endif /* OS_CFG_DEVICE_MAX */ #endif /* OS_CFG_DEVICE_MAX */
#ifndef OS_CFG_IDLE_TASK_TICKS
#define OS_CFG_IDLE_TASK_TICKS 5
#endif /*OS_CFG_IDLE_TASK_TICKS*/
#ifndef OS_CFG_IDLE_TASK_STACK_SIZE
#define OS_CFG_IDLE_TASK_STACK_SIZE 1024
#endif /*OS_CFG_IDLE_TASK_STACK_SIZE*/
#ifndef OS_CFG_IDLE_TASK_PRIORITY
#define OS_CFG_IDLE_TASK_PRIORITY OS_PRIORITY_IDLE
#endif /*OS_CFG_IDLE_TASK_PRIORITY*/
#endif /*INCLUDED_OS_CONFIG_H*/ #endif /*INCLUDED_OS_CONFIG_H*/
+3 -2
View File
@@ -12,13 +12,14 @@ volatile os_bool_t g_os_port_context_switch_flag;
void os_port_on_switch_success(void){ void os_port_on_switch_success(void){
os_critical_enter_in_isr(); // os_critical_enter_in_isr();
g_os_sched_current_task_p = g_os_port_switch_to_sp; g_os_sched_current_task_p = g_os_port_switch_to_sp;
g_os_sched_current_task_p->state = kOsTaskState_Running; g_os_sched_current_task_p->state = kOsTaskState_Running;
g_os_port_context_switch_flag = OS_FALSE; g_os_port_context_switch_flag = OS_FALSE;
os_critical_leave_in_isr(); // os_critical_leave_in_isr();
} }
OS_WEAK
void os_port_context_switch(void* from_sp, void* to_sp){ void os_port_context_switch(void* from_sp, void* to_sp){
os_critical_enter_in_isr(); os_critical_enter_in_isr();
if(g_os_port_context_switch_flag==OS_TRUE){ if(g_os_port_context_switch_flag==OS_TRUE){
+2 -2
View File
@@ -33,8 +33,8 @@ os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
/* /*
* 请求上下文切换 * 请求上下文切换
* @param from_sp - 切换的源头任务栈 * @param from_sp - 切换的源头任务栈指针
* @param to_sp - 切换的目标任务栈 * @param to_sp - 切换的目标任务栈指针
*/ */
void os_port_context_switch(void* from_sp, void* to_sp); void os_port_context_switch(void* from_sp, void* to_sp);