版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、温州大学物理与电子信息工程学院 杨卫波嵌入式系统原理与应用第11章 任务管理11.1 单任务系统p裸机编程主要是采用超级循环(super-loops)系统,又称前后台系统。p应用程序是一个无限的循环,循环中调用相应的函数完成相应的操作,这部分可以看做后台行为,中断服务程序处理异步事件,这部分可以看做是前台行为。11.1.1 查询方式p处理器查询数据或者消息是否就绪,就绪后进行处理,然后再等待,如此循环下去。p处理简单的应用,效果比较好,但是随着工程的复杂,采用查询方式实现的工程就变的很难维护,同时由于无法定义查询任务的优先级,这种查询方式会使得重要的接口消息得不到及时响应。11.1.2 中断方
2、式p必须在中断(ISR)内处理时间关键运算;p超级循环和ISR之间的数据交换是通过全局共享变量进行的;p超级循环使得应用程序变得非常复杂,因此难以扩展。11.2 多任务系统p调度器的作用就是使用相关的调度算法调度算法来决定当前需要执行的任务;p这里所说的多任务系统同一时刻只能有一个任务可以运行,只是通过调度器的决策,看起来像所有任务同时运行一样。多任务系统运行过程运行条件如下: p使用抢占式调度器p1个空闲任务,优先级最低p2个应用任务,一个高优先级和一个低优先级,优先级都比空闲任务优先级高p中断服务程序含USB 中断、串口中断和系统滴答定时器中断11.3.1 任务设置RTX 操作系统的配置工
3、作是通过配置文件 RTX_Conf_CM.c 实现11.3.2 任务栈设置不管是裸机编程还是RTOS编程,局部变量、函数调时现场保护和返回地址、函数的形参、进入中断函数前和中断嵌套等都需要栈空间,栈空间定义小了会造成系统崩溃。 裸机的情况下,用户可以在这里配置栈大小:任务栈设置在RTOS下,每个任务都有自己的栈空间。任务的栈大小可以在配置向导中通过如下参数进行配置:11.3.3 系统栈设置pRTOS下图中设置的栈有一个新的名字叫系统栈空间系统栈空间,任务栈不使用这里的栈空间,使用这里的栈空间的是中断函数和中断嵌套。pCortex-M3内核具有双堆栈指针,在RTX操作系统中,主堆栈指针主堆栈指针
4、MSPMSP是给系统栈空间使用的,进程堆栈指针进程堆栈指针PSPPSP是给任务栈使用的。11.3.5 RTX初始化和启动voidvoid os_sys_init_user( os_sys_init_user(voidvoid( (* *task)(task)(voidvoid),),/ /* * 任务函数 */U8 priority, U8 priority, / /* * 任务优先级 (1-254) */voidvoid* * stack, stack, / /* * 任务栈地址 */U16 size); U16 size); / /* * 任务栈大小,单位字节*/ 函数描述:实现RTX的初
5、始化和启动任务的创建,并且使用这个函数做初始化还可以自定义任务栈的大小。 注意:1)优先级0用于空闲任务,如果将其设置为0,RTX会将其更改为1。优先级255被保留用于最重要的任务。优先级参数中数值越小优先级越低,也就是说空闲任务的优先级是最低的。 2)必须在main函数中调用os_sys_init_useros_sys_init_user; 3)任务栈空间必须 8 字节对齐。举例staticstatic uint64_t uint64_t AppTaskStartStkAppTaskStartStk512/8; 512/8; / /* * 任务栈任务栈 * */ /intint main(
6、main(voidvoid) ) / /* * RTX RTX初始化并创建启动任务初始化并创建启动任务 */os_sys_init_useros_sys_init_user( (AppTaskStartAppTaskStart, , / /* * 任务函数任务函数 */ 4, 4, / /* * 任务优先级任务优先级 */ & &AppTaskStartStkAppTaskStartStk, ,/ /* * 任务栈任务栈 */ sizeofsizeof( (AppTaskStartStkAppTaskStartStk); ); / /* * 任务栈大小,单位字节数任务栈大小,单位字节数 */
7、while while (1); (1); 11.3.6 任务创建OS_TID os_tsk_create_user(OS_TID os_tsk_create_user(voidvoid( (* *task)(task)(voidvoid), ), / /* * 任务函数 */U8 priority, U8 priority, / /* * 任务优先级 (1-254) */voidvoid* * stk, stk, / /* * 任务栈*/U16 size); U16 size); / /* * 任务栈大小*/函数描述:实现RTX任务创建,还可以自定义任务栈的大小。 注意:1)如果新创建的任务
8、优先级比当前正在执行任务的优先级高,那么就会立即切换到高优先级任务去执行; 2)函数的返回值是任务的ID,使用ID号可以区分不同的任务。 3)任务栈空间必须8字节对齐,可将任务栈数组定义成uint64_tuint64_t类型即可。举例staticstatic uint64_t AppTaskUserIFStk512 / 8; uint64_t AppTaskUserIFStk512 / 8; / /* * 任务栈 */OS_TID HandleTaskUserIF = NULL;OS_TID HandleTaskUserIF = NULL; / /* * 任务句柄 */staticstatic
9、 voidvoid AppTaskCreate( AppTaskCreate(voidvoid) ) HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, / /* * 任务函数 */ 1, 1, / /* * 任务优先级 */ &AppTaskUserIFStk, &AppTaskUserIFStk, / /* * 任务栈 */ sizeofsizeof(AppTaskUserIFStk); (AppTaskUserIFStk); ty
10、pedef unsigned int U32;typedef U32 OS_TID;11.3.7 任务删除OS_RESULT os_tsk_delete (OS_TID task_id); OS_RESULT os_tsk_delete (OS_TID task_id); /* 任务ID */ 函数描述:实现RTX操作系统的任务删除。如果任务删除成功,函数返回OS_R_OKOS_R_OK,其余情况返回 OS_R_NOKOS_R_NOK,比如所写的任务ID不存在。注意:如果用往此函数里面填的任务ID是 0 的话,那么删除的就是当前正在执行的任务,此任务被删除后,RTX会切换到任务就绪列表里面下一
11、个要执行的高优先级任务。任务删除例子staticstatic uint64_t uint64_t AppTaskUserIFStkAppTaskUserIFStk512 / 8; 512 / 8; / /* * 任务栈任务栈 */OS_TID OS_TID HandleTaskUserIFHandleTaskUserIF = NULL; = NULL;staticstatic voidvoid AppTaskDeleteAppTaskDelete( (voidvoid) ) HandleTaskUserIFHandleTaskUserIF = = os_tsk_create_useros_ts
12、k_create_user(AppTaskUserIF, (AppTaskUserIF, / /* * 任务函数任务函数 */1, 1, / /* * 任务优先级任务优先级 */& &AppTaskUserIFStkAppTaskUserIFStk, , / /* * 任务栈任务栈 */sizeofsizeof( (AppTaskUserIFStkAppTaskUserIFStk); ); / /* * 任务栈大小任务栈大小*/ifif ( (HandleTaskUserIFHandleTaskUserIF != NULL) != NULL) ifif ( (os_tsk_deleteos_t
13、sk_delete( (HandleTaskUserIFHandleTaskUserIF) = OS_R_OK) = OS_R_OK) HandleTaskUserIFHandleTaskUserIF = NULL; = NULL;printf(printf( 任务任务HandleTaskUserIF删除成功删除成功rn);); elseelse printfprintf( ( 任务任务HandleTaskUserIF删除失败删除失败rn); ); 11.3.8 空闲任务几乎所有的小型RTOS中都有一个空闲任务,空闲任务应该属于系统任务,是必须要执行的,用户程序不能将其关闭。比如WIN7中有空
14、闲任务,空闲任务主要有以下几个作用作用: p不能让系统一直在执行各个应用任务,这样系统利用率就是100%,系统就会一直的超负荷运行,所以空闲任务很有必要。p为了更好的实现低功耗,用户可以在空闲任务中实现睡眠,停机等低功耗措施。空闲任务RTX 的空闲任务在文件RTX_Conf_CM.c 里面,源代码如下: / /* *- os_idle_demon - os_idle_demon -* */ /_task _task voidvoid os_idle_demon( os_idle_demon(voidvoid) ) / /* * The idle demon is a system task,
15、running when no other task is ready The idle demon is a system task, running when no other task is ready to run. The os_xxx function calls are not allowed from this task. to run. The os_xxx function calls are not allowed from this task. * */ /forfor (;) (;) / /* * HERE: include optional user code to
16、 be executed when no task HERE: include optional user code to be executed when no task runs. runs.* */ / 11.3.9 例程说明目的:目的: 学习 RTX 的任务创建和删除。内容:内容: 1. K1 按键按下,串口打印。 2. K2 按键按下,删除任务 AppTaskLED。 3. K3 按键按下,重新创建任务 AppTaskLED。 4. 各个任务实现的功能如下: AppTaskUserIF 任务 :按键消息处理。 AppTaskLED 任务 :LED 闪烁。 AppTaskMsgPro
17、任务 :消息处理,用作 LED 闪烁。 AppTaskStart 任务:启动任务,最高优先级最高优先级任务,实现按键扫描。 RTX 配置应用实例RTX RTX 初始化:初始化:intint main( main(voidvoid) ) bsp_Initbsp_Init();(); / /* * 初始化外设初始化外设 */ /* * 创建启动任务创建启动任务 */os_sys_init_useros_sys_init_user( (AppTaskStartAppTaskStart, , / /* * 任务函数任务函数 */ 4, 4, / /* * 任务优先级任务优先级 */ & &AppTas
18、kStartStkAppTaskStartStk, , / /* * 任务栈 */ sizeofsizeof( (AppTaskStartStkAppTaskStartStk); ); / /* * 任务栈大小任务栈大小 */ whilewhile (1); (1); static uint64_t AppTaskUserIFStk512/8; static uint64_t AppTaskLEDStk256/8; static uint64_t AppTaskMsgProStk512/8; static uint64_t AppTaskStartStk512/8; 应用实例RTX RTX 任
19、务创建:任务创建:staticstatic voidvoid AppTaskCreateAppTaskCreate( (voidvoid) ) HandleTaskUserIFHandleTaskUserIF = = os_tsk_create_useros_tsk_create_user(AppTaskUserIF,(AppTaskUserIF, 1, 1, / /* * 任务优先级任务优先级 */ & &AppTaskUserIFStkAppTaskUserIFStk, , / /* * 任务栈任务栈 */ sizeofsizeof( (AppTaskUserIFStkAppTaskUse
20、rIFStk); ); HandleTaskLEDHandleTaskLED = = os_tsk_create_useros_tsk_create_user( (AppTaskLEDAppTaskLED, , 2, 2, / /* * 任务优先级任务优先级 */ & &AppTaskLEDStkAppTaskLEDStk, , / /* * 任务栈任务栈 */ sizeofsizeof( (AppTaskLEDStkAppTaskLEDStk); ); HandleTaskMsgProHandleTaskMsgPro = = os_tsk_create_useros_tsk_create_u
21、ser( (AppTaskMsgProAppTaskMsgPro, , 3, 3,/ /* * 任务优先级任务优先级 */ & &AppTaskMsgProStkAppTaskMsgProStk, , / /* * 任务栈任务栈 */ sizeofsizeof( (AppTaskMsgProStkAppTaskMsgProStk); ); RTX 任务调试信息思考题1:30嵌入式系统原理与应用24用用RTX实现:实现: 按下按下Key1时,时, LED每每1s闪烁闪烁5次,再次按下次,再次按下Key1时,时,LED停止闪烁;依次循环停止闪烁;依次循环。#include#include incl
22、udes.hincludes.h staticstatic uint64_t uint64_t AppTaskStartStkAppTaskStartStk512/8; 512/8; / /* * 任务栈任务栈 * */ /staticstatic uint64_t uint64_t AppTaskKEYStkAppTaskKEYStk256/8; 256/8; / /* * 任务栈任务栈 * */ /_task _task voidvoid AppTaskKEYAppTaskKEY( (voidvoid) ) whilewhile(1) (1) bsp_KeyScanbsp_KeyScan(
23、);();os_dly_waitos_dly_wait(10);(10); _task _task voidvoid AppTaskStartAppTaskStart( (voidvoid) ) uint8_t uint8_t ucKeyCodeucKeyCode, , bLedTogglebLedToggle = 1; = 1;os_tsk_create_useros_tsk_create_user( (AppTaskKEYAppTaskKEY, 2, &, 2, &AppTaskKEYStkAppTaskKEYStk, , sizeofsizeof( (AppTaskKEYStkAppTa
24、skKEYStk););whilewhile(1) (1) ucKeyCodeucKeyCode = = bsp_GetKeybsp_GetKey();();ifif ( (ucKeyCodeucKeyCode = KEY_DOWN_K1) = KEY_DOWN_K1)bLedTogglebLedToggle = 1 - = 1 - bLedTogglebLedToggle; ; ifif( (bLedTogglebLedToggle = 1) = 1)bsp_LedTogglebsp_LedToggle(1);(1); os_dly_waitos_dly_wait(100);(100); i
25、ntint main ( main (voidvoid) ) bsp_Initbsp_Init();();os_sys_init_useros_sys_init_user ( (AppTaskStartAppTaskStart, 4, &, 4, &AppTaskStartStk,AppTaskStartStk,sizeofsizeof( (AppTaskStartStkAppTaskStartStk); ); whilewhile(1);(1); RTX内核分析p 进程是对一个运行单元的抽象,主要包括内存(code,data,heap和stack),CPU状态(PC,SP和寄存器值等)与其他
26、OS管理相关的内容。进程是一个运行中的程序。在RTX中一个task就是一个进程。p 一般有一个进程控制块(Process control block,PCB),用于记录进程的相关信息。RTX中这个控制块叫做task control block(TCBTCB),是一个结构体,其中的成员记录了关于该task的信息,其定义在rt_TypeDef.h中。RTX任务控制块typedeftypedef structstruct OS_TCB OS_TCB / /* * General part: identical for all implementations. General part: identi
27、cal for all implementations. * */ /U8 cb_type; U8 cb_type; / /* *内存块内存块IDID号,号,RTXRTX链表操作非常灵活性,传递参数时多用链表操作非常灵活性,传递参数时多用OS_XCBOS_XCB类型指针类型指针 * */ /U8 state; U8 state; / /* * 任务状态任务状态* */ /U8 prio; U8 prio; / /* * 优先级,优先级,RTXRTX的互斥量使用优先级继承,此为继承后优先级的互斥量使用优先级继承,此为继承后优先级 * */ /U8 task_id; U8 task_id; / /
28、* *通过通过TIDTID快速访问快速访问TCBTCB,所有激活任务都注册到任务数组中,所有激活任务都注册到任务数组中,TIDTID就是下标就是下标 * */ /structstruct OS_TCBOS_TCB * *p_lnk; p_lnk; / /* * 互斥量、信号量、邮箱等待双向链表下个节点指针;就绪任务单链表下个节点指针;互斥量、信号量、邮箱等待双向链表下个节点指针;就绪任务单链表下个节点指针;* */ /structstruct OS_TCBOS_TCB * *p_rlnk; p_rlnk; / /* * 双向链表中的上个节点指针双向链表中的上个节点指针 * */ /struct
29、struct OS_TCBOS_TCB * *p_dlnk; p_dlnk; / /* * 延时任务双向链表,下个节点指针延时任务双向链表,下个节点指针 * */ / structstruct OS_TCBOS_TCB * *p_blnk; p_blnk; / /* * 上个节点指针上个节点指针 * */ / U16 delta_time; U16 delta_time; / /* * 任务延时时,如任务延时时,如4 4任务延时任务延时1010、9090、9090、120120后,各任务的后,各任务的delta_timedelta_time为:为:0 0,8080,0 0,3030* */ /
30、 U16 interval_time; U16 interval_time; / /* * 区间延时,为周期性延时用区间延时,为周期性延时用 * */ /U16 events; U16 events; / /* *TCBTCB的事件标志,每个任务有的事件标志,每个任务有1616个事件标志个事件标志 * */ /U16 waits; U16 waits; / /* * 等待事件被阻塞时,暂存此处;事件或等待成功时保存实际等待到的事件等待事件被阻塞时,暂存此处;事件或等待成功时保存实际等待到的事件 * */ /voidvoid * * *msg; msg; / /* *邮箱操作阻塞时,暂存接收或发
31、送消息的地址邮箱操作阻塞时,暂存接收或发送消息的地址 * */ / structstruct OS_MUCBOS_MUCB * *p_mlnk; p_mlnk; / /* * 任务拥有的互斥量链表头节点任务拥有的互斥量链表头节点 * */ /U8 prio_base; U8 prio_base; / /* *基本优先级,未继承前的优先级基本优先级,未继承前的优先级 * */ / U8 ret_val; U8 ret_val; / /* *任务被同步量阻塞时,同时进入同步量等待链表和延时等待链表,此处指示应用程序从哪个任务被同步量阻塞时,同时进入同步量等待链表和延时等待链表,此处指示应用程序从哪
32、个 等待链表返回等待链表返回 * */ / /* * Hardware dependant part: specific for CM processor Hardware dependant part: specific for CM processor* */ /U8 ret_upd; U8 ret_upd; / /* * 返回值更新标记,替换返回值更新标记,替换R0R0值为值为ret_val ret_val * */ /U16 priv_stack; U16 priv_stack; / /* * 仅在任务初始化时指示是否使用自定义栈仅在任务初始化时指示是否使用自定义栈* */ / U32
33、 tsk_stack; U32 tsk_stack; / /* * (R13) (R13)任务任务SPSP保存在此处保存在此处* */ /U32 U32 * *stack; stack; / /* * 任务栈的基址任务栈的基址 * */ /FUNCP ptask; FUNCP ptask; / /* * 任务入口任务入口* */ / * *P_TCB;P_TCB;Task States in RTX Kernel1:30嵌入式系统原理与应用29RTX中的各种链表1:30嵌入式系统原理与应用30RTX系统服务实现RTX进程创建的源代码OS_TID rt_tsk_create (FUNCP OS_
34、TID rt_tsk_create (FUNCP tasktask, U32 , U32 prio_stkszprio_stksz, , voidvoid * *stkstk, , voidvoid * *argvargv) ) / /* * Start a new task declared with task. Start a new task declared with task. * */ / P_TCB task_context; P_TCB task_context; U32 i; U32 i; ifif ( (prio_stkszprio_stksz & 0 xFF) = 0)
35、& 0 xFF) = 0) / /* * Priority 0 is reserved for idle task! Priority 0 is reserved for idle task! * */ / prio_stkszprio_stksz += 1; += 1; task_context = rt_alloc_box (mp_tcb); task_context = rt_alloc_box (mp_tcb); ifif (task_context = NULL) (task_context = NULL) returnreturn (0); (0); / /* * If size
36、!= 0 use a private user provided stack. If size != 0 use a private user provided stack. * */ / task_context-stack = task_context-stack = stkstk; ; task_context-priv_stack = task_context-priv_stack = prio_stkszprio_stksz 8; 8; / /* * Pass parameter argv to rt_init_context Pass parameter argv to rt_in
37、it_context * */ / task_context-msg = task_context-msg = argvargv; ; / /* * For size = 0 system allocates the user stack from the memory pool. For size = 0 system allocates the user stack from the memory pool. * */ / rt_init_context (task_context, rt_init_context (task_context, prio_stkszprio_stksz &
38、 0 xFF, & 0 xFF, tasktask);); / /* * Find a free entry in os_active_TCB table. Find a free entry in os_active_TCB table. * */ / i = rt_get_TID (); i = rt_get_TID (); os_active_TCBi-1 = task_context; os_active_TCBi-1 = task_context; task_context-task_id = i; task_context-task_id = i; DBG_TASK_NOTIFY(
39、task_context, _TRUE); DBG_TASK_NOTIFY(task_context, _TRUE); rt_dispatch (task_context); rt_dispatch (task_context); os_tsk.run-ret_val = i; os_tsk.run-ret_val = i; returnreturn (OS_TID)i); (OS_TID)i); 基本就是填TCB,分配内存空间,确定优先级和排程相关设置等。11.4 任务优先级修改RTX操作系统任务优先级的设置要注意以下几个问题: 1)设置任务的优先级时,数值越小优先级越低。2)最低任务优先级
40、是0,此优先级被空闲任务使用,任何其它任务都不可以使用。3)用户可设置的优先级范围是1-254,由于RTX支持时间片调度,也支持用户任务设置为相同的优先级。4)优先级255被保留,用于最重要的任务。11.4.2 任务优先级分配方案RTXRTX有一个任务优先级推荐的设置标准:有一个任务优先级推荐的设置标准:u IRQ任务:通过中断服务程序进行触发的任务,应设置为优先级最高的。u 高优先级后台任务:如按键检测、USB消息处理、串口消息处理等。u 低优先级的时间片调度任务:如界面显示、LED显示等不需要实时执行的都可以归为这一类任务。u 空闲任务:空闲任务是系统任务。u 特别注意:IRQ任务和高优先
41、级任务必须设置为阻塞式(调用消息等待或者延迟等函数),只有这样高优先级任务才会释放CPU的使用权,低优先级任务才有机会得到执行。RTX的优先度p RTX并不能处理快速中断,相反地当快速中断发生时,RTX内核可能会被打断。p 普通中断并不是一个进程,所以不需要设定优先度,但普通中断一定会打断进程。p 每一个优先级都有一个先入先出的队列结构;进程会按照先入先出的顺序运行。低优先度的进程不能打断高优先度的进程,但高优先度的进程会打断低优先度的进程。如果当前最高优先度是x,但所有优先度为x的进程都处于等待状态,那么排程器就会考虑下一优先度(x-1)的进程,但一旦任一x进程进入就绪状态,排程器会打断低优
42、先度进程。RTX的优先度p 优先度为0的进程为空闲进程。当没有进程执行时,RTX会执行它,并提升其优先度到1;p 几个特殊进程的优先度:os_idle_demon(void) 的优先度永远为0,RTX实在没进程可跑才会运行这个进程;os_error (U32 err_code)的优先度永远为255,用于处理错误的。这两个进程原型都在RTX_CONFIG.C文件中。1:30嵌入式系统原理与应用36RTX中断处理下图显示了RTX中断处理的过程,IRQ中断函数可以发送信号或消息启动一个更高优先级的任务。11.4.3 任务优先级设置OS_RESULT os_tsk_prio( OS_TID task_
43、id, /* 任务ID */ U8 new_prio); /* 新的任务优先级 (1-254) */函数描述函数描述:用于修改任务的优先级。 p 第1个参数如是0,那么设置就是当前任务的优先级。p 如果new_prio的数值比当前执行任务的优先级大,将触发一次任务切换,切换到任务ID为task_id的任务中。如果new_pro的数值比当前执行任务的优先级小,当前任务会继续执行。p 如果任务优先级修改成功,函数返回 OS_R_OK,其余情况返回 OS_R_NOK,比如所写的任务ID不存在或者任务还没有启动。p 被修改任务的新优先级会一直保持有效直到用户再次修改。使用举例staticstatic
44、uint64_t AppTaskUserIFStk512 / 8; uint64_t AppTaskUserIFStk512 / 8; / /* * 任务栈 */OS_TID HandleTaskUserIF = NULL;OS_TID HandleTaskUserIF = NULL; / /* * 任务句柄 */staticstatic voidvoid AppTaskDelete( AppTaskDelete(voidvoid) ) HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, HandleTaskUserIF = os_tsk_
45、create_user(AppTaskUserIF, / /* * 任务函数 */1, 1, / /* * 任务优先级 */&AppTaskUserIFStk, &AppTaskUserIFStk, / /* * 任务栈 */sizeofsizeof(AppTaskUserIFStk); (AppTaskUserIFStk); / /* * 任务栈大小,单位字节数 */ ifif (os_tsk_prio(HandleTaskLED, 3) = OS_R_OK) (os_tsk_prio(HandleTaskLED, 3) = OS_R_OK) printf(printf( 任务AppTask
46、LED优先级修改成功rn);); elseelse printf(printf( 任务AppTaskLED优先级修改失败rn);); 11.4.4 例程说明内容: 1. K1 按键按下,串口打印。2. K2 按键按下,将任务 AppTaskLED 的优先级由 2 修改为 3。3. k3 按键按下,将任务 AppTaskLED 的优先级由 3 修改为 2。4. 各个任务实现的功能如下: AppTaskUserIF 任务:按键消息处理。 AppTaskLED 任务:LED 闪烁。 AppTaskMsgPro 任务:消息处理,用作 LED 闪烁。 AppTaskStart 任务:启动任务,也是最高优
47、先级任务,这里实现按键扫描。 RTX 配置RTX 配置任务栈大小分配:static uint64_t AppTaskUserIFStk512/8; /* 任务栈 */ static uint64_t AppTaskLEDStk256/8; /* 任务栈 */ static uint64_t AppTaskMsgProStk512/8; /* 任务栈 */ static uint64_t AppTaskStartStk512/8; /* 任务栈 */系统栈大小分配RTX 任务调试信息11.5 任务调度p调度器就是使用相关的调度算法来决定当前需要执行的任务。所有的调度器有一个共同的特性:调度器可以
48、区分就绪态任务和挂起任务。p调度器可以选择就绪态中的一个任务,然后激活它(通过执行这个任务)。不同调度器之间最大的区别就是如何分配就绪态任务间的完成时间。p嵌入式实时操作系统的核心就是调度器和任务切换,调度器的核心就是调度算法。11.5.1 RTX 支持的调度方式RTX操作系统支持三种调度方式: p 抢占式调度:每个任务都有不同不同的优先级,任务会一直运行直到被高优先级任务抢占或遇到阻塞式的API函数,如 os_dly_waitos_dly_wait。p 时间片调度:每个任务都有相同相同的优先级,任务会运行固定的时间片个数直到遇到系统阻塞式的API函数,如os_dly_waitos_dly_w
49、ait。p 合作式调度:每个任务都有相同的优先级,而且时间片调度要被禁止。任务会一直的运行直到遇到阻塞式的API函数,如 os_dly_waitos_dly_wait或者用户调用函数os_tsk_passos_tsk_pass。对于RTX操作系统而言,实际应用主要是抢占式调度和时间片调度,合作式调度用到的很少。11.5.2 抢占式调度器p 在实际的应用中,不同的任务需要不同的响应时间。如在一个应用中需要使用电机、键盘和 LCD 显示。电机比键盘和 LCD 需要更快速的响应,如果我们使用合作式调度器或者时间片调度,那么电机将无法得到及时的响应,这时抢占式调度是必须的。 p 如果使用了抢占式调度,
50、最高优先级的任务一旦就绪,总能得到 CPU 的控制权。当一个运行着的任务被其它高优先级的任务抢占,当前任务的 CPU 使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了 CPU 的控制权。抢占式调度器p 如果是中断服务程序使一个高优先级的任务进入就绪态,中断完成时,被中断的任务被挂起,优先级高的任务开始运行。 p 使用抢占式调度器,使得最高优先级的任务什么时候可以执行,可以得到 CPU 的控制权是可知的,同时使得任务级响应时间得以最优化。 p 总的来说,学习抢占式调度掌握最关键的一点是:抢占式调度器会为每个任务都分配一个优先级,调度器会激活就绪任务中优先级最高的任务,并运行任务就绪
51、列表里面优先级最高的那个任务。RTX 抢占式调度器的实现如禁止使用时间片调度,每个任务必须配置不同的优先级。多任务启动后: p首先执行的最高优先级的任务Task1,Task1会一直运行直到遇到系统阻塞式的API函数,比如延迟、事件标志等待、信号量等待,Task1任务会被挂起,也就是释放CPU的执行权,让低优先级的任务得到执行。pRTX 操作系统继续执行任务就绪列表中下一个最高优先级的任务Task2,执行过程中有两种情况:uTask1延迟时间到,接收到信号量消息等方面的原因,在抢占式调度器的作用下,Task2的执行会被Task1抢占。uTask2会一直运行直到遇到系统阻塞式的API函数,比如延迟
52、,事件标志等待,信号量等待,Task2任务会被挂起,继而执行就绪列表中下一个最高优先级的任务。p根据抢占式调度器,当前的任务要么被高优先级任务抢占,要么通过调用阻塞式API来释放CPU使用权让低优先级任务执行,没有用户任务执行时就执行空闲任务。RTX 抢占式调度器的实现Task1 的优先级为 1,Task2 的优先级为 2,Task3 的优先级为 3。运行过程描述如下: pTask1在运行中,由于Task2就绪,Task2 抢占Task1的执行。Task2 进入到运行态,Task1由运行态进入到就绪态。pTask2在运行中,由于Task3就绪,Task3 抢占Task2的执行。Task3进入到
53、运行态,Task2由运行态进入到就绪态。pTask3运行过程中调用了阻塞式函数,如os_dly_wait,Task3被挂起,查找到下一个要执行的最高优先级任务是Task2,Task2由就绪态进入到运行态。 pTask2在运行中,由于Task3再次就绪,Task3抢占Task2的执行。Task3进入到运行态,Task2由运行态进入到就绪态。11.5.3 时间片调度器 在小型的嵌入式 RTOS 中,最常用的的时间片调度算法就是 Round-robin 调度算法。实现 Round-robin 调度算法需要给同优先级的每个任务分配一个时间片(也就是需要运行的时间长度,时间片用完了就进行任务切换)。pR
54、ound-Robin Task switching选择是否使能时间片调度,选上单选框表示使能时间片调度,取消单选框表示不使用时间片调度。pRound-Robin Timeout ticks 范围 1 1000。表示时间片的大小,单位是系统时钟节拍个数。时间片调度器p创建 4 个同优先级任务 Task1,Task2,Task3 和 Task4。p每个任务分配的时间片大小是 5 个系统时钟节拍。运行过程描述如下: p先运行任务 Task1,运行够 5 个系统时钟节拍后,通过时间片调度切换到任务 Task2。p任务 Task2 运行够 5 个系统时钟节拍后,通过时间片调度切换到任务 Task3。p任
55、务 Task3 在运行期间调用了阻塞式 API 函数,调用函数时,5 个系统时钟节拍的时间片大小还没有用完,此时会通过时间片调度切换到下一个任务 Task4。p任务 Task4 运行够 5 个系统时钟节拍后,通过时间片调度切换到任务 Task1。时间片调度器例程1. K1 按键按下,串口打印。2. 本实验将任务 AppTaskLED 和 AppTaskMsgPro 的优先级都设置为 2,同优先级的任务才会用到时间片调度。3. 时间片调度的使能和每个任务时间片的大小在文件 RTX_Conf_CM.c 文件里面:#define OS_ROBIN 1 /使能时间片调度#define OS_ROBIN
56、TOUT 5 /设置每个同优先级任务的时间片大小。4. 各个任务实现的功能如下:AppTaskUserIF 任务:按键消息处理。AppTaskLED 任务 :LED 闪烁。AppTaskMsgPro 任务:消息处理,这里用作 LED 闪烁。 AppTaskStart 任务:启动任务,最高优先级任务,实现按键扫描。RTX 配置系统栈大小分配RTX任务调试信息11.5.4 合作式调度器 对于同优先级的任务,如果将 RTX 系统配置向导中时间片调度关闭后,这些同优先级的任务就是在合作式调度器的作用下运行。这些同优先级的任务会依次执行,每个任务会一直执行直到遇到阻塞式 API 函数或者函数 os_ts
57、k_pass ()就会切换到下个任务。创建 4 个同优先级任务 Task1,Task2,Task3 和 Task4。运行过程描述如下: p先运行 Task1,然后调用阻塞式 API 切换到 Task2。p Task2 运行,然后调用阻塞式 API 切换到任务 Task3。p Task3 运行,然后调用阻塞式 API 切换到任务 Task4。p任务 Task4 运行,然后调用阻塞式 API 重新切换回任务 Task1。p一直如此循环往复下去。11.5.5 合作式调度器例程1. K1按键按下,串口打印。2. 将任务 AppTaskLED 和 AppTaskMsgPro 的优先级都设置为 2,同优先
58、级的任务才会用到合作式调度。3. 使用合作式调度的话,在 RTX 操作系统的配置向导文件RTX_Conf_CM.c 中禁止时间片调度: #define OS_ROBIN 04. 各个任务实现的功能如下:AppTaskUserIF 任务 :按键消息处理。AppTaskLED 任务:LED 闪烁。AppTaskMsgPro 任务 :消息处理,这里用作 LED 闪烁。 AppTaskStart 任务:启动任务,最高优先级任务,实现按键扫描。RTX 配置RTX 任务调试信息RTX的调度总结1.pre-emptivepre-emptive:每一个进程都有不同的优先级,最高优先级的进程会运行,排程器不会终
59、止它,所以它会运行直到它自行中止挂起(blocked),或者被更高优先级的进程打断。自行挂起的办法就三个:os_tsk_pass(); os_dly_wait(delay_time);和os_itv_wait(void);如果其被中止挂起,其余优先级最高的进程会运行。2.Round robinRound robin:每一个进程的优先级都是相同,每一个进程都会被分配到一个时间片,在运行完这个时间片后,该进程就会加入优先级相同队列的末端,然后队列最前端的进程继续运行。3.Co-operativeCo-operative:这个是所有进程都是相同的优先度且除能了轮转式排程。 在这种合作模式下,进程不会
60、被排程器挂起,只能自己中止。1:30嵌入式系统原理与应用59思考题(不同优先级下的调度)AppTaskUserIF(优先级1)AppTaskStart(优先级4)现象抢占式调度bsp_Delayus(10)os_dly_wait(10)os_dly_wait(10)bsp_Delayus(10)1:30嵌入式系统原理与应用60思考题(不同优先级下的调度)AppTaskUserIF(优先级1)AppTaskStart(优先级4)现象时间片调度bsp_Delayus(10)os_dly_wait(10)os_dly_wait(10)bsp_Delayus(10)1:30嵌入式系统原理与应用61思考
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025江苏泰州市春晖企业管理服务有限公司招聘8人笔试历年常考点试题专练附带答案详解
- 2025山东海洋集团有限公司招聘1人笔试历年备考题库附带答案详解2套试卷
- 2025安徽亳州芜湖投资开发有限责任公司招聘12人笔试历年常考点试题专练附带答案详解2套试卷
- 2025中国人民财产保险股份有限公司西双版纳州分公司招聘5人笔试历年备考题库附带答案详解2套试卷
- 2026年南通师范高等专科学校单招职业倾向性测试题库附答案详解(典型题)
- 2026年南昌健康职业技术学院单招职业适应性测试题库含答案详解(巩固)
- 2026年包头轻工职业技术学院单招职业适应性测试题库附答案详解(研优卷)
- 2026年厦门华厦学院单招职业技能考试题库含答案详解(典型题)
- 2026年南充职业技术学院单招职业倾向性测试题库带答案详解(综合卷)
- 2026年南京交通职业技术学院单招职业倾向性考试题库带答案详解(突破训练)
- 2025至2030中国智慧港口建设现状及自动化技术应用分析报告
- 世界最大的黄土堆积区-黄土高原
- 2026年高考化学专项复习讲义:化学用语的正误判断(含详解)
- 餐饮店火灾事故
- 传染性疾病控制副高考试真题及答案
- 现场提升活动方案
- 混凝土环保管理制度
- 个人投资公司合同标准文本
- 医保管理工作制度96012
- GB/T 18983-2017淬火-回火弹簧钢丝
- 第十一章多孔材料课件
评论
0/150
提交评论