理解RTOS多任务系统,仿写
目录一、理解 FreeRTOS 任务调度的底层原理二、仿写 FreeRTOS 任务调度器1. 任务创建函数设计2. 调度器触发机制3. 中断处理流程4. 任务启动机制5. 任务切换过程6. 上下文恢复7. 实现效果展示一、理解 FreeRTOS 任务调度的底层原理二、仿写 FreeRTOS 任务调度器1. 任务创建函数设计首先需要实现一个任务创建函数其参数包括函数指针任务入口、函数参数、栈空间地址、栈大小。// __attribute__((aligned(4))) 实现4字节对齐 static char stack_a[1024] __attribute__((aligned(4))); static char stack_b[1024] __attribute__((aligned(4))); static char stack_c[1024] __attribute__((aligned(4))); // 任务函数1循环输出字符 void task(void *parameter) { char c (char)parameter; while(1) { putchar(c); } } // 任务函数2计算累加和并显示 void task2(void *parameter) { int i; int sum 0; for(i 0; i 100; i) { sum i; } while(1) { put_s_hex(sum , sum); } } // 主函数创建并启动任务 int mymain() { create_task(task, a, stack_a, 1024); create_task(task, b, stack_b, 1024); create_task(task2, 0, stack_c, 1024); start_task(); return 0; }这个创建函数的核心作用是伪造任务上下文包括硬件自动保存的寄存器R0-R3, R12, LR, PC, PSR和需要软件保存的寄存器R4-R11。void create_task(task_function f, void *parameter, char *stack, int stack_len) { int *top (int *)(stack stack_len); /* 伪造任务上下文模拟中断现场 */ top - 16; // 为16个寄存器预留空间 /* R4-R11软件保存的寄存器 */ top[0] 0; // r4 top[1] 0; // r5 top[2] 0; // r6 top[3] 0; // r7 top[4] 0; // r8 top[5] 0; // r9 top[6] 0; // r10 top[7] 0; // r11 /* R0-R3硬件自动保存的寄存器 */ top[8] (int)parameter; // r0任务参数 top[9] 0; // r1 top[10] 0; // r2 top[11] 0; // r3 top[12] 0; // r12 /* LR链接寄存器特殊处理 */ top[13] 0; // lr不关心因为任务退出不会返回到main /* 返回地址任务入口函数 */ top[14] (int)f; // PC任务入口地址 /* PSR程序状态寄存器 */ top[15] (1 24); // 使用Thumb指令集 /* 记录栈顶位置到任务栈数组 */ task_stacks[task_count] (int)top; }2. 调度器触发机制调度器由系统时钟中断触发。每次SysTick中断发生时都会检查是否需要执行任务切换。当发生SysTick_Handler中断时硬件会自动保存以下寄存器到当前任务的栈中我们需要在中断处理函数中软件保存剩余的寄存器R4-R11以及LR寄存器的特殊值。同时需要记录当前栈的位置并传递给SysTick_Handler函数。3. 中断处理流程进入SysTick_Handler函数后首先进行状态判断如果任务尚未创建完成直接返回如果只有一个任务直接启动即可无需切换如果有多个任务执行任务切换逻辑4. 任务启动机制任务启动的关键是从栈中恢复寄存器的值。在上下文切换时会传递两个重要参数R0栈地址新任务的栈顶R1LR的特殊值用于异常返回5. 任务切换过程当需要切换任务时需要执行以下操作保存当前任务的上下文到其栈中恢复新任务的上下文从其栈中更新当前任务指针切换栈指针SP到新任务的栈在SysTick_Handler函数中主要工作是更新新旧任务的SP地址完成任务切换。6. 上下文恢复切换到新任务后需要找到新任务的栈并恢复所有寄存器的值然后跳转到任务入口点继续执行。这个过程通常发生在中断服务程序如 SysTick_Handler的末尾通过执行特定的汇编指令序列来完成。上下文恢复的核心步骤以 ARM Cortex-M 为例获取新任务的栈指针调度器决定切换到哪个任务后将该任务的栈顶地址即保存的上下文起始地址加载到某个寄存器例如 R0。恢复软件保存的寄存器R4-R11执行指令LDMIA SP!, {r4 - r11}。这条指令从当前栈指针SP指向的内存地址开始依次将值弹出到寄存器 R4, R5, ..., R11 中同时栈指针 SP 会递增因为后缀!表示写回。这一步恢复的是在中断入口时由软件手动压栈的寄存器。恢复硬件自动保存的寄存器R0-R3, R12, LR, PC, PSR执行指令LDMIA SP!, {r0}。注意这里的{r0}是一个简写实际在异常返回流程中硬件会从栈中自动恢复一整套寄存器。在典型的 PendSV 或中断退出序列中会使用类似LDMIA SP!, {r0, r1, r2, r3, r12, lr, pc, psr}的指令或由硬件自动完成。文章示例中简化为LDMIA SP!, {r0}可能是一个示意代表恢复关键参数寄存器。更完整的恢复会触发异常返回机制将 PC 恢复为任务入口点PSR 恢复为任务状态。执行中断返回通过一条特殊的返回指令如BX LR或直接触发异常返回跳转到新任务的代码位置继续执行。两条指令的执行时机LDMIA SP!, {r4 - r11}在中断服务程序中在决定切换任务并加载了新任务的栈指针之后、执行中断返回之前运行。它负责恢复被调用者保存的寄存器。LDMIA SP!, {r0}或完整的恢复指令紧随其后执行在恢复 R4-R11 之后、中断返回指令之前。它负责恢复剩余的上下文并最终将 PC 指向新任务要执行的指令地址。这两条指令共同完成了从新任务栈中“弹出”整个处理器现场的过程是任务切换中“恢复”环节的具体实现。7. 实现效果展示最终实现的仿FreeRTOS调度器能够正确创建多个任务并在SysTick中断的驱动下进行任务切换实现多任务并发执行的效果。

