在C语言里,任务调度指的是对多个任务(也被叫做线程或者进程)的执行顺序进行管理,以此来达成高效利用系统资源的目的。
下面为你详细介绍任务调度的相关概念和实现方法。
一:任务调度的概念思想:
抢占式调度:在这种调度方式下,操作系统能够依据任务优先级,强行暂停当前正在执行的任务,转而执行其他任务。
非抢占式调度:采用这种调度方式时,任务只有在主动放弃 CPU 控制权的情况下,其他任务才有机会执行。
实时调度:实时调度的核心是保证任务能在严格的时间限制内完成,它又可以细分为硬实时调度和软实时调度。
优先级调度:优先级调度会为每个任务分配一个优先级,系统会优先执行优先级较高的任务。
二:任务调度的关键要点
上下文切换:在任务切换时,需要保存当前任务的状态(例如寄存器值),并恢复下一个任务的状态。
临界区保护:对于共享资源,要使用互斥锁、信号量等机制来避免竞态条件。
任务同步:可以通过信号量、事件标志组等方式实现任务间的同步。
堆栈管理:每个任务都有自己独立的堆栈,必须确保堆栈大小足够,防止溢出。
常用的任务调用有Free Rtos,OS,RT-threard等等实时操作系统专为嵌入式系统设计,提供了强大的任务调度功能,
这里和大家分享一个简单任务调度器。创建任务队列。然后按照一定时间间隔来处理任务。
三:任务调度使用的是 定时器0进行控制
3.1 FSP库配置:
四:代码编写:
4.1 底层驱动代码如下,可以移植到其他架构的平台
char Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]); //======================================================================== // 函数: Task_Handler_Callback // 描述: 任务标记回调函数. // 参数: None. // 返回: None. // 版本: V1.0, 2025-07-09 //======================================================================== void Task_Marks_Handler_Callback(void) { char i; for(i=0; i<Tasks_Max; i++) { if(Task_Comps[i].TIMCount) /* If the time is not 0 */ { Task_Comps[i].TIMCount--; /* Time counter decrement */ if(Task_Comps[i].TIMCount == 0) /* If time arrives */ { /*Resume the timer value and try again */ Task_Comps[i].TIMCount = Task_Comps[i].TRITime; Task_Comps[i].Run = 1; /* The task can be run */ } } } } //======================================================================== // 函数: Task_Pro_Handler_Callback // 描述: 任务处理回调函数. // 参数: None. // 返回: None. // 版本: V1.0, 2025-07-09 //======================================================================== void Task_Pro_Handler_Callback(void) { char i; for(i=0; i<Tasks_Max; i++) { if(Task_Comps[i].Run) /* If task can be run */ { Task_Comps[i].Run = 0; /* Flag clear 0 */ Task_Comps[i].TaskHook(); /* Run task */ } } }
4.2 任务如下:
//======================================================================== // 函数: void task_1000ms(void) // 描述: 1000ms 任务. // 参数: None. // 返回: None. // 版本: V1.0, 2025-07-09 //======================================================================== void task_1000ms(void) { printf("EEPW world test printf!\n"); } //======================================================================== // 函数: void task_100ms(void) // 描述: 100 任务. // 参数: None. // 返回: None. // 版本: V1.0, 2025-07-09 //======================================================================== int flag = 0 ; void task_100ms(void) { if(flag ==0) { flag =1 ; R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_LOW); } else { flag =0 ; R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH); } } //======================================================================== // 函数: TASK_COMPONENTS // 描述: 添加任务列表 // 参数: None. // 返回: None. // 版本: V1.0, 2025-07-09 //======================================================================== static TASK_COMPONENTS Task_Comps[]= { {0, 1000,1000, task_1000ms}, //task 1 Period: 1000ms {0, 100,100, task_100ms}, //task 2 Period: 500ms };
4.3 修改程序代码如下:
/*******************************************************************************************************************//** * @brief This function is callback for 16-bit counter TML. * @param[in] p_args * @retval None **********************************************************************************************************************/ void g_timer0_callback(timer_callback_args_t *p_args) { if (TIMER_EVENT_CYCLE_END == p_args->event) { Task_Marks_Handler_Callback(); } }
void hal_entry(void) { /* TODO: add your own code here */ g_uart0_init() R_TAU_Time0ing_Init(); while(1) { Task_Pro_Handler_Callback(); } #if BSP_TZ_SECURE_BUILD /* Enter non-secure code */ R_BSP_NonSecureEnter(); #endif