TimeScheduleSystem.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /************************************/
  2. /* @Author: @woshiashuai */
  3. /* @Version: V1.0 */
  4. /* @Date: 2023-02-13 10:49:00 */
  5. /* @Description: */
  6. /* V1.0: create */
  7. /************************************/
  8. #include "TimeScheduleSystem.h"
  9. TSS_t *TSS_head = NULL; // 分时调度系统工作链表头节点
  10. /**
  11. * @brief 分时调度事件初始化
  12. * @note 加入到初始化中
  13. * @param TSS: 事件指针
  14. * @param targetTicks: 目标计数值 = 事件调度周期 / 调度器周期 例如: 100 = 500ms / 5ms
  15. * @param callback: 事件回调函数
  16. * @retval 0: 初始化成功 1: 参数二为零 2: 参数三为空 3: 事件已存在
  17. */
  18. unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(void))
  19. {
  20. if(targetTicks == 0) return 1;
  21. if(callback == NULL) return 2;
  22. memset(TSS, 0, sizeof(TSS_t));
  23. TSS->targetTicks = targetTicks;
  24. TSS->callback = callback;
  25. return 0;
  26. }
  27. /**
  28. * @brief 分时调度事件执行(循环)处理的内部方法
  29. * @note None
  30. * @param TSS: 事件指针
  31. * @retval None
  32. */
  33. static void TSS_whileHandle(TSS_t *TSS)
  34. {
  35. // 分时调度结果是等待中或跳过调度则退出
  36. if(!TSS->result || TSS->skip) return ;
  37. TSS->callback(); // 执行绑定的回调函数
  38. TSS->ticks = 0; // 防止因手动切换状态导致的ticks不为0
  39. TSS->result = 0; // 切换分时调度结果为等待中
  40. }
  41. /**
  42. * @brief 分时调度事件执行(循环)处理
  43. * @note 加入到主循环中
  44. * @param None
  45. * @retval None
  46. */
  47. void TSS_while(void)
  48. {
  49. TSS_t *TSS_target;
  50. for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) {
  51. TSS_whileHandle(TSS_target);
  52. }
  53. }
  54. /**
  55. * @brief 分时调度事件调度处理的内部方法
  56. * @note None
  57. * @param TSS: 事件指针
  58. * @retval None
  59. */
  60. static void TSS_timerHandle(TSS_t *TSS)
  61. {
  62. // 分时调度结果是可执行或跳过调度则退出
  63. if(TSS->result || TSS->skip) return ;
  64. TSS->ticks += 1; // 计数自加
  65. // 计数大于等于目标计数
  66. if(TSS->ticks >= TSS->targetTicks) {
  67. TSS->ticks = 0; // 计数清零
  68. TSS->result = 1; // 切换分时调度结果为可执行
  69. }
  70. }
  71. /**
  72. * @brief 分时调度事件调度处理
  73. * @note 加入到调度器中
  74. * @param None
  75. * @retval None
  76. */
  77. void TSS_timer(void)
  78. {
  79. TSS_t *TSS_target;
  80. for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) {
  81. TSS_timerHandle(TSS_target);
  82. }
  83. }
  84. /**
  85. * @brief 分时调度事件挂起处理
  86. * @note 主要用于将事件从工作链表中取下
  87. * @param TSS: 事件指针
  88. * @retval 0: 挂起成功 1: 事件未初始化/初始化失败 2: 事件不在工作链表中(可能已被挂起)
  89. */
  90. unsigned char TSS_pending(TSS_t *TSS)
  91. {
  92. if((TSS->targetTicks == 0) || (TSS->callback == NULL)) return 1;
  93. TSS_t *TSS_target = TSS_head;
  94. TSS_t *TSS_last = NULL;
  95. while(TSS_target) {
  96. // 查找事件是否存在
  97. if(TSS_target == TSS) {
  98. // 是否在头节点
  99. if(TSS_last == NULL) {
  100. TSS_head = TSS_target->next; // 在头节点则将下一个节点作为新的头节点
  101. } else {
  102. // 不在头节点则将下一个节点链接到上一个节点
  103. TSS_last->next = TSS_target->next;
  104. TSS_head = TSS_last;
  105. }
  106. TSS->state = 0; // 退出工作链表则改变状态为不在工作链表
  107. return 0;
  108. }
  109. TSS_last = TSS_target;
  110. TSS_target = TSS_target->next;
  111. }
  112. return 2;
  113. }
  114. /**
  115. * @brief 分时调度事件启动处理
  116. * @note 主要用于将事件加入到工作链表中
  117. * @param TSS: 事件指针
  118. * @retval 0: 启动成功 1: 事件未初始化/初始化失败 2: 事件已在工作链表中(可能已被恢复)
  119. */
  120. unsigned char TSS_start(TSS_t *TSS)
  121. {
  122. if((TSS->targetTicks == 0) || (TSS->callback == NULL)) return 1;
  123. TSS_t *TSS_target = TSS_head;
  124. while(TSS_target) {
  125. if(TSS_target == TSS) return 2;
  126. TSS_target = TSS_target->next;
  127. }
  128. TSS->state = 1; // 加入工作链表则改变状态为在工作链表
  129. TSS->next = TSS_head;
  130. TSS_head = TSS;
  131. return 0;
  132. }
  133. /**
  134. * @brief 分时调度事件设置计数值处理
  135. * @note None
  136. * @param TSS: 事件指针
  137. * @param ticks: 设置的计数值
  138. * @retval None
  139. */
  140. void TSS_setTicks(TSS_t *TSS, unsigned char ticks)
  141. {
  142. TSS->ticks = ticks;
  143. }
  144. /**
  145. * @brief 分时调度事件获取计数值处理
  146. * @note None
  147. * @param TSS: 事件指针
  148. * @retval 事件计数值
  149. */
  150. unsigned int TSS_getTicks(TSS_t *TSS)
  151. {
  152. return TSS->ticks;
  153. }
  154. /**
  155. * @brief 分时调度事件设置目标计数值处理
  156. * @note 主要用于修改事件执行周期,若较上次改小则可能立即触发事件执行
  157. * @param TSS: 事件指针
  158. * @param result: 设置的目标计数值
  159. * @retval None
  160. */
  161. void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks)
  162. {
  163. TSS->targetTicks = targetTicks;
  164. }
  165. /**
  166. * @brief 分时调度事件获取目标计数值处理
  167. * @note 主要用于查看事件执行周期
  168. * @param TSS: 事件指针
  169. * @retval 事件目标计数值
  170. */
  171. unsigned int TSS_TargetTicks(TSS_t *TSS)
  172. {
  173. return TSS->targetTicks;
  174. }
  175. /**
  176. * @brief 分时调度事件设置结果值处理
  177. * @note 主要用于立即切换事件结果为1:可执行
  178. * @param TSS: 事件指针
  179. * @param result: 设置的结果值
  180. * @retval None
  181. */
  182. void TSS_setResult(TSS_t *TSS, unsigned char result)
  183. {
  184. TSS->result = result;
  185. }
  186. /**
  187. * @brief 分时调度事件获取结果值处理
  188. * @note 一般获取到的事件结果多为0:等待中,因为在事件执行后事件结果值即清零
  189. * @param TSS: 事件指针
  190. * @retval 事件结果值 0: 等待中 1: 可执行
  191. */
  192. unsigned char TSS_getResult(TSS_t *TSS)
  193. {
  194. return TSS->result;
  195. }
  196. /**
  197. * @brief 分时调度事件设置状态值处理
  198. * @note 手动操作此函数无效,因为事件状态只与事件是否存在于工作链表中有关
  199. * @param TSS: 事件指针
  200. * @param state: 设置的状态值
  201. * @retval None
  202. */
  203. void TSS_setState(TSS_t *TSS, unsigned char state)
  204. {
  205. // TSS->state = state;
  206. }
  207. /**
  208. * @brief 分时调度事件获取状态值处理
  209. * @note 主要用于查看事件是否存在于工作链表中
  210. * @param TSS: 事件指针
  211. * @retval 事件的状态值 0:不在工作链表 1:在工作链表
  212. */
  213. unsigned char TSS_getState(TSS_t *TSS)
  214. {
  215. return TSS->state;
  216. }
  217. /**
  218. * @brief 分时调度事件设置跳过值处理
  219. * @note 主要用于事件仍在工作链表中的启动或挂起,相较于把事件从工作链表取下和恢复,此操作更快
  220. * @param TSS: 事件指针
  221. * @param state: 设置的跳过值
  222. * @retval None
  223. */
  224. void TSS_setSkip(TSS_t *TSS, unsigned char skip)
  225. {
  226. TSS->skip = skip;
  227. }
  228. /**
  229. * @brief 分时调度事件获取跳过值处理
  230. * @note 主要用于查看事件是否跳过事件调度,事件仍在工作链表中的启动或挂起
  231. * @param TSS: 事件指针
  232. * @retval 事件的跳过值 0:不跳过调度 1: 跳过调度
  233. */
  234. unsigned char TSS_getSkip(TSS_t *TSS)
  235. {
  236. return TSS->skip;
  237. }