13918210822 发表于 2024-5-6 09:06:58

最小“非抢占”系统调度服务的必须功能--理念讨论贴,小白发贴,欢迎各位高手及小白

本帖最后由 13918210822 于 2024-5-12 16:42 编辑

需求上
1. DelayMs的时候,让其他需要的事情能够处理起来
2. 无论多重要,不要丢中断,不要丢信号
3. 知道这个CPU干活有多少,还有多少潜力,哪些任务比较占时间
4. 让用户有一个大状态机,“永远不死”

暂时就想到这些

实现上期望:
增加的代码或者宏,占用空间时间越少越好,少到 128字节都能跑,1~2K flash都能跑(tiny配置),复杂的功能可以配置使用,如果MCU资源多,128K RAM, 128K Flash也许是上限
ASM部分越少越好
能让使用者,自己搞清楚加了什么特性,负担多少,当然这个不着急

想法比较粗燥,各位见谅
--robin 20240506


本周除了设计硬件,主要都在学习各位的大作,以及思考轻量级的多任务究竟需要怎么划分功能,而且作为多任务运行库的支持API最少要哪些功能,以下仍然是粗略的思考:



从理念上,不再把MCU-RTOS当作传统意义上的操作系统,因为MCU本质上是单用户多数据源的应用。
传统操作系统2大部分功能 1:运行资源提供, 2: 多任务切换(主动与被动)与同步(加锁与免锁),在一个单用户应用中其实意义有所不同。
在一个增强型51MCU多任务系统中,没有线性内存,也没有资源影射,寄存器都是公用的,除了R0~R8有4个bank也是裸露在所有任务面前
   由此,在一个MCU-RTOS上,任何虚拟化都是没有必要的。自然所谓的内核态也没有意义。
          其实能提供的就是一个多任务的运行库提供异步读写与任务同步对象的支持。
   统计功能作为一个子任务都是附加的,可裁减的非必要功能。
         而必需的,至少有以下一些(逐步完善,并提供必要程度分级,0级表示最必需的)

1. 一个阻塞读取(休眠): reaedQ(qid, timeout)  0级
  qid = 0, 表示只是单纯释放控制权, timeout期待的时间片数量,如果时间片为100us, 10表示1ms,
               若设置为0,表示任务希望释放当前时间片。delay(timeout) 等价于 readQ(0,timeout)
  qid > 0, 表示读取特定信号队列,比如DMA Uart Recv Fifo, ADC Value Fifo, ... 之所以规约为Q(Fifo),
               因为这个结构如果是单生产单消费,是一个免锁结构,不必增加关闭中断的步骤
