os_cpu_a.S:
#********************************************************************************************************
# uC/OS-III
# The Real-Time Kernel
#
# Copyright 2009-2022 Silicon Laboratories Inc. www.silabs.com
#
# SPDX-License-Identifier: APACHE-2.0
#
# This software is subject to an open source license and is distributed by
# Silicon Laboratories Inc. pursuant to the terms of the Apache License,
# Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
#
#********************************************************************************************************
#********************************************************************************************************
#
# 汇编语言移植
# RISC-V 移植
#
# 文件 : os_cpu_a.S
# 版本 : V3.08.02
#********************************************************************************************************
# 平台 : RISC-V RV32
# 工具链 : GNU C 编译器
#********************************************************************************************************
# 注意事项 : 不支持硬件浮点。
#********************************************************************************************************
#********************************************************************************************************
# 公有函数
#********************************************************************************************************
.extern OSRunning # 外部引用
.extern OSPrioCur # 当前任务优先级
.extern OSPrioHighRdy # 最高优先级就绪任务
.extern OSTCBCurPtr # 当前任务控制块指针
.extern OSTCBHighRdyPtr # 最高优先级就绪任务控制块指针
.extern OSIntExit # 中断退出函数
.extern OSTaskSwHook # 任务切换钩子函数
.global OSStartHighRdy # 本文件中声明的函数
.global OSCtxSw # 上下文切换函数
.global OSIntCtxSw # 中断上下文切换函数
.global Software_IRQHandler # 软件中断处理函数
#********************************************************************************************************
# 定义
#********************************************************************************************************
.equ RISCV_MSTATUS_MIE, 0x08 # MSTATUS 寄存器中的 MIE 位
.equ RISCV_MIE_MSIE, 0x08 # MIE 寄存器中的 MSIE 位(软件中断位)
.equ RISCV_PRCI_BASE_ADDR, 0x44000000 # PRCI 基地址
#********************************************************************************************************
# 代码生成指令
#********************************************************************************************************
.section .text # 定义代码段
#********************************************************************************************************
# 启动多任务
# void OSStartHighRdy(void)
#
# 注意事项: 1) OSStartHighRdy() 必须:
# a) 调用 OSTaskSwHook() 然后,
# b) 将 OSRunning 设置为 TRUE,
# c) 将 OSTCBHighRdyPtr->StkPtr = SP
# d) 恢复 x1-x31;无需恢复 x0,因为它始终为零。
# e) 启用中断(任务将在中断启用的情况下运行)。
# f) 切换到最高优先级任务。
#********************************************************************************************************
OSStartHighRdy:
# 禁用中断
li t0, RISCV_MSTATUS_MIE
csrrc zero, mstatus, t0
# 执行 OS 任务切换钩子
jal OSTaskSwHook
# OSRunning = TRUE;
li t0, 0x01
la t1, OSRunning
sb t0, 0(t1)
# 切换到最高优先级任务
la t0, OSTCBHighRdyPtr
lw t1, 0(t0)
lw sp, 0(t1)
# 获取跳转位置
lw t0, 31 * 4(sp)
csrw mepc, t0
# 恢复 x1 到 x31 寄存器
lw ra, 0 * 4(sp)
lw t0, 4 * 4(sp)
lw t1, 5 * 4(sp)
lw t2, 6 * 4(sp)
lw s0, 7 * 4(sp)
lw s1, 8 * 4(sp)
lw a0, 9 * 4(sp)
lw a1, 10 * 4(sp)
lw a2, 11 * 4(sp)
lw a3, 12 * 4(sp)
lw a4, 13 * 4(sp)
lw a5, 14 * 4(sp)
lw a6, 15 * 4(sp)
lw a7, 16 * 4(sp)
lw s2, 17 * 4(sp)
lw s3, 18 * 4(sp)
lw s4, 19 * 4(sp)
lw s5, 20 * 4(sp)
lw s6, 21 * 4(sp)
lw s7, 22 * 4(sp)
lw s8, 23 * 4(sp)
lw s9, 24 * 4(sp)
lw s10, 25 * 4(sp)
lw s11, 26 * 4(sp)
lw t3, 27 * 4(sp)
lw t4, 28 * 4(sp)
lw t5, 29 * 4(sp)
lw t6, 30 * 4(sp)
# 补偿堆栈指针
addi sp, sp, 32 * 4
# 使用寄存器 t6 跳转到最高优先级任务
csrr t6, mepc
# 启用全局中断
li t0, RISCV_MSTATUS_MIE
csrrs zero, mstatus, t0
# 跳转到最高优先级任务
jalr x0, t6, 0
#********************************************************************************************************
# 执行上下文切换(从任务级别) - OSCtxSw()
# 执行上下文切换(从中断级别) - OSIntCtxSw()
#
# 注意事项: 1) OSCtxSw() 在操作系统需要执行任务上下文切换时被调用。此函数通过写入 MSIP 寄存器触发同步软件中断。
#
# 2) OSIntCtxSw() 在 OSIntExit() 确定需要上下文切换作为中断的结果时被调用。此函数通过写入 MSIP 寄存器触发同步软件中断。
#********************************************************************************************************
OSCtxSw:
OSIntCtxSw:
# MIE_MSIE -- 启用软件中断位
li t0, RISCV_MIE_MSIE
csrrs zero, mie, t0
# 这将触发一个同步软件中断;PRCI->MSIP[0] = 0x01;
li t0, RISCV_PRCI_BASE_ADDR
li t1, 0x1
sw t1, 0x0(t0)
ret
#********************************************************************************************************
# void Software_IRQHandler (void)
#
# 注意事项: 1) 此函数在 'riscv_hal_stubs.c' 中定义为弱链接,以便内核移植可以使用相同的原型覆盖它。
#
# 2) 伪代码如下:
# a) 禁用全局中断。
# b) 清除 hart0 的软件中断。
# c) 将进程的 SP 保存在其 TCB 中,OSTCBCurPtr->StkPtr = SP;
# d) 调用 OSTaskSwHook();
# e) 获取当前最高优先级,OSPrioCur = OSPrioHighRdy;
# f) 获取当前就绪线程的 TCB,OSTCBCurPtr = OSTCBHighRdyPtr;
# g) 从 TCB 中获取新的进程 SP,SP = OSTCBHighRdyPtr->StkPtr;
# h) 检索发生异常的地址
# i) 从新进程堆栈中恢复 x1-x31;x0 始终为零。
# j) 执行异常返回,这将恢复剩余的上下文。
#
# 3) 进入 Software_IRQHandler 时:
# a) 初始寄存器上下文保存由 'entry.S' 完成
# b) 堆栈指针由 'entry.s' 传递到寄存器 a2 中。
# c) OSTCBCurPtr 指向要挂起的任务的 OS_TCB
# OSTCBHighRdyPtr 指向要恢复的任务的 OS_TCB
#********************************************************************************************************
Software_IRQHandler:
# 禁用全局中断并防止上下文切换期间的中断
li t0, RISCV_MSTATUS_MIE
csrrc zero, mstatus, t0
# 清除 hart0 的软件中断,PRCI->MSIP[0] = 0x00;
li t0, RISCV_PRCI_BASE_ADDR
sw zero, 0x0(t0)
# 堆栈指针由 'entry.s' 传递到寄存器 a2 中。
# OSTCBCurPtr->StkPtr = SP;
la t0, OSTCBCurPtr
lw t1, 0(t0)
sw a2, 0(t1)
# 执行 OS 任务切换钩子
jal OSTaskSwHook
# OSPrioCur = OSPrioHighRdy;
la t0, OSPrioHighRdy
lb t1, 0(t0)
la t0, OSPrioCur
sb t1, 0(t0)
# OSTCBCurPtr = OSTCBHighRdyPtr;
la t0, OSTCBHighRdyPtr
lw t1, 0(t0)
la t0, OSTCBCurPtr
sw t1, 0(t0)
# SP = OSTCBHighRdyPtr->StkPtr;
lw sp, 0(t1)
# 检索发生异常的地址
lw t0, 31 * 4(sp)
csrw mepc, t0
# 恢复 x1 到 x31 寄存器
lw ra, 0 * 4(sp)
lw t0, 4 * 4(sp)
lw t1, 5 * 4(sp)
lw t2, 6 * 4(sp)
lw s0, 7 * 4(sp)
lw s1, 8 * 4(sp)
lw a0, 9 * 4(sp)
lw a1, 10 * 4(sp)
lw a2, 11 * 4(sp)
lw a3, 12 * 4(sp)
lw a4, 13 * 4(sp)
lw a5, 14 * 4(sp)
lw a6, 15 * 4(sp)
lw a7, 16 * 4(sp)
lw s2, 17 * 4(sp)
lw s3, 18 * 4(sp)
lw s4, 19 * 4(sp)
lw s5, 20 * 4(sp)
lw s6, 21 * 4(sp)
lw s7, 22 * 4(sp)
lw s8, 23 * 4(sp)
lw s9, 24 * 4(sp)
lw s10, 25 * 4(sp)
lw s11, 26 * 4(sp)
lw t3, 27 * 4(sp)
lw t4, 28 * 4(sp)
lw t5, 29 * 4(sp)
lw t6, 30 * 4(sp)
# 补偿堆栈指针
addi sp, sp, 4 * 32
# 异常返回将恢复剩余的上下文
mret
#********************************************************************************************************
# 模块结束
#********************************************************************************************************
os_cpu_c.c:
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* Copyright 2009-2022 Silicon Laboratories Inc. www.silabs.com
*
* SPDX-License-Identifier: APACHE-2.0
*
* This software is subject to an open source license and is distributed by
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* RISC-V 移植
*
* 文件 : os_cpu_c.c
* 版本 : V3.08.02
*********************************************************************************************************
* 适用平台 : RISC-V RV32
* 工具链 : GNU C 编译器
*********************************************************************************************************
* 注意事项 : 不支持硬件浮点。
*********************************************************************************************************
*/
#define OS_CPU_GLOBALS
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_cpu_c__c = "$Id: $";
#endif
/*
*********************************************************************************************************
* 包含文件
*********************************************************************************************************
*/
#include "../../../../Source/os.h"
/*
*********************************************************************************************************
* 局部变量
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 外部 C 语言链接
*
* 注意事项 : (1) C++ 编译器必须外部声明所有 C 函数原型和变量/对象声明,以确保正确的 C 语言链接。
*********************************************************************************************************
*/
#ifdef __cplusplus
extern "C" { /* See Note #1. */
#endif
/*
*********************************************************************************************************
* 空闲任务挂钩
*
* 描述: 此函数由空闲任务调用。添加此挂钩是为了允许您执行诸如停止 CPU 以节省电力等操作。
*
* 参数: 无。
*
* 注意事项: 无。
*********************************************************************************************************
*/
void OSIdleTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
// 如果应用程序空闲任务挂钩指针不为空,则调用该挂钩函数
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppIdleTaskHookPtr)();
}
#endif
}
/*
*********************************************************************************************************
* 操作系统初始化挂钩
*
* 描述: 此函数在 OSInit() 开始时由 OSInit() 调用。
*
* 参数: 无。
*
* 注意事项: 无。
*********************************************************************************************************
*/
void OSInitHook (void)
{
}
/*
*********************************************************************************************************
* 栈溢出挂钩
*
* 描述: 当任务的堆栈溢出时调用此函数。
*
* 参数: p_tcb 指向违规任务的任务控制块的指针。如果是中断服务例程,则为 NULL。
*
* 注意事项: 无。
*********************************************************************************************************
*/
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
void OSRedzoneHitHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
// 如果应用程序栈溢出挂钩指针不为空,则调用该挂钩函数
if (OS_AppRedzoneHitHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppRedzoneHitHookPtr)(p_tcb);
} else {
// 如果没有定义应用程序挂钩,则触发软件异常
CPU_SW_EXCEPTION(;);
}
#else
// 防止编译器警告
(void)p_tcb;
// 触发软件异常
CPU_SW_EXCEPTION(;);
#endif
}
#endif
/*
*********************************************************************************************************
* 统计任务挂钩
*
* 描述: 此函数每秒由 uC/OS-III 的统计任务调用。这允许您的应用程序向统计任务添加功能。
*
* 参数: 无。
*
* 注意事项: 无。
*********************************************************************************************************
*/
void OSStatTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
// 如果应用程序统计任务挂钩指针不为空,则调用该挂钩函数
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppStatTaskHookPtr)();
}
#endif
}
/*
*********************************************************************************************************
* 任务创建钩子
*
* 描述: 当任务被创建时调用此函数。
*
* 参数: p_tcb 指向正在创建的任务的任务控制块的指针。
*
* 注意: 无。
*********************************************************************************************************
*/
void OSTaskCreateHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskCreateHookPtr)(p_tcb); // 调用应用程序定义的任务创建钩子函数
}
#else
(void)p_tcb; // 防止编译器警告,当应用钩子功能未启用时
#endif
}
/*
*********************************************************************************************************
* 任务删除钩子
*
* 描述: 当任务被删除时调用此函数。
*
* 参数: p_tcb 指向正在删除的任务的任务控制块的指针。
*
* 注意: 无。
*********************************************************************************************************
*/
void OSTaskDelHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskDelHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*
*********************************************************************************************************
* 任务返回钩子
*
* 描述: 如果任务意外返回,则调用此函数。换句话说,任务应该是一个无限循环或在完成时自行删除。
*
* 参数: p_tcb 指向正在返回的任务的任务控制块的指针。
*
* 注意: 无。
*********************************************************************************************************
*/
void OSTaskReturnHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskReturnHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*
*********************************************************************************************************
* 初始化任务的堆栈
*
* 描述: 此函数由 OSTaskCreate() 调用,用于初始化正在创建的任务的堆栈帧。此函数高度依赖于处理器。
*
* 参数: p_task 指向任务入口地址的指针。
*
* p_arg 指向用户提供的数据区域的指针,该数据区域将在任务首次执行时传递给任务。
*
* p_stk_base 指向堆栈基地址的指针。
*
* stk_size 堆栈大小,以 CPU_STK 元素的数量表示。
*
* opt 用于改变 OS_Task_StkInit() 行为的选项。(参见 OS.H 中的 OS_TASK_OPT_xxx)。
*
* 返回值: 总是返回新的堆栈顶部位置,一旦处理器寄存器按正确顺序放置在堆栈上。
*
* 注意: 1) 任务开始执行时中断是启用的。
*
* 2) 不需要保存寄存器 x0,因为它是一个硬连线的零。
*
* 3) RISC-V 调用约定寄存器使用情况:
*
* +-------------+-------------+----------------------------------+
* | 寄存器 | ABI 名称 | 描述 |
* +-------------+-------------+----------------------------------+
* | x31 - x28 | t6 - t3 | 临时寄存器 |
* +-------------+-------------+----------------------------------+
* | x27 - x18 | s11 - s2 | 保存寄存器 |
* +-------------+-------------+----------------------------------+
* | x17 - x12 | a7 - a2 | 函数参数 |
* +-------------+-------------+----------------------------------+
* | x11 - x10 | a1 - a0 | 函数参数/返回值 |
* +-------------+-------------+----------------------------------+
* | x9 | s1 | 保存寄存器 |
* +-------------+-------------+----------------------------------+
* | x8 | s0/fp | 保存寄存器/帧指针 |
* +-------------+-------------+----------------------------------+
* | x7 - x5 | t2 - t0 | 临时寄存器 |
* +-------------+-------------+----------------------------------+
* | x4 | tp | 线程指针 |
* +-------------+-------------+----------------------------------+
* | x3 | gp | 全局指针 |
* +-------------+-------------+----------------------------------+
* | x2 | sp | 堆栈指针 |
* +-------------+-------------+----------------------------------+
* | x1 | ra | 返回地址 |
* +-------------+-------------+----------------------------------+
* | x0 | zero | 硬连线零 |
* +-------------+-------------+----------------------------------+
*
*********************************************************************************************************
*/
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)p_stk_limit; // 防止编译器警告
(void)opt;
p_stk = &p_stk_base[stk_size]; // 加载堆栈指针并将其对齐到 16 字节
p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF0u);
*(--p_stk) = (CPU_STK) p_task; // 入口点
*(--p_stk) = (CPU_STK) 0x31313131uL; // t6
*(--p_stk) = (CPU_STK) 0x30303030uL; // t5
*(--p_stk) = (CPU_STK) 0x29292929uL; // t4
*(--p_stk) = (CPU_STK) 0x28282828uL; // t3
// 保存寄存器
*(--p_stk) = (CPU_STK) 0x27272727uL; // s11
*(--p_stk) = (CPU_STK) 0x26262626uL; // s10
*(--p_stk) = (CPU_STK) 0x25252525uL; // s9
*(--p_stk) = (CPU_STK) 0x24242424uL; // s8
*(--p_stk) = (CPU_STK) 0x23232323uL; // s7
*(--p_stk) = (CPU_STK) 0x22222222uL; // s6
*(--p_stk) = (CPU_STK) 0x21212121uL; // s5
*(--p_stk) = (CPU_STK) 0x20202020uL; // s4
*(--p_stk) = (CPU_STK) 0x19191919uL; // s3
*(--p_stk) = (CPU_STK) 0x18181818uL; // s2
// 函数参数
*(--p_stk) = (CPU_STK) 0x17171717uL; // a7
*(--p_stk) = (CPU_STK) 0x16161616uL; // a6
*(--p_stk) = (CPU_STK) 0x15151515uL; // a5
*(--p_stk) = (CPU_STK) 0x14141414uL; // a4
*(--p_stk) = (CPU_STK) 0x13131313uL; // a3
*(--p_stk) = (CPU_STK) 0x12121212uL; // a2
// 函数参数/返回值
*(--p_stk) = (CPU_STK) 0x11111111uL; // a1
*(--p_stk) = (CPU_STK) p_arg; // a0
*(--p_stk) = (CPU_STK) 0x09090909uL; // s1: 保存寄存器
*(--p_stk) = (CPU_STK) 0x08080808uL; // s0/fp: 保存寄存器/帧指针
// 临时寄存器
*(--p_stk) = (CPU_STK) 0x07070707uL; // t2
*(--p_stk) = (CPU_STK) 0x06060606uL; // t1
*(--p_stk) = (CPU_STK) 0x05050505uL; // t0
*(--p_stk) = (CPU_STK) 0x04040404uL; // tp: 线程指针
*(--p_stk) = (CPU_STK) 0x03030303uL; // gp: 全局指针
*(--p_stk) = (CPU_STK) 0x02020202uL; // sp: 堆栈指针
*(--p_stk) = (CPU_STK) OS_TaskReturn; // ra: 返回地址
return (p_stk);
}
/*
*********************************************************************************************************
* 任务切换钩子
*
* 描述: 当任务切换时调用此函数。这允许你在上下文切换期间执行其他操作。
*
* 参数: 无。
*
* 注意: 1) 在此调用期间中断是禁用的。
* 2) 假设全局指针 'OSTCBHighRdyPtr' 指向将被“切换进入”的任务的 TCB(即最高优先级任务),而 'OSTCBCurPtr'
* 指向被切换出去的任务(即被抢占的任务)。
*********************************************************************************************************
*/
void OSTaskSwHook (void)
{
#if OS_CFG_TASK_PROFILE_EN > 0u
CPU_TS ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_TS int_dis_time;
#endif
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
CPU_BOOLEAN stk_status;
#endif
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) { // 如果应用程序任务切换钩子指针不为空
(*OS_AppTaskSwHookPtr)(); // 调用应用程序任务切换钩子函数
}
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
ts = OS_TS_GET(); // 获取当前时间戳
if (OSTCBCurPtr != OSTCBHighRdyPtr) { // 如果当前任务与即将切换进的任务不同
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart; // 计算当前任务的运行时间
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta; // 累加当前任务的总运行时间
}
OSTCBHighRdyPtr->CyclesStart = ts; // 更新即将切换进的任务的起始时间戳
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
int_dis_time = CPU_IntDisMeasMaxCurReset(); // 记录每个任务的中断禁用时间
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) { // 如果当前任务的最大中断禁用时间小于记录的时间
OSTCBCurPtr->IntDisTimeMax = int_dis_time; // 更新当前任务的最大中断禁用时间
}
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
// 记录每个任务的调度锁时间
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) { // 如果当前任务的最大调度锁时间小于记录的时间
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur; // 更新当前任务的最大调度锁时间
}
OSSchedLockTimeMaxCur = (CPU_TS)0; // 重置每个任务的调度锁时间
#endif
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
// 检查堆栈是否溢出
stk_status = OSTaskStkRedzoneChk((OS_TCB *)0u);
if (stk_status != OS_TRUE) { // 如果堆栈溢出
OSRedzoneHitHook(OSTCBCurPtr); // 调用堆栈溢出处理函数
}
#endif
}
/*
*********************************************************************************************************
* 定时器钩子
*
* 描述: 此函数在每个定时器滴答时调用。
*
* 参数: 无。
*
* 注意: 1) 假设此函数是从定时器中断服务例程 (ISR) 中调用的。
*********************************************************************************************************
*/
void OSTimeTickHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTimeTickHookPtr)();
}
#endif
#if (CPU_CFG_TS_EN > 0u)
CPU_TS_Update();
#endif
}
/*
*********************************************************************************************************
* 系统定时器处理程序
*
* 描述: 处理系统定时器 (SysTick) 中断,该中断用于生成 uC/OS-III 的定时器中断。
*
* 参数: 无。
*
* 注意: 1) 此函数在 'riscv_hal_stubs.c' 中定义为弱链接,以便内核端口可以使用相同的原型覆盖它。
*********************************************************************************************************
*/
void SysTick_Handler (void)
{
CPU_SR_ALLOC(); // 分配存储以保存 CPU 状态寄存器
CPU_CRITICAL_ENTER(); // 进入临界区
OSIntEnter(); // 告诉 uC/OS-III 我们正在开始一个 ISR
CPU_CRITICAL_EXIT(); // 退出临界区
OSTimeTick(); // 调用 uC/OS-III 的 OSTimeTick() 函数
OSIntExit(); // 告诉 uC/OS-III 我们正在离开 ISR
}
/*
*********************************************************************************************************
* 外部 C 语言链接结束
*********************************************************************************************************
*/
#ifdef __cplusplus
} /* End of 'extern'al C lang linkage. */
#endif
os_cpu.h:
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* Copyright 2009-2022 Silicon Laboratories Inc. www.silabs.com
*
* SPDX-License-Identifier: APACHE-2.0
*
* This software is subject to an open source license and is distributed by
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* RISC-V 端口
*
* 文件 : os_cpu.h
* 版本 : V3.08.02
*********************************************************************************************************
* 平台 : RISC-V RV32
* 工具链 : GNU C 编译器
*********************************************************************************************************
* 注意 : 不支持硬件浮点。
*********************************************************************************************************
*/
#ifndef _OS_CPU_H
#define _OS_CPU_H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
/*
*********************************************************************************************************
* 外部 C 语言链接
*
* 注意: (1) C++ 编译器必须外部声明所有 C 函数原型和变量/对象声明,以确保正确的 C 语言链接。
*********************************************************************************************************
*/
#ifdef __cplusplus
extern "C" { /* See Note #1. */
#endif
/*
*********************************************************************************************************
* 宏定义
*
* 注意: OS_TASK_SW() 用于调用任务级别的上下文切换。
*
* (1) 在某些处理器上,这对应于对 OSCtxSw() 的调用,这是一个汇编语言函数,用于执行上下文切换。
*
* (2) 在某些处理器上,你需要使用“软件中断”或 TRAP 指令来模拟中断。一些编译器允许添加内联汇编语言。
*********************************************************************************************************
*/
#define OS_TASK_SW() OSCtxSw()
/*
*********************************************************************************************************
* 时间戳配置
*
* 注意: (1) OS_TS_GET() 通常定义为 CPU_TS_Get32(),以允许 CPU 时间戳计时器具有任何数据类型大小。
*
* (2) 对于提供 32 位或更高精度自由运行计数器的架构(例如周期计数寄存器):
*
* (a) OS_TS_GET() 可以定义为 CPU_TS_TmrRd(),以在获取时间戳时提高性能。如果此函数返回 32 位自由运行计数器的值(从 0x00000000 到 0xFFFFFFFF,然后回滚到 0x00000000),则应使用 CPU_TS_TmrRd()。
*
* (b) CPU_TS_TmrRd() 必须配置为大于或等于 32 位,以避免时间戳 TS 的截断。
*
* (c) 计时器必须是递增计数器。
*********************************************************************************************************
*/
#if OS_CFG_TS_EN == 1u
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
#else
#define OS_TS_GET() (CPU_TS)0u
#endif
#if (CPU_CFG_TS_32_EN > 0u) && \
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
/* see Note #2b. */
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
#endif
/*
*********************************************************************************************************
* 函数原型
*********************************************************************************************************
*/
/* See OS_CPU_A.S */
void OSCtxSw (void);
void OSIntCtxSw (void);
void OSStartHighRdy(void);
/*
*********************************************************************************************************
* 外部 C 语言链接结束
*********************************************************************************************************
*/
#ifdef __cplusplus
} /* End of 'extern'al C lang linkage. */
#endif
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif
标签:os,sp,CPU,lw,源码,STK,stk,OS,cpu
From: https://www.cnblogs.com/lanlincmos/p/18521937