找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5512|回复: 14
打印 上一主题 下一主题
收起左侧

小小调度器问星整理版[可设置选择8/16/32位] 极小资源MCU操作系统

  [复制链接]
跳转到指定楼层
楼主
ID:97470 发表于 2020-7-3 10:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在原作者smset基础上增加1、可以在宏定义里选择8位 16位还是32位2、定义任务用TASK开头
  1. //  任务0 任务定义以TASK开头
  2. TASK task0(){
  3. _SS
  4.   while(1){
  5.    WaitX(50);
  6.    LED0=!LED0;   
  7.   }
  8. _EE
  9. }
复制代码

3、增加实时性更高的等待某条件定义。
4、更多详细信息请参考附件内容。


最近修改记录:

2020-07-03
  1、增加 普通函数无阻塞延时开关宏定义,方便在不使用普通函数无阻塞延时功能时减少RAM占用和更新任务的时间:
      NORMALDELAY  默认为0关闭,修改为1则打开
  
  2020-04-17
   1、同步smset的小小调度器1.11(16位定时器版),新增的等待某个条件或超时溢出
       WaitUtilT(A,TimeOut)
   2、在smset的WaitUtilT(A,TimeOut)基础上,增加等待某个条件为某个值或超时溢出
       WAITUNTILT(A,VAL,TimeOut)
  
  2019-05-30
  1、增加等待某个条件为某个值或超时溢出
      A条件变量;VAL条件值;TaskVAL超时值,不能为0,和TaskVAL的位数调度器定义的位数一样;ONLY超时判断唯一序号
      WAITUNTILO(A,VAL,TaskVAL,ONLY)
      每增加一个超时判断会增加一个调度器位数对应内存占用
  2、添加 void runTasks(void); 声明,确保部分编译器不会报错
  
  2019-05-29
   1、整合群主semet的普通函数无阻塞延时
   2、添加变量位数类型定义,方便根据编译器环境定义修改
   注意:无阻塞延时 只能被主任务,以及主任务调用的函数,及主任务调用的函数调用的函数使用


