amobbs.com 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
回复: 49

开源个我的极简定时调度器

  [复制链接]
(18843549)
发表于 2019-11-28 21:37:19 | 显示全部楼层 |阅读模式
就俩文件,五个api:
ztask.h:
  1. #ifndef _ZTASK_H
  2. #define _ZTASK_H

  3. #define ZT_MAX_TASKS 4

  4. typedef void (*zt_func_t)(void);

  5. // should be called in main loop
  6. void zt_poll(void);

  7. // timeout: repeat inteval;   en: start immediately or not
  8. int zt_bind(zt_func_t func, int repeat, int en);

  9. // should be called in systick_irqhandler
  10. void zt_tick(void);

  11. void zt_start(int id);
  12. void zt_stop(int id);

  13. #endif
复制代码


ztask.c:
  1. #include "ztask.h"

  2. typedef struct {
  3.     zt_func_t func;
  4.     unsigned long timeout, repeat;
  5.     int en;
  6. } zt_task_t;

  7. static struct {
  8.     unsigned long ticks;
  9.     int num_tasks;
  10.     zt_task_t tasks[ZT_MAX_TASKS];
  11. } g;

  12. void zt_tick(void)
  13. {
  14.     // overflow not handled. for 1ms tick, it could run 2^32 * 1ms = ~50 days.
  15.     g.ticks++;
  16. }

  17. void zt_poll(void)
  18. {
  19.     int i;
  20.     for(i = 0; i < g.num_tasks; i++) {
  21.         if(g.ticks >= g.tasks[i].timeout) {
  22.             g.tasks[i].timeout = g.ticks + g.tasks[i].repeat;
  23.             if(g.tasks[i].en)
  24.                 g.tasks[i].func();
  25.         }
  26.     }
  27. }

  28. void zt_stop(int id)
  29. {
  30.     if(id < ZT_MAX_TASKS)
  31.         g.tasks[id].en = 0;
  32. }

  33. void zt_start(int id)
  34. {
  35.     if(id < ZT_MAX_TASKS)
  36.         g.tasks[id].en = 1;
  37. }

  38. int zt_bind(zt_func_t func, int repeat, int en)
  39. {
  40.     if(g.num_tasks < ZT_MAX_TASKS) {
  41.         g.tasks[g.num_tasks].func = func;
  42.         g.tasks[g.num_tasks].repeat = repeat;
  43.         g.tasks[g.num_tasks].timeout = 0;
  44.         g.tasks[g.num_tasks].en = en;
  45.         return g.num_tasks++;
  46.     }
  47.     else
  48.         return -1;
  49. }
复制代码

使用方法:
定义两个任务函数:
  1. void blink(void)
  2. {
  3.     GPIOA->ODR |= GPIO_PIN_1;
  4.     _delay_us(10);
  5.     GPIOA->ODR &= ~GPIO_PIN_1;
  6. }

  7. void hello(void)
  8. {
  9.     printf("Hello, world.\n");
  10. }
复制代码


在进入主循环前:

  1.    zt_bind(blink, 100, 1);      // 每100ms执行一次
  2.    zt_bind(hello, 500, 1);     // 每500ms执行一次
复制代码


最后在主循环里调用 zt_poll(), 在systick中断里调用zt_tick(), 就行了。

如果需要控制任务启动/停止, 需要用一个变量保存zt_bind的返回值,然后执行zt_start和zt_stop即可。
(18843228)
发表于 2019-11-28 21:42:40 | 显示全部楼层
谢谢,感谢开源,学习了
(18842230)
发表于 2019-11-28 21:59:18 | 显示全部楼层
有空研究一番,感谢分享,开源必顶。
(18841796)
发表于 2019-11-28 22:06:32 来自手机 | 显示全部楼层
非常小巧,谢谢
(18841627)
发表于 2019-11-28 22:09:21 | 显示全部楼层
谢谢分享!
(18841607)
发表于 2019-11-28 22:09:41 | 显示全部楼层
感谢楼主的奉献啊
(18840748)
发表于 2019-11-28 22:24:00 来自手机 | 显示全部楼层
非常好,感谢开源,有空自己写一遍学习
(18840302)
发表于 2019-11-28 22:31:26 | 显示全部楼层
学习下   谢谢分享
(18840120)
发表于 2019-11-28 22:34:28 来自手机 | 显示全部楼层
学习 谢谢分享
(18839366)
发表于 2019-11-28 22:47:02 | 显示全部楼层
提2个意见:
1. z_bind和z_start好象重复了,好象前者已经暗含后者的功能了,
2. 看注释 z_bind可以决定功能函数执行几次,是不是应该有一个 .en--,这个自减减动作呢。。。当减到0就不运行了。。