相关新闻

中豪亿联:智能硬件通信模组的效率优化与实战技巧

中豪亿联:智能硬件通信模组的效率优化与实战技巧

1. 中豪亿联:智能硬件创业者的效率倍增器 第一次接触中豪亿联的产品是在三年前的一个创客马拉松活动上。当时我们团队正在为智能家居项目寻找可靠的通信模组,现场工程师随手扔给我一个火柴盒大小的黑色模块:"试试这个,比你们…

2026/7/21 5:50:47阅读更多 →
大模型上下文窗口爆了怎么办?——资深架构师的10条应对策略

大模型上下文窗口爆了怎么办?——资深架构师的10条应对策略

1. 面试官想要的:不是“扩容”,而是“工程智慧” 在大模型面试中,当被问到“上下文窗口爆了怎么办”,面试官期待的绝不是一个简单的“用更大的窗口”,而是你对上下文压缩、记忆管理、检索增强与工程折衷的系统性思考。回答需要体现“架构师视角”:在成本、延迟、效果之间…

2026/7/21 5:50:47阅读更多 →
AI时代网站GEO优化:提升大模型引用率的关键策略

AI时代网站GEO优化:提升大模型引用率的关键策略

1. 网站GEO优化的时代背景与技术逻辑 2026年的数字营销领域正在经历一场深刻变革。随着AI搜索逐渐成为用户获取信息的主流方式,企业官网作为品牌"数字门面"的角色正在被重新定义。传统SEO优化主要解决的是"如何让网站在搜索引擎结果页排名靠前"…

2026/7/21 5:50:47阅读更多 →
终极Node.js命令行解析工具command-line-args:10分钟快速入门指南

终极Node.js命令行解析工具command-line-args:10分钟快速入门指南

终极Node.js命令行解析工具command-line-args:10分钟快速入门指南 【免费下载链接】command-line-args A mature, feature-complete library to parse command-line options. 项目地址: https://gitcode.com/gh_mirrors/co/command-line-args 你是否厌倦了手…