全部资料51hei下载地址:
小小调度器1.1.6问星整理版.zip (2.95 KB, 下载次数: 43)

  1. #ifndef __xxddq_H
  2. #define __xxddq_H
  3. /*
  4. * @Project      : 小小调度器问星整理版
  5. * @Descripttion : 可设置选择8/16/32版本,在原来的基础上进一步增强
  6. * @version      : 1.1.6 maintask版
  7. * @Author       : smset
  8. * @Date         : 2015-06-02 09:02:31
  9. * @LastEditors  : 问星
  10. * @LastEditTime : 2020-07-03 09:54:57
  11. * @History      :
  12. * 2020-07-03
  13. * 1、增加 普通函数无阻塞延时开关宏定义,方便在不使用普通函数无阻塞延时功能时减少RAM占用和更新任务的时间:
  14. *     NORMALDELAY  默认为0关闭,修改为1则打开
  15. *
  16. * 2020-04-17
  17. *  1、同步smset的小小调度器1.11(16位定时器版),新增的等待某个条件或超时溢出
  18. *      WaitUtilT(A,TimeOut)
  19. *  2、在smset的WaitUtilT(A,TimeOut)基础上,增加等待某个条件为某个值或超时溢出
  20. *      WAITUNTILT(A,VAL,TimeOut)
  21. *
  22. * 2019-05-30
  23. * 1、增加等待某个条件为某个值或超时溢出
  24. *     A条件变量;VAL条件值;TaskVAL超时值,不能为0,和TaskVAL的位数调度器定义的位数一样;ONLY超时判断唯一序号
  25. *     WAITUNTILO(A,VAL,TaskVAL,ONLY)
  26. *     每增加一个超时判断会增加一个调度器位数对应内存占用
  27. * 2、添加 void runTasks(void); 声明,确保部分编译器不会报错
  28. *
  29. * 2019-05-29
  30. *  1、整合群主semet的普通函数无阻塞延时
  31. *  2、添加变量位数类型定义,方便根据编译器环境定义修改
  32. *  注意:无阻塞延时 只能被主任务,以及主任务调用的函数,及主任务调用的函数调用的函数使用
  33. */

  34. /****小小调度器开始********************************************/
  35. //可根据编译器环境修改定义变量位数类型,如果出现重复定义错误提示,可以注释掉变量类型定义
  36. #define U8 unsigned char        //8位变量类型定义
  37. #define U16 unsigned int        //16位变量类型定义
  38. #define U32 unsigned long        //32位变量类型定义

  39. #define MAXTASKS 2          //定义调度器主任务数:1-255
  40. #define BITS 8             //定义调度器位数可选值:8/16/32
  41. #define NORMALDELAY 0       //普通函数无阻塞延时开关:0=关;1=开
  42. #define SEM U16                            //信号量定义宏

  43. #if (BITS==8)
  44. #define TASK U8
  45. #define TICKET_MAX 0xFF
  46. #endif

  47. #if (BITS==16)
  48. #define TASK U16
  49. #define TICKET_MAX 0xFFFF
  50. #endif

  51. #if (BITS==32)
  52. #define TASK U32
  53. #define TICKET_MAX 0xFFFFFFFF
  54. #endif

  55. volatile TASK timers[MAXTASKS];
  56. #if (NORMALDELAY==1)
  57. volatile TASK delaycount;
  58. #endif
  59. void runTasks(void);

  60. //任务头
  61. #define _SS static U8 _lc=0; switch(_lc){default:

  62. //任务尾
  63. #define _EE ;}; _lc=0; return TICKET_MAX;

  64. //等待X个时钟周期
  65. #define WaitX(tickets)  do { _lc=(__LINE__%255)+1; return (tickets) ;case (__LINE__%255)+1:;} while(0);

  66. //等待某个条件
  67. #define WaitUntil(A)    do { while(!(A)) WaitX(1);} while(0);

  68. //等待某个条件为某个值        A条件变量;VAL条件值
  69. #define WAITUNTIL(A,VAL)  do { WaitX(1);} while((A)!=VAL);

  70. //等待某个条件或超时溢出
  71. #define WaitUtilT(A,TimeOut)  do {static TASK _count=(TimeOut); do { WaitX(1); _count--; } while((!(A))&&(_count>0));} while(0);

  72. //等待某个条件为某个值或超时溢出
  73. #define WAITUNTILT(A,VAL,TimeOut)  do {static TASK _count=(TimeOut); do { WaitX(1); _count--; } while(((A)!=VAL)&&(_count>0));} while(0);

  74. //等待某个条件为某个值或超时溢出        A条件变量;VAL条件值;TaskVAL超时值,不能为0,和TaskVAL的位数调度器定义的位数一样;ONLY超时判断唯一序号
  75. #define WAITUNTILO(A,VAL,TaskVAL,ONLY)  do {static TASK A##ONLY;A##ONLY=TaskVAL;do {WaitX(1);A##ONLY--;} while((A)!=VAL && A##ONLY!=0);}while(0);

  76. //只能用在RunTask调用的任务里 实时性更高 等待某个条件
  77. #define WaitUntilR(A)    do { while(!(A)) WaitX(0);} while(0);

  78. //只能用在RunTask调用的任务里 实时性更高 等待某个条件为某个值        A条件变量;VAL条件值
  79. #define WAITUNTILR(A,VAL)  do { WaitX(0);} while((A)!=VAL);

  80. //只能用在RunTask调用的任务里 实时性更高 等待某个条件或超时溢出
  81. #define WaitUtilTR(A,TimeOut)  do {static TASK _count=(TimeOut); do { WaitX(0); _count--; } while((!(A))&&(_count>0));} while(0);

  82. //只能用在RunTask调用的任务里 实时性更高 等待某个条件为某个值或超时溢出
  83. #define WAITUNTILTR(A,VAL,TimeOut)  do {static TASK _count=(TimeOut); do { WaitX(0); _count--; } while(((A)!=VAL)&&(_count>0));} while(0);

  84. //运行任务
  85. #define RunTask(TaskName,TaskID)  do { if (timers[TaskID]==0) { TASK d=TaskName(); while(timers[TaskID]!=d) timers[TaskID]=d;} } while(0);

  86. //运行任务,前面的任务优先保证执行
  87. #define RunTaskA(TaskName,TaskID) do { if (timers[TaskID]==0) {TASK d=TaskName(); while(timers[TaskID]!=d) timers[TaskID]=d;continue;} } while(0);

  88. //调用子任务
  89. #define CallSub(SubTaskName) do {TASK currdt; _lc=(__LINE__%255)+1; return 0; case (__LINE__%255)+1:  currdt=SubTaskName(); if(currdt!=TICKET_MAX) return currdt;} while(0);

  90. //调用子任务,传入一个参数,传入的参数需在释放CPU前使用
  91. #define CallSub1(SubTaskName,p1) do {TASK currdt; _lc=(__LINE__%255)+1; return 0; case (__LINE__%255)+1:  currdt=SubTaskName(p1); if(currdt!=TICKET_MAX) return currdt;} while(0);

  92. //调用子任务,传入二个参数,传入的参数需在释放CPU前使用
  93. #define CallSub2(SubTaskName,p1,p2) do {TASK currdt; _lc=(__LINE__%255)+1; return 0; case (__LINE__%255)+1:  currdt=SubTaskName(p1,p2); if(currdt!=TICKET_MAX) return currdt;} while(0);

  94. //初始化任务调度
  95. #define InitTasks() do {U8 i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; } while(0);

  96. #if (NORMALDELAY==0)
  97. //更新任务
  98. #define UpdateTimers() do{U8 i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=TICKET_MAX)) timers[i-1]--;}} while(0);
  99. #endif

  100. #if (NORMALDELAY==1)
  101. //更新任务
  102. #define UpdateTimers() do{U8 i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=TICKET_MAX)) timers[i-1]--;} if(delaycount>0) delaycount--;} while(0);

  103. //普通函数无阻塞延时 只能被主任务,以及主任务调用的函数,及主任务调用的函数调用的函数 使用
  104. #define DELAYX(tickets) do{delaycount=tickets;while(delaycount>0) {runTasks();}}while(0);
  105. #endif

  106. //初始化信号量
  107. #define InitSem(sem) do{sem=0;}while(0);

  108. //等待信号量
  109. #define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);

  110. //发送信号量
  111. #define SendSem(sem)  do {sem=0;} while(0);

  112. //等待信号量或定时器溢出
  113. #define WaitSemX(sem, tickets) do{sem=tickets+1;WaitX(0);if(sem>1){sem--;return 1;}}while (0);

  114. /*****小小调度器结束*******************************************************/

  115. /*****调用示例*************************************************
  116. #include "xxddq.h"

  117. sbit LED1 = P2^1;
  118. sbit LED2 = P2^2;
  119. sbit LED0 = P2^5;

  120. //  任务0 任务定义以TASK开头
  121. TASK task0(){
  122. _SS
  123.   while(1){
  124.    WaitX(50);
  125.    LED0=!LED0;   
  126.   }
  127. _EE
  128. }
  129. //  任务1 任务定义以TASK开头
  130. TASK task1(){
  131. _SS
  132.   while(1){
  133.   // WaitX(100);
  134.   // LED1=!LED1;
  135.   test1();  
  136.   }
  137. _EE
  138. }
  139. //  任务2 任务定义以TASK开头
  140. TASK task2(){
  141. _SS
  142.     while(1){
  143.         WaitX(100);
  144.         LED2=!LED2;   
  145.     }
  146. _EE
  147. }

  148. //  TIME0初始化
  149. void InitT0()
  150. {
  151.     TMOD = 0x21;
  152.     IE |= 0x82;  // 12t
  153.     TL0=0Xff;
  154.     TH0=0XDB;
  155.     TR0 = 1;
  156. }
  157. //  TIM0中断服务
  158. void INTT0(void) interrupt 1 using 1
  159. {
  160.     TL0=0Xff;           //10ms 重装
  161.     TH0=0XDB;           //b7;   
  162.     UpdateTimers();     //更新任务
  163.     RunTask(task0,0);   //任务0具有精确按时获得执行的权限,要求:task0每次执行消耗时间<0.5个 ticket
  164. }

  165. //无阻塞延时 只能被主任务,以及主任务调用的函数,及主任务调用的函数调用的函数 使用
  166. //TASK i 定义参数确保参数位数和调度器内定义的位数一样
  167. void delayx(TASK i){
  168.       DELAYX(i);        //普通函数无阻塞延时
  169. }

  170. //普通函数
  171. void test1(){
  172.      delayx(50);
  173.      LED0=1;

  174.      delayx(50);
  175.      LED0=0;

  176.      delayx(50);
  177.      LED0=1;

  178.      delayx(50);
  179.      LED0=0;
  180. }

  181. //主任务 主任务函数名必须为 runTasks
  182. void runTasks()
  183. {
  184. //        RunTask(task0,0);
  185.     RunTaskA(task1,1);//任务1具有比任务2高的运行权限                  
  186.     RunTaskA(task2,2);//任务2具有低的运行权限
  187. }

  188. //  主循环
  189. void main()
  190. {
  191.     InitT0();
  192.     InitTasks(); //初始化任务,实际上是给timers清零
  193.    
  194.         //主循环或主循环内的函数或主循环函数调用的子函数里,必须有一个无阻塞延时函数执行
  195.     while(1){
  196.     //  delayx(1);        //无阻塞延时1个任务时钟
  197.         test1();        //调用了无阻塞延时函数的普通函数
  198.     //        runTasks();        //没有普通函数调用无阻塞延时函数时,可以只调用主任务
  199.     }
  200. }
  201. **************************************************************/
  202. #endif