(18839078)
 楼主| 发表于 2019-11-28 22:51:50 | 显示全部楼层
kinsno 发表于 2019-11-28 22:47
提2个意见:
1. z_bind和z_start好象重复了,好象前者已经暗含后者的功能了,
2. 看注释 z_bind可以决定功 ...

不是, en就是当布尔量用的,我不想让它依赖stdbool之类c99的库。
zt_bind时如果en参数为0,就是不让它立刻开始自动执行,而是需要时才用zt_start启动。
(18838961)
发表于 2019-11-28 22:53:47 | 显示全部楼层
tomzbj 发表于 2019-11-28 22:51
不是, en就是当布尔量用的,我不想让它依赖stdbool之类c99的库。
zt_bind时如果en参数为0,就是不让它立 ...

那你这个就是永久启动的,并没有执行多少次的功能,是吧。。en也只是个使能,并不是number

(18838782)
发表于 2019-11-28 22:56:46 来自手机 | 显示全部楼层
假如任务超级费时的,怎么办?
(18838183)
 楼主| 发表于 2019-11-28 23:06:45 | 显示全部楼层
kinsno 发表于 2019-11-28 22:53
那你这个就是永久启动的,并没有执行多少次的功能,是吧。。en也只是个使能,并不是number

...

对,没有设计按次数执行。需要的话加一个也容易呀~
(18838160)
 楼主| 发表于 2019-11-28 23:07:08 | 显示全部楼层
hnlg 发表于 2019-11-28 22:56
假如任务超级费时的,怎么办?

交给用户自己考虑吧, hehe
(18837178)
发表于 2019-11-28 23:23:30 | 显示全部楼层
代码这么简短,学习学习
(18805014)
发表于 2019-11-29 08:19:34 | 显示全部楼层
感谢楼主分享,学习一下
(18803078)
发表于 2019-11-29 08:51:50 | 显示全部楼层

感谢楼主分享,学习一下
(18802198)
发表于 2019-11-29 09:06:30 | 显示全部楼层
感谢楼主分享,收藏。
(18801987)
发表于 2019-11-29 09:10:01 | 显示全部楼层
感谢分享
(18801442)
发表于 2019-11-29 09:19:06 | 显示全部楼层
非常感谢lz的开源,支持开源精神!
两点建议:
1、timeout 的callback支持参数会更灵活;
2、bind接口,可增加是否初始化timeout变量,满足不需要一启动就马上timeout的情景;
(18801067)
发表于 2019-11-29 09:25:21 | 显示全部楼层
感谢楼主分享,学习一下
(18799414)
发表于 2019-11-29 09:52:54 来自手机 | 显示全部楼层
对单个任务的执行时间有限制吗?超过一个时间片会打断吗
(18798855)
发表于 2019-11-29 10:02:13 | 显示全部楼层
子任务是轮询,不会打断,单个长时间任务最好通过状态机进行任务分割
(18798320)
发表于 2019-11-29 10:11:08 | 显示全部楼层
简单程序的用状态机机制就可以
(18797589)
发表于 2019-11-29 10:23:19 | 显示全部楼层
这个就是轮询任务函数,坛子里其他调度器
(18797141)
发表于 2019-11-29 10:30:47 | 显示全部楼层
不错,有点像“时间触发嵌入式系统......”
(18783333)
发表于 2019-11-29 14:20:55 | 显示全部楼层
收藏,谢谢楼主分享
(18767929)
发表于 2019-11-29 18:37:39 来自手机 | 显示全部楼层
加回调,可以在中断中运行
(18716751)
发表于 2019-11-30 08:50:37 | 显示全部楼层
收藏,谢谢楼主分享
(18716531)
发表于 2019-11-30 08:54:17 | 显示全部楼层
赞楼主开源!
(18696967)
发表于 2019-11-30 14:20:21 | 显示全部楼层
谢谢楼主分享
(18683537)
发表于 2019-11-30 18:04:11 | 显示全部楼层
短小精悍
(18675885)
发表于 2019-11-30 20:11:43 | 显示全部楼层
好精简啊!
(18667647)
发表于 2019-11-30 22:29:01 | 显示全部楼层
短小精悍,收藏研究下
(18667347)
发表于 2019-11-30 22:34:01 | 显示全部楼层
感谢开源
(18634498)
发表于 2019-12-1 07:41:30 | 显示全部楼层
不错、不错,看来还是有一堆人没玩过 OS 啊!呵呵~
(18628885)
发表于 2019-12-1 09:15:03 | 显示全部楼层

