找回密码
 立即注册

QQ登录

只需一步,快速开始

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

闲着无聊写了个简便的裸机调度器 附单片机程序

[复制链接]
跳转到指定楼层
楼主
ID:130230 发表于 2020-11-8 00:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
废话不说,直接上单片机程序。
=========================================================================================
  1. /*
  2. 说明:精简调度器实现
  3. 作者:jizhongbiao
  4. 微信:mcu6666
  5. */
  6. #ifndef CORE_H
  7. #define CORE_H

  8. /* 基本类型转义(与平台相关注意修改) */
  9. typedef (unsigned char)  u8;
  10. typedef (char)           i8;
  11. typedef (unsigned short) u16;
  12. typedef (short)          i16;

  13. #define USE_LOW_POWER_MODE 0 /* 需要低功耗则打开这个宏 */

  14. enum {
  15.     /* 依次在此处添加任务枚举作为唯一ID */
  16.     MAX_TASK_NUM
  17. };

  18. typedef enum {
  19.     DEL_INDEX,
  20.     DEL_ID,
  21.     MAX_DEL_TYPE,
  22. }DeleteType;

  23. typedef enum {
  24.     DEL_PARAERR,
  25.     DEL_SUCCESS,
  26.     DEL_FAIL,
  27.     MAX_DEL,
  28. } DeleteResult;

  29. typedef enum {
  30.     ADD_PARAERR,
  31.     ADD_SUCCESS,
  32.     ADD_FAIL,
  33.     MAX_ADD,
  34. }AddResult;

  35. /* 任务数据结构定义 */
  36. typedef struct {
  37.     void (*TaskPtr)(void); /* 待运行的任务函数指针 */
  38.     u16  actionDelay;      /* 运行延迟,以时标为单位,为0代表立即执行 */
  39.     u16  actionPeriod;     /* 运行间隔为0代表单次运行 */
  40.     u8   readyFlg;         /* 就绪标志 */
  41.     u8   taskId;           /* 任务标识 非优先级 */
  42. }TaskStruct;

  43. void Scheduling(void);
  44. DeleteResult TaskDelete(const u8 para, const DeleteType type);
  45. void UpdataHandle(void);
  46. AddResult AddTask( void (*TaskPtr)(), const u16 delay, const u16 period, const u8 id);

  47. #endif


  48. ==========================================================================================
  49. /*
  50. 说明:精简合作式调度器实现
  51. 作者:jizhongbiao
  52. 微信:mcu6666(项目承接)
  53. 版本:tt001.0
  54. 备注:1,需要硬件提供一个定时中断
  55.       2,当前版本不支持抢占式调度
  56. */
  57. #include "core.h"

  58. /* 任务队列 */
  59. volatile static TaskStruct g_task[MAX_TASK_NUM];

  60. /* 任务删除,支持两种方式(id及index) */
  61. DeleteResult TaskDelete(const u8 para, const DeleteType type)
  62. {
  63.     u8 i;
  64.     u8 temp = para;
  65.     DeleteResult ret;

  66.     /* 参数不合法 */
  67.     if ((type >= MAX_DEL_TYPE) || (para >= MAX_TASK_NUM)) {
  68.         return DEL_PARAERR;
  69.     }

  70.     if (type == DEL_INDEX) {
  71.         if(g_task[para].TaskPtr == 0) {
  72.             return DEL_FAIL;
  73.         }
  74.     } else {
  75.         for(i = 0; i < MAX_TASK_NUM, i++) {
  76.             if (g_task[i].TaskPtr) {
  77.                 temp = i;
  78.                 break;
  79.             }
  80.         }
  81.         if(i == MAX_TASK_NUM) {
  82.             return DEL_FAIL;
  83.         }
  84.     }

  85.     /* 真正的删除动作,注意不可以使用memset(id不准清0) */
  86.     g_task[temp].actionDelay  = 0;
  87.     g_task[temp].actionPeriod = 0;
  88.     g_task[temp].readyFlg     = 0;
  89.     g_task[temp].TaskPtr      = 0;

  90.     return DEL_SUCCESS;
  91. }

  92. /* 任务创建 */
  93. AddResult AddTask( void (*TaskPtr)(), const u16 delay, const u16 period, const u8 id)
  94. {
  95.     u8 i = 0;
  96.     /* 判空 指向0地址会发生不可预测错误*/
  97.     if(TaskPtr == 0) {
  98.         return ADD_PARAERR;
  99.     }

  100.     while ((i < MAX_TASK_NUM) && g_task[i].TaskPtr) {
  101.         i++;
  102.     }
  103.     if (i == MAX_TASK_NUM) {
  104.         return ADD_FAIL;
  105.     }
  106.     /* 向表中空隙插入任务块信息 */
  107.     if(delay == 0) {
  108.         /* 在调度函数中会立即执行,不需要等待时标响应 */
  109.         g_task[i].readyFlg = 1;
  110.     } else {
  111.         g_task[i].readyFlg = 0;
  112.     }
  113.     g_task[i].actionDelay  = delay;
  114.     g_task[i].actionPeriod = period;
  115.     g_task[i].taskId       = id;
  116.     g_task[i].TaskPtr      = TaskPtr;
  117.     return ADD_SUCCESS;
  118. }

  119. /* 定时刷新任务状态函数,本函数应在定时器中断函数中调用 */
  120. void UpdataHandle(void)
  121. {
  122.     u8 i;
  123.     for (i = 0; i < MAX_TASK_NUM; i++) {
  124.         if(g_task[i].TaskPtr) {
  125.             if(g_task[i].actionDelay) {
  126.                 g_task[i].actionDelay--;
  127.             } else {
  128.                 /* 本分支为延迟时间已经为0 */
  129.                 g_task[i].readyFlg = 1;
  130.                 /* 周期性任务重新设置延迟时标 单次任务删除在调度函数中完成*/
  131.                 if(g_task[i].actionPeriod) {
  132.                     g_task[i].actionDelay = g_task[i].actionPeriod;
  133.                 }
  134.             }
  135.         }
  136.     }
  137. }

  138. /*调度器初始化*/
  139. void  ScheduInit(void)
  140. {
  141.     u8 i;
  142.     for(i = 0; i < MAX_TASK_NUM; i++) {
  143.         (void)TaskDelete(i, DEL_INDEX);
  144.     }
  145. }

  146. /* 调度执行函数 */
  147. void Scheduling(void)
  148. {
  149.     u8 index;
  150.     for(index = 0; index < MAX_TASK_NUM; index++) {
  151.         if (g_task[index].readyFlg) {
  152.             (g_task[index].TaskPtr)(); /* 执行已就绪的任务 */
  153.             g_task[index].readyFlg = 0;
  154.             /* 如果单次运行则删除该任务 */
  155.             if(g_task[index].actionPeriod == 0) {
  156.                 TaskDelte(index);
  157.             }
  158.         }
  159.     }
  160. #if (USE_LOW_POWER_MODE == 1)
  161.     McuEnterStandby(); /* 需要根据不同芯片及硬件适配低功耗函数 */
  162. #endif
  163. }
复制代码


评分

参与人数 1黑币 +90 收起 理由
admin + 90 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:420836 发表于 2020-11-8 08:23 | 只看该作者
感谢您分享您的代码。 应该会很有帮助!
回复

使用道具 举报

板凳
ID:328014 发表于 2020-11-8 14:56 | 只看该作者
好东东啊,能应用在哪些地方呢?
回复

使用道具 举报

地板
ID:130230 发表于 2020-11-22 12:38 | 只看该作者
核心还是时间触发,不适合需要快速响应的场合。因为不支持抢占式调度,就我的经验来说绝大多数单片机的应用合作式调度足够了。
回复

使用道具 举报

5#
ID:258257 发表于 2020-11-30 15:20 | 只看该作者
牛人呀!这是自定义多任务系统的最佳启蒙资料了。受教了!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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