复制代码


评分

参与人数 2黑币 +62 收起 理由
jzbas + 12 赞一个!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏10 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:97470 发表于 2020-10-25 14:15 | 只看该作者
2020-10-15
  1、整合SETJMP版.可通过定义SETJMP切换
     #define SETJMP 0            //版本选择:0=SWINCH版 1=SETJMP版

  2020-10-14
  1、增加LCBIT宏定义来设置_lc变量类型.
          #define LCBIT 0                        //选择_lc的变量类型: 0=8位;1=16位.
          PICC高版本编译器宏不支持__LINE__%255运算,LCBIT定义需设置为1。代价就是每个任务多占一个字节的RAM.
     其它编译器如果不报错,建议 LCBIT 设置为0,和原来一样.

小小调度器1.2.0问星整理版.rar (3.32 KB, 下载次数: 18)


评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:328014 发表于 2020-10-26 03:13 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

地板
ID:97470 发表于 2020-11-4 14:01 | 只看该作者
重要更新!!!
2020-11-04
  1、修复超时判断只能生效1次的BUG(群友"上善若水"发现)
     在WaitUtilT(A,TimeOut)、WAITUNTILT(A,VAL,TimeOut)、WaitUtilTR(A,TimeOut)、WAITUNTILTR(A,VAL,TimeOut)定义里增加”_count=TimeOut;“


