首页 > 编程语言 >UcOs-III RISC-V接口移植源码阅读: os_cpu_a.S、os_cpu_c.c、os_cpu.h

UcOs-III RISC-V接口移植源码阅读: os_cpu_a.S、os_cpu_c.c、os_cpu.h

时间:2024-11-02 14:47:22浏览次数:2  
标签:os sp CPU lw 源码 STK stk OS cpu

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

相关文章