RL78G13移植BasicOS

📅 2026/7/23 23:34:57
RL78G13移植BasicOS
BasicOS狗哥出品基于“共享栈”的协作式调度内核BasicOS一切都是为了用“RTOS的任务”的形式写MCU任务【可以但是必要不大】任务切换时需要处理任务栈有别于ProtoThread的Superloop唯一栈本质有栈协程 and 无栈协程无栈协程对比有栈协程 (BasicOS)每个任务配备独立私有栈切换时完整保存所有通用寄存器、栈指针 SP、程序断点 PC 与函数局部变量可在任意嵌套函数内暂停 / 恢复运行时动态记录断点位置进出点不固定。无栈假协程 (ProtoThreadwhile(1)循环)ProtoThread基于编译期静态状态机实现语法糖仅用 1 个状态变量line 行号记录执行分支while(1)循环的内部函数可通过轮询状态机的形式实现假并发软件定时器的并发不保存寄存器、PC、局部变量使用全局变量保存变量持续化的数据所有暂停 / 恢复分支地址编译时固定资源开销最小。轮流执行round-robin执行方式前后顺序就是优先级内部可使用状态机实现进入点和退出点的有限控制无栈真协程 (ctx)无独立任务栈共用全局主栈使用语法糖的形式保证了局部变量的持续化不是通过轮询的形式来仅在全局内存保存 PC 断点与少量核心寄存器无法在嵌套子函数中 yield运行时动态记录断点地址进出点不固定RAM 占用极低。大佬总结大佬的糖协作式调度大家文明排队轮到你就一直跑只有当你自己说 “我好了可以换人”调度器才能换下一个没人能强制把你赶下来。CPU 使用权只能由任务主动释放内核不会强行剥夺高优先级任务无法打断正在运行的任务只有当前运行任务主动让出 CPU调度器才有机会切换其他就绪任务。任务一旦拿到 CPU会持续运行直到主动调用 yield() / 任务切换接口 【suspend】主动阻塞延时、等待信号量、等待消息 【blocked】任务执行完毕退出。调度时机完全受控于任务代码中断不会引发任务上下文切换中断可以标记任务就绪但中断返回后一定回到被打断的原任务不会立刻切任务真正切换必须等到任务主动让出。不需要复杂的临界区保护相比抢占式不存在 “任务在任意指令中间被打断”只要不在共享资源访问中间调用 yield天然不会出现任务并发争抢破坏数据。各线程是线性执行不存在各线程间的资源共享中断都在任务栈中不像freertos一进入中断就切换到中断栈因为freertos在中断中可能会调度任务共享栈的情况中断都在任务栈中处理没有独立中断栈风险共享资源要“一次性”处理没有一次性处理完“共享资源”不要苛求系统实时性1.【考验程序设计】如果一个任务长时间运算、迟迟不 yield外部事件对应的任务迟迟得不到调度。例如按键检测任务需要 10ms 响应但是后台运算任务连续运行几百毫秒不释放 CPU按键响应严重滞后。长时间循环内部必须周期性插入 yield防止独占 CPU2.中断里“唤醒”高优先级任务【任务已经到了就绪时候】但是当前正在运行的任务不肯 yield新就绪任务只能“礼貌”排队等待。实时需求强的场景很难满足。3.TaskA低优先级正在运行TaskB高优先级已经就绪只要 TaskA 不主动 yield高优先级 B 一直无法调度。即使 B 事件紧急也必须等 A 自愿放手。只有yeild没有delay:导致任务一有空就运行cpu没得歇yield() 的定位主动临时让出 CPU不进入阻塞任务保持「就绪态」delay / 延时sleep让出 CPU 进入「阻塞等待态」到期才重新就绪饥饿问题任务1 优先级高任务2 3 优先级低一些且一致当任务2好了之后任务1立马就绪有没有可能到值任务3是始终无法执行高优先级任务空闲时必须进入阻塞态block而不是挂起态(suspend)固定时间片-任务环 Round-Robin运行固定时间后强制切换上下文共享栈栈大小动态调整将有限的栈空间给正在运行的线程使用其他栈保持最小尺寸缺点增加栈空间调整的处理优点省资源用时间换空间export把一个任务的“配置部分”和“实时数据”部分 分开任务数据内容存储位置配置部分任务入口、任务优先级、任务名称、参数地址const rom段实时数据任务栈指针、任务栈地址、栈大小、超时时间ram将配置部分部分使用magic_word包裹实现初始化动态判断任务个数并定义“内核任务”作为整个任务的链表头用于比遍历对比其他export 使用段的形式定义该段数据统一处理方法并使用段开始标记和段结束标记集中判断移植初始化栈保存寄存器PS PSW AX BC DE HL CSBRK中断上下文保存入栈push寄存器“栈空间的调整”出栈pop寄存器栈空间的调整注意往前拷贝和往后拷贝有区别