2026/7/21 15:53:38阅读更多 →
BilibiliDown完全指南:开源B站视频下载器的5大高效技巧

BilibiliDown完全指南:开源B站视频下载器的5大高效技巧

BilibiliDown完全指南:开源B站视频下载器的5大高效技巧 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/…

2026/7/21 15:53:38阅读更多 →
内网渗透测试报告生成:Pentestly多格式输出与漏洞管理方案

内网渗透测试报告生成:Pentestly多格式输出与漏洞管理方案

内网渗透测试报告生成:Pentestly多格式输出与漏洞管理方案 【免费下载链接】pentestly Python and Powershell internal penetration testing framework 项目地址: https://gitcode.com/gh_mirrors/pe/pentestly 在网络安全领域,高效的内网渗透测…

2026/7/21 15:53:38阅读更多 →
flatcc开发者指南:贡献代码、调试技巧与社区协作流程

flatcc开发者指南:贡献代码、调试技巧与社区协作流程

flatcc开发者指南:贡献代码、调试技巧与社区协作流程 【免费下载链接】flatcc FlatBuffers Compiler and Library in C for C 项目地址: https://gitcode.com/gh_mirrors/fl/flatcc FlatCC FlatBuffers 编译器是一个为C语言设计的高性能序列化库,…

2026/7/21 15:53:38阅读更多 →
OpenCV-Python实战(18)——深度学习简介与入门示例

OpenCV-Python实战(18)——深度学习简介与入门示例

OpenCV-Python实战(18)——深度学习简介与入门示例 0. 前言 1. 计算机视觉中的深度学习简介 1.1 深度学习的特点 1.2 深度学习大爆发 2. 用于图像分类的深度学习简介 3. 用于目标检测的深度学习简介 4. 深度学习框架 keras 介绍与使用 4.1 keras 库简介与安装 4.2 使用 keras…

2026/7/21 15:53:38阅读更多 →
redis持久化RDB与AOF

redis持久化RDB与AOF

文章目录 RDB简介持久化触发条件RDB的优缺点AOF简介AOF的三种持久化规则AOF的重写机制AOF文件修复AOF的优缺点 RDB简介 RDB是Redis默认用来进行持久化的一种方式,根据配置文件中的save m n配置自动触发bgsave将当前内存中的数据集以快照的方式写入到磁盘中并生成一…

2026/7/21 15:51:37阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 0:51:49阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 0:51:49阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 0:51:49阅读更多 →
Windows+macOS 通用 OpenClaw 部署流程,内置依赖一键启动智能桌面助手

Windows+macOS 通用 OpenClaw 部署流程,内置依赖一键启动智能桌面助手

📌教程适配:OpenClaw v2.7.9 | 兼容 Windows10/11、macOS 双系统 📖前言 当下各类本地 AI 工具层出不穷,多数产品仅能完成文字问答交互,很难直接操控电脑执行实际操作。OpenClaw,业内常称小龙虾 AI&#…

2026/7/21 0:01:46阅读更多 →
Codex 接入后 Bug 反增?复盘从个人演示到团队协作的“流程陷阱”

Codex 接入后 Bug 反增?复盘从个人演示到团队协作的“流程陷阱”

聊《一次Codex项目复盘,问题最后出在流程而不是模型》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要先把这篇文章的目标说清楚:看完之后,你应该能判断这件事值不值得做&…

2026/7/21 0:01:46阅读更多 →
手把手搓一个五子棋游戏,零代码也能当“游戏开发者”

手把手搓一个五子棋游戏,零代码也能当“游戏开发者”

大家好,还是我。前几期带大家做了心情日记本和可视化大屏,后台有朋友留言:“能不能教点好玩的?我想做游戏,但一行代码都不会。”行,这期就安排。今天的目标:从零做一个五子棋游戏。 带AI对战、三…

2026/7/21 0:03:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/20 22:51:39阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/20 18:51:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/20 18:51:18阅读更多 →