/************************************/ /* @Author: @woshiashuai */ /* @Version: V1.0 */ /* @Date: 2023-02-12 13:06:48 */ /* @Description: */ /* V1.0: create */ /************************************/ #include "TimeScheduleSystem.h" TSS_t *TSS_head = NULL; // 分时调度系统工作链表头节点 /** * @brief 分时调度事件初始化 加入到初始化中 * @param TSS: 事件指针 * @param targetTicks: 目标计数值 = 事件调度周期 / 调度器周期 例如: 100 = 500ms / 5ms * @param callback: 事件回调函数 * @retval 0: 初始化成功 1: 参数二为零 2: 参数三为空 3: 事件已存在 */ unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(void)) { if(targetTicks == 0) return 1; if(callback == NULL) return 2; memset(TSS, 0, sizeof(TSS_t)); TSS->targetTicks = targetTicks; TSS->callback = callback; TSS_t *TSS_target = TSS_head; while(TSS_target) { if(TSS_target == TSS) return 3; TSS_target = TSS_target->next; } TSS->state = 1; // 加入工作链表则改变状态为在工作链表 TSS->next = TSS_head; TSS_head = TSS; return 0; } /** * @brief 分时调度事件循环处理的内部方法 * @param TSS: 事件指针 * @retval None */ static void TSS_whileHandle(TSS_t *TSS) { // 分时调度结果是可执行 if(TSS->result) { TSS->callback(); // 执行绑定的回调函数 TSS->ticks = 0; // 防止因手动切换状态导致的ticks不为0 TSS->result = 0; // 切换分时调度结果为等待中 } } /** * @brief 分时调度事件循环处理 加入到主循环中 * @param None * @retval None */ void TSS_while(void) { TSS_t *TSS_target; for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) { TSS_whileHandle(TSS_target); } } /** * @brief 分时调度事件调度处理的内部方法 * @param TSS: 事件指针 * @retval None */ static void TSS_timerHandle(TSS_t *TSS) { // 分时调度结果是等待中 if(!TSS->result) { TSS->ticks += 1; // 计数自加 // 计数大于等于目标计数 if(TSS->ticks >= TSS->targetTicks) { TSS->ticks = 0; // 计数清零 TSS->result = 1; // 切换分时调度结果为可执行 } } } /** * @brief 分时调度事件调度处理 加入到调度器中 * @param None * @retval None */ void TSS_timer(void) { TSS_t *TSS_target; for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) { TSS_timerHandle(TSS_target); } } /** * @brief 分时调度事件挂起处理 将事件从工作链表中去掉 * @param TSS: 事件指针 * @retval 0: 挂起成功 1: 事件未初始化/初始化失败 2: 事件不在工作链表中(可能已被挂起) */ unsigned char TSS_pending(TSS_t *TSS) { if((TSS->targetTicks == 0) || (TSS->callback == NULL) || (TSS->next == NULL)) return 1; TSS_t *TSS_target = TSS_head; TSS_t *TSS_last = NULL; while(TSS_target) { // 查找事件是否存在 if(TSS_target == TSS) { // 是否在头节点 if(TSS_last == NULL) { TSS_head = TSS_target->next; // 在头节点则将下一个节点作为新的头节点 } else { // 不在头节点则将下一个节点链接到上一个节点 TSS_last->next = TSS_target->next; TSS_head = TSS_last; } TSS->state = 0; // 退出工作链表则改变状态为不在工作链表 return 0; } TSS_last = TSS_target; TSS_target = TSS_target->next; } return 2; } /** * @brief 分时调度事件恢复处理 * @param TSS: 事件指针 * @retval 0: 恢复成功 1: 事件未初始化/初始化失败 2: 事件已在工作链表中(可能已被恢复) */ unsigned char TSS_resume(TSS_t *TSS) { if((TSS->targetTicks == 0) || (TSS->callback == NULL) || (TSS->next == NULL)) return 1; TSS_t *TSS_target = TSS_head; while(TSS_target) { if(TSS_target == TSS) return 2; TSS_target = TSS_target->next; } TSS->state = 1; // 加入工作链表则改变状态为在工作链表 TSS->next = TSS_head; TSS_head = TSS; return 0; } /** * @brief 分时调度事件设置计数值处理 * @param TSS: 事件指针 * @param ticks: 设置的计数值 * @retval None */ void TSS_setTicks(TSS_t *TSS, unsigned char ticks) { TSS->ticks = ticks; } /** * @brief 分时调度事件获取计数值处理 * @param TSS: 事件指针 * @retval 事件计数值 */ unsigned int TSS_getTicks(TSS_t *TSS) { return TSS->ticks; } /** * @brief 分时调度事件设置目标计数值处理 主要用于修改事件执行周期,若较上次改小则可能立即触发事件执行 * @param TSS: 事件指针 * @param result: 设置的目标计数值 * @retval None */ void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks) { TSS->targetTicks = targetTicks; } /** * @brief 分时调度事件获取目标计数值处理 主要用于查看事件执行周期 * @param TSS: 事件指针 * @retval 事件目标计数值 */ unsigned int TSS_TargetTicks(TSS_t *TSS) { return TSS->targetTicks; } /** * @brief 分时调度事件设置结果值处理 主要用于立即切换事件结果为1:可执行 * @param TSS: 事件指针 * @param result: 设置的结果值 * @retval None */ void TSS_setResult(TSS_t *TSS, unsigned char result) { TSS->result = result; } /** * @brief 分时调度事件获取结果值处理 一般获取到的事件结果多为0:等待中,因为事件执行后即清零 * @param TSS: 事件指针 * @retval 事件结果值 0: 等待中 1: 可执行 */ unsigned char TSS_getResult(TSS_t *TSS) { return TSS->result; } /** * @brief 分时调度事件设置状态值处理 手动操作此函数无效,因为事件状态只与事件是否存在于工作链表中有关 * @param TSS: 事件指针 * @param state: 设置的状态值 * @retval None */ void TSS_setState(TSS_t *TSS, unsigned char state) { // TSS->state = state; } /** * @brief 分时调度事件获取状态值处理 主要用于查看事件是否存在于工作链表中 * @param TSS: 事件指针 * @retval 事件的状态值 0:不在工作链表 1:在工作链表 */ unsigned char TSS_getState(TSS_t *TSS) { return TSS->state; }