2. 一个非延迟异步写,不需要运行库,但是最好一个Q(Fifo)绑定
3. 一个带延迟同步写,需要运行库,delay(timeout)即readQ(0,timeout), 这种极限利用的操作,要求快速的任务切换,时间片应该是微秒级别。
4. ISR, 中断服务(DMA-UART/UART, ADC...,作为一个多任务运行库,不应该限制任何中断的使用,
             除了一个定时器中断和其他任务可以重用,但是至少运行库要分享一个定时器中断
运行库关键支持功能:
1. 一个任务信息(优先级,是否可以允许打断...)更新,集成在运行库API的下端被调用
2. LCALL/ACALL/中断/发生后的栈处理
3. 某个定时中断内,更新多任务状态机
附8051指令码(STC8H) 第一字节OPCODE 256坑位图,要熟悉汇编,整理一下.
   不同颜色是不同速度,绿色1周期,黄色2周期,棕色(乘法除法)4周期
下周争取抽空整理一个轻量多任务的框架--robin 20240512








神农鼎 发表于 2024-5-13 13:01:37



任务调度方法,【无错,至简】!“多任务分时调度” - uCOS/FreeRTOS,GUI-uGFX/U8g2, 文件系统, 国产RTOS, 实时操作系统 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

13918210822 发表于 2024-5-6 13:43:46

论坛上Cosy, UCosII, RTOSTiny等等实现,都比我要的更多

我发这个帖子,主要是想从应用的角度,找到一个功能“子集”

功能将将够用,开销够小,如此而已

tzz1983 发表于 2024-5-6 13:49:42

13918210822 发表于 2024-5-6 13:43
论坛上Cosy, UCosII, RTOSTiny等等实现,都比我要的更多

我发这个帖子,主要是想从应用的角度,找到一个功 ...

你自己造一个吧,到时也分享出来给我们学习

13918210822 发表于 2024-5-6 14:56:36

本帖最后由 13918210822 于 2024-5-6 15:50 编辑

tzz1983 发表于 2024-5-6 13:49
你自己造一个吧,到时也分享出来给我们学习
是有向你们学习,缩减一个功能子集的想法

但是,理论知识储备不够,想得到大家的指点,哪些才是最基础的功能

你可以提点一二么?

我先把我的想法一点点说一下:(编译环境还是要支持KEIL的),至少目前国产编译器IDE没有说比KEIL要好到哪里(我目前不知道)。
1. 如果要在51类跑,没有必要区分内核态/用户态, 因为,MCU只有中断模式(4级)和普通运行模式2种状态
   最弱的CPU也有中断模式,否则也没有必要做出来(总不能不收外部信号,不能只靠轮询IO的)。
2. MCU支持有限的调用栈,比如定义到支持8级或者16级,这样系统的栈空间不用保留很多,有的OTP MCU连栈都是硬件的,STC比起来还算比较大容量的
3. 很多时候MCU上其实都是单用户多任务,没有独立进程,只有TASK/ISR共享一个MCU, 每个TASK/ISR都有各自的任务类型,互相之间其实是有明确“岗位”划分的
    这种时候,ISR之间优先级抢占是硬件直接支持的(中断处理器MCU再弱也是要有的,STC还是做得比较强的)
    因此,我想如果ISR划分好“岗位”和“优先级”,把“信号和信息帧“预处理后放好,有特别着急的事件处理通过触发软中断伺候着,运行在普通模式下的TASK也就不用抢占了
    不抢占,也就不用预留任务切换的服务区“堆”和“切换保留的上下文栈”,是不是想比较这些主流rtos配置,能少一些开销
4. 如果使用LCD模块,其实内部还有一些RAM, 相关的FIFO甚至可以压到LCD模块内部RAM中去, 其实也就100来个BYTE, 如果是Linux编程不至于这么小气,
    但是MCU环境有的只有1~2K, 节约个1/10也许有些价值。
5. MCU在实际使用中,总有1~2种任务响应速度是有要求的,特别是IO模拟时序的接口,这些接口往往要delay凑时序(比如LCD1602). 这种delay 1ms~nms其实不应该浪费在nop上

所以,我想至少要有一个非抢占(调用sleep就触发调度,任何阻塞式Fifo读取read或getMsg也触发调度)的任务调度服务是必须的



fanxsp 发表于 2024-5-6 15:31:46

13918210822 发表于 2024-5-6 14:56
是有向你们学习,缩减一个功能子集的想法

但是,理论知识储备不够,想得到大家的指点,哪些才是最基础的 ...

功能都是可裁剪的,你可以只用你需要的。

13918210822 发表于 2024-5-6 15:51:21

fanxsp 发表于 2024-5-6 15:31
功能都是可裁剪的,你可以只用你需要的。

你可以提点一二么?以下应用方式,如果使用你的作品,应该如何配置?
谢谢!

我先把我的想法一点点说一下:(编译环境还是要支持KEIL的),至少目前国产编译器IDE没有说比KEIL要好到哪里(我目前不知道)。
1. 如果要在51类跑,没有必要区分内核态/用户态, 因为,MCU只有中断模式(4级)和普通运行模式2种状态
   最弱的CPU也有中断模式,否则也没有必要做出来(总不能不收外部信号,不能只靠轮询IO的)。
2. MCU支持有限的调用栈,比如定义到支持8级或者16级,这样系统的栈空间不用保留很多,有的OTP MCU连栈都是硬件的,STC比起来还算比较大容量的
3. 很多时候MCU上其实都是单用户多任务,没有独立进程,只有TASK/ISR共享一个MCU, 每个TASK/ISR都有各自的任务类型,互相之间其实是有明确“岗位”划分的
    这种时候,ISR之间优先级抢占是硬件直接支持的(中断处理器MCU再弱也是要有的,STC还是做得比较强的)
    因此,我想如果ISR划分好“岗位”和“优先级”,把“信号和信息帧“预处理后放好,有特别着急的事件处理通过触发软中断伺候着,运行在普通模式下的TASK也就不用抢占了
    不抢占,也就不用预留任务切换的服务区“堆”和“切换保留的上下文栈”,是不是想比较这些主流rtos配置,能少一些开销
4. 如果使用LCD模块,其实内部还有一些RAM, 相关的FIFO甚至可以压到LCD模块内部RAM中去, 其实也就100来个BYTE, 如果是Linux编程不至于这么小气,
    但是MCU环境有的只有1~2K, 节约个1/10也许有些价值。
5. MCU在实际使用中,总有1~2种任务响应速度是有要求的,特别是IO模拟时序的接口,这些接口往往要delay凑时序(比如LCD1602). 这种delay 1ms~nms其实不应该浪费在nop上

所以,我想至少要有一个非抢占(调用sleep就触发调度,任何阻塞式Fifo读取read或getMsg也触发调度)的任务调度服务是必须的

fanxsp 发表于 2024-5-6 16:20:30

13918210822 发表于 2024-5-6 15:51
你可以提点一二么?以下应用方式,如果使用你的作品,应该如何配置?
谢谢!



调度模式设为 协作式保留延时服务   其它功能全部关闭

13918210822 发表于 2024-5-6 16:55:04

fanxsp 发表于 2024-5-6 16:20
调度模式设为 协作式保留延时服务   其它功能全部关闭

请教一下:
1. 这样Tiny需要资源有多少?
2. 延时服务,是否可以触发Task调度,比如Task0 Delay中,Task1被调用起来
如果Task0以外的不能被调用,这个延时服务就和while_nop差别不大

fanxsp 发表于 2024-5-6 19:10:18

本帖最后由 fanxsp 于 2024-5-6 19:14 编辑

13918210822 发表于 2024-5-6 16:55
请教一下:
1. 这样Tiny需要资源有多少?
2. 延时服务,是否可以触发Task调度,比如Task0 Delay中,Task1 ...
1. 协作式调度,只调用OSDelay(),代码占用 850字节 左右。
2. OSDelay()会进行任务调度,当前任务进入阻塞,运行其它任务。

13918210822 发表于 2024-5-6 20:38:53

fanxsp 发表于 2024-5-6 19:10
1. 协作式调度,只调用OSDelay(),代码占用 850字节 左右。
2. OSDelay()会进行任务调度,当前任务进入阻 ...

那我想你的作品应该基本满足我的需求,具体如何配置,我要学习一下
我考虑在 STC8H1K08上跑一个机箱前面板的控制程序
负责 ADC按键, 状态LED*2, LCD1602显示和自动滚动,
接受上位机通过UART控制
页: [1] 2 3 4 5 6
查看完整版本: 最小“非抢占”系统调度服务的必须功能--理念讨论贴,小白发贴,欢迎各位高手及小白