赞楼主开源!
(18495763)
发表于 2019-12-2 22:13:45 | 显示全部楼层
kinsno 发表于 2019-11-28 22:47
提2个意见:
1. z_bind和z_start好象重复了,好象前者已经暗含后者的功能了,
2. 看注释 z_bind可以决定功 ...

z_bind没有运行次数的限定,repeat作为时间在用。只能手动修改en进行开启或者停止。

好像前面有说了,回调加入参数就更好了。其实与其说是时间调度,还不如说是软件定时器。
(18492045)
发表于 2019-12-2 23:15:43 | 显示全部楼层
謝謝分享,有機會使用一下,但目前用的編譯器都不支持函數指針,咋整?
(18491649)
 楼主| 发表于 2019-12-2 23:22:19 | 显示全部楼层
lzm2010 发表于 2019-12-2 23:15
謝謝分享,有機會使用一下,但目前用的編譯器都不支持函數指針,咋整? ...

不是吧, 什么编译器? 符合ansi标准的c编译器就应该支持啊
(18467792)
发表于 2019-12-3 05:59:56 | 显示全部楼层
tomzbj 发表于 2019-12-2 23:22
不是吧, 什么编译器? 符合ansi标准的c编译器就应该支持啊

HOLTEK的編譯器不支持函數指針
(18459403)
 楼主| 发表于 2019-12-3 08:19:45 | 显示全部楼层
lzm2010 发表于 2019-12-3 05:59
HOLTEK的編譯器不支持函數指針

标准库的qsort都用不了啊……
(18457248)
发表于 2019-12-3 08:55:40 | 显示全部楼层
不错, 还蛮简单实用
(18449388)
发表于 2019-12-3 11:06:40 | 显示全部楼层
STOP的时候是不是需要清一下计数器
(18438614)
发表于 2019-12-3 14:06:14 | 显示全部楼层
学习,谢谢!!!!
(18434520)
发表于 2019-12-3 15:14:28 | 显示全部楼层
hnlg 发表于 2019-11-28 22:56
假如任务超级费时的,怎么办?

估计只能用抢占式了
(18416623)
发表于 2019-12-3 20:12:45 | 显示全部楼层
收下了,谢谢分享
(18344778)
发表于 2019-12-4 16:10:10 | 显示全部楼层
hnlg 发表于 2019-11-28 22:56
假如任务超级费时的,怎么办?

任务超过时间的话问题不大,就是其他任务的执行的时间点会延后一点而已,但是如果有些任务的执行频率十分高的话,会出现部分轮空的情况。
(18344636)
发表于 2019-12-4 16:12:32 | 显示全部楼层
程序还没有来的及看, 先研究了一下你的头像
回帖提示: 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号-1 )

GMT+8, 2020-7-3 23:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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