小小调度器1.2.1问星整理版.rar (3.64 KB, 下载次数: 21)

回复

使用道具 举报

5#
ID:429830 发表于 2020-12-14 00:52 | 只看该作者
赞赞赞
回复

使用道具 举报

6#
ID:97470 发表于 2020-12-14 10:10 | 只看该作者
2020-11-06
    1、增加 #define WAITUTILTRTYPE 0         //WaitUtilTR 超时等待判断类型选择宏
        0=简单,WaitUtilTR(A,TimeOut,TINDEX) TINDEX:超时等待索引只能0-7,每个WaitUtilTR的索引不能重复,只支持8个实时性高的超时判断;
        1=灵活 自定义变量,WaitUtilTR(A,TimeOut,T1FLAY) T1FLAY:1个调度器时钟周期标志变量,需在调度器时钟周期定时器中断里将变量置1。
        简单调用示例:WaitUtilTR(f.b0,2,0);

2020-11-05
    1、修改“_count”赋初值的位置,使之理合理
    2、修改“WaitUtilTR(A,TimeOut)、WAITUNTILTR(A,VAL,TimeOut)”定义,解决实时性高的判断等待超时时间不准的问题
        增加“T1FLAY”一个调度器周期标志变量参数,变为“WaitUtilTR(A,TimeOut,T1FLAY)、WAITUNTILTR(A,VAL,TimeOut,T1FLAY)”
        使用方式请参考例子
小小调度器1.2.3问星整理版.rar (5.06 KB, 下载次数: 50)

回复

使用道具 举报

7#
ID:230847 发表于 2020-12-27 10:25 | 只看该作者
谢谢楼主,这个不错。能看懂,期待更新。
回复

使用道具 举报

8#
ID:230847 发表于 2020-12-28 09:18 | 只看该作者
编译后出现test.c(99): warning C294: unreachable code。这个怎么消除呢?
回复

使用道具 举报

9#
ID:814329 发表于 2021-1-9 11:29 | 只看该作者
支持,下载详细学习一下
回复

使用道具 举报

10#
ID:814329 发表于 2021-1-9 11:35 | 只看该作者
有简单的应用指导说明和具体应用的实例介绍吗?三个LED,三个任务,不能充分说明系统真正的实用价值。
回复

使用道具 举报

11#
ID:219078 发表于 2021-4-8 14:19 | 只看该作者
赞个,后续还有更新吗?准备试试看
回复

使用道具 举报

12#
ID:807361 发表于 2023-6-24 22:13 | 只看该作者
这个小小调度器现在更新到哪个版本了??
回复

使用道具 举报

13#
ID:899151 发表于 2025-1-24 10:35 | 只看该作者
感谢分享,这个比较好 1.2.3加入了setjmp
回复

使用道具 举报

14#
ID:1101997 发表于 2025-1-25 12:15 | 只看该作者
51用OS做的看来还是少啊,关心的人不多,其实项目大还是这个方便
回复

使用道具 举报

15#
ID:338503 发表于 2025-1-25 14:18 | 只看该作者
51用OS做我还没做过,下载下来有空研究一下,后期有大项目用这个比较方便好。非常感谢 xyb851。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表