GoDm@'s Blog

stupidRTos开发日记

版权信息

warning

本文章为博主原创文章。遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。


开发进度

DAY1 26-03-29

正式开始 suipidRTOS 项目。根据前面学习的FreeRTOS的内部机制进行开发。

完成了任务创建与TCB、任务栈的初始化、SVC中断的实现。

DAY2 26-03-30

完成任务主动让出CPU、PendSV中断的汇编逻辑。

Bug1:只会触发一次上下文切换

问题出在 stm32f4xx_it.c 中的中断函数嵌套调用
stm32f4xx_it.c 中,我是这么写的:

void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */
  srtos_PendSV_Handler(); // 你在这里调用了汇编函数!
  /* USER CODE END PendSV_IRQn 0 */
}

PendSV_Handler 是一个标准的 C 函数。当内核进入这个函数时,编译器为了遵守 C 语言调用约定,会生成压栈指令(Prologue),并用 bl(分支并链接)指令去调用 srtos_PendSV_Handler()bl 指令覆盖掉了 LR 寄存器!此时 r14 不再是 0xFFFFFFFD,而是变成了 PendSV_Handler 函数内部的下一条指令地址。导致PendSV中断不能正常返回到应该被切换到的任务函数,而是返回到 PendSV_Handler(void),进一步返回到原先的函数。只能切换一次是因为首次运行时手动设置了LR寄存器的值。

Fix:上下文切换的汇编函数必须是中断向量表的直接入口,绝对不能被其他 C 函数包装或调用。

DAY3 26-04-02

完成Systick和中断屏蔽宏函数。

Q1:行为寄存器的写入规则

不同于数据寄存器,行为寄存器的写入规则不应该用 |= (或等于)来赋值,而是直接用等于号赋值。例如ARM Cortex-M 内核的 ICSR(Interrupt Control and State Register,中断控制和状态寄存器) 就是一个行为寄存器。

写入规则:“写 0 无效”。硬件会直接无视 0,原来是什么状态,就是什么状态。

Q2:终于理解了为什么要为OS单独设置一个时基而不是和MCU共用一个时基

OS和MCU时钟(HAL库依赖的时钟)解耦的妙处——确保这两个系统不受对方的影响。两个系统完全控制自己的时钟。

如果在多任务运行期间,需要临时挂起调度器(vTaskSuspendAll())去执行一段极其关键的裸机代码,或者发生严重 Fault 需要在不依赖 OS 的情况下用 HAL 库保存错误日志到 Flash,SysTick 此时的状态是不可控的。

时钟解耦,能保证无论 OS 处于未启动、运行中、还是崩溃状态,MCU(HAL库)永远有一颗正常跳动的心脏。

DAY4 26-04-04

清明前夕苦逼营业中…

初步实现了Delay函数的逻辑还有空闲任务。一遍调通没啥大问题。


共计约840字。于2026/04/03首次发布,最后更新于2026/04/04。

本文章为博主原创文章。遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

  1. 开发进度
    1. DAY1 26-03-29
    2. DAY2 26-03-30
      1. Bug1:只会触发一次上下文切换
    3. DAY3 26-04-02
      1. Q1:行为寄存器的写入规则
      2. Q2:终于理解了为什么要为OS单独设置一个时基而不是和MCU共用一个时基
    4. DAY4 26-04-04