# CE2609_TickTask **Repository Path**: Cation_git/tick-task ## Basic Information - **Project Name**: CE2609_TickTask - **Description**: 基于systick的时间片调度框架 - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-25 - **Last Updated**: 2026-02-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TickTask #### 介绍 基于systick的时间片调度框架 ```c #include /* 频率宏定义(单位:毫秒),可在编译前修改 */ #define HIGH_FREQ_INTERVAL_MS 10 // 高频周期 10ms #define MED_FREQ_INTERVAL_MS 100 // 中频周期 100ms #define LOW_FREQ_INTERVAL_MS 1000 // 低频周期 1s /* 各频次最大任务数 */ #define HIGH_TASK_NUM 5 #define MED_TASK_NUM 5 #define LOW_TASK_NUM 5 /* 任务结构体:函数指针 + 使能标志 */ typedef struct { void (*func)(void); // 任务函数 uint8_t enable; // 1-使能,0-禁能 } Task_t; /* 各频次任务数组 */ static Task_t high_tasks[HIGH_TASK_NUM]; static Task_t med_tasks[MED_TASK_NUM]; static Task_t low_tasks[LOW_TASK_NUM]; /* 时间标志,由定时器中断置位 */ static volatile uint8_t high_flag = 0; static volatile uint8_t med_flag = 0; static volatile uint8_t low_flag = 0; /* 系统滴答计数器(假设1ms中断一次) */ static volatile uint32_t system_tick = 0; /* 任务处理函数声明 */ static void task_high_handler(void); static void task_med_handler(void); static void task_low_handler(void); /* 系统状态机状态 */ static uint8_t system_state = 0; // 0-初始化,1-运行,2-低功耗 static void display_refresh(void) { } // 串口发送进入忙碌 中断里清理忙碌标志为空闲(发送完成中断) // 忙碌中 直接退出任务 // DMA发送 完成回调里清理空闲 主循环根据空闲情况装载下一帧 static void low_task_uart_process(void) { switch (uart_state) { case UART_IDLE: if (uart_tx_cnt == 0) { if (uart_tx_cnt_max > uart_tx_cnt_interval) { uart_tx_cnt_max = 0; deQueue(); uart_tx_cnt = uart_tx_buf_len; } } else { //HAL_UART_Transmit(&huart1,&uart_tx_buf[uart_tx_cnt-1],1,0xffff); USART1->DR = uart_tx_buf[uart_tx_cnt-1]; uart_tx_cnt--; uart_state = UART_TX_BUSY; } break; case UART_TX_BUSY: // 发送中断处理 break; default: break; } // if(tx_busy) { tx_busy = 0; tx_buffer[uart_tx_cnt] = 0xAA; HAL_UART_Transmit_DMA(&huart1, (uint8_t*)&tx_buffer, 1); } } typedef struct { queue_buff queue_len } void uart_send_data(void) { if queue_empty() && tx_state == IDLE // 队列为空 且无间隔需要等待提前结束 tx_count != 0 return; // 空闲退出 if tx_state == BUSY return; // 忙碌中 if tx_state == INTERVAL if (uint32_t)(get_tick_ms() - last_tx_tick) < 帧间间隔 // 间隔时间未到 用无符号减法不会有溢出的可能 return; // 未到间隔时间 else // 延迟达标进入空闲状态 tx_state = IDLE; // 准备下一帧 构建帧 // tx_count -= 帧长度; if HAL_UART_Transmit_IT() == HAL_OK //启动串口发送成功 tx_state = BUSY else tx_state = INTERVAL //丢弃帧或重发当前帧 // uart_send_error(); } uint32_t last_tx_tick = 0; void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 一帧发送完成,进入帧间隔等待状态 tx_state = INTERVAL; last_tx_tick = HAL_GetTick(); // 记录完成时刻 } } static void high_task_display_and_uart(void) { static uint8_t cnt = 0; cnt++; if(cnt == 100 / HIGH_FREQ_INTERVAL_MS)// 需要延迟的时间 / 当前时间片速度 = 10 { cnt = 0; display_refresh(); } if(get_tick_ms() - last_time < 100) { return; } else { last_time = get_tick_ms(); } } static void med_task_adc(void) { } void tasks_register(void) { high_tasks[0].func = high_task_display_and_uart; high_tasks[0].enable = 1;// 可根据需要使能或禁能 禁用后任务挂起 med_tasks[0].func = med_task_adc; med_tasks[0].enable = 1; low_tasks[0].func = low_task_uart_process; low_tasks[0].enable = 1; } /* 初始化任务数组(示例) */ void tasks_init(void) { // 将所有任务置空 for (int i = 0; i < HIGH_TASK_NUM; i++) { high_tasks[i].func = NULL; high_tasks[i].enable = 0; } for (int i = 0; i < MED_TASK_NUM; i++) { med_tasks[i].func = NULL; med_tasks[i].enable = 0; } for (int i = 0; i < LOW_TASK_NUM; i++) { low_tasks[i].func = NULL; low_tasks[i].enable = 0; } // 注册实际任务 tasks_register(); } /* 注册任务函数(可封装成接口) */ void register_high_task(uint8_t index, void (*task_func)(void)) { if (index < HIGH_TASK_NUM) { high_tasks[index].func = task_func; high_tasks[index].enable = 1; // 默认使能 } } // 类似可注册中、低频任务... /* 高频任务处理 */ static void task_high_handler(void) { for (int i = 0; i < HIGH_TASK_NUM; i++) { if (high_tasks[i].enable && high_tasks[i].func != NULL) { high_tasks[i].func(); // 执行高频任务 } } } /* 中频任务处理 */ static void task_med_handler(void) { for (int i = 0; i < MED_TASK_NUM; i++) { if (med_tasks[i].enable && med_tasks[i].func != NULL) { med_tasks[i].func(); } } } /* 低频任务处理 */ static void task_low_handler(void) { for (int i = 0; i < LOW_TASK_NUM; i++) { if (low_tasks[i].enable && low_tasks[i].func != NULL) { low_tasks[i].func(); } } } /* 设备初始化(示例) */ void dev_init(void) { // 初始化硬件、外设等 tasks_init(); // 初始化任务表 // 启动定时器中断等 } void dev_deinit(void) { } /* 进入低功耗模式(示例) */ void enter_low_power(void) { // 可在此处关闭不必要的时钟,进入睡眠模式 // 等待中断唤醒(如1ms滴答) // HAL_SuspendTick(); __WFI(); // 以ARM Cortex-M为例 } /* 1ms 定时器中断服务程序 */ void SysTick_Handler(void) // 假设使用SysTick void HAL_IncTick(void) { static uint32_t high_cnt = 0; static uint32_t med_cnt = 0; static uint32_t low_cnt = 0; // uwTick += uwTickFreq; system_tick++; // 高频计数 if (++high_cnt >= HIGH_FREQ_INTERVAL_MS) { high_cnt = 0; high_flag = 1; } // 中频计数 if (++med_cnt >= MED_FREQ_INTERVAL_MS) { med_cnt = 0; med_flag = 1; } // 低频计数 if (++low_cnt >= LOW_FREQ_INTERVAL_MS) { low_cnt = 0; low_flag = 1; } } uint32_t get_tick_ms(void) { #if 1 uint32_t tick; __disable_irq(); tick = system_tick; __enable_irq(); return tick; #else return xTaskGetTickCount() * portTICK_PERIOD_MS; #endif } /* 主函数 */ int main(void) { __disable_irq(); uint8_t system_state = 0; while (1) { switch (system_state) { case INIT: // 初始化 __disable_irq(); dev_init(); __enable_irq(); system_state = RUNNING; // 初始化完成后进入运行态 break; case RUNNING: // 运行态 // 按优先级处理任务(高频最优先,可调顺序) if (high_flag) { high_flag = 0; task_high_handler(); } else if (med_flag) { med_flag = 0; task_med_handler(); } else if (low_flag) { low_flag = 0; task_low_handler(); } #if LOW_POWER_MODE // 若无任务需要立即执行,可进入低功耗(可选) if (high_flag == 0 && med_flag == 0 && low_flag == 0) { // 切换到低功耗态,等待中断唤醒 system_state = SLEEP; } #endif break; case SLEEP: // 低功耗态 dev_deinit(); // 关闭硬件、外设等 enter_low_power();// 中断进入唤醒时间 // 唤醒后进入唤醒态 if (wakeup_irq_flag) wakeup_irq_flag = 0; // 清除标志 wakeup_start_tick = HAL_GetTick(); HAL_ResumeTick(); system_state = WAKEUP; // 进入唤醒态 break; case WAKEUP: // 唤醒态 { static uint32_t last_scan = 0; uint32_t now = HAL_GetTick(); if (now - last_scan >= KEY_SCAN_INTERVAL_MS) { last_scan = now; if (key_pressed()) { // 按键仍按下 if (now - wakeup_start_tick >= LONG_PRESS_MS) { // 长按时间达到,正式唤醒 sys_state = INIT; // 可以在这里做一些初始化或者恢复任务 } // 否则继续等待 } else { // 按键已释放,未达到长按时间,返回低功耗 sys_state = SLEEP; } } break; } default: // 错误状态,退出 break; } } } ```