ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:21.34KB ,
资源ID:9012301      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9012301.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(freertos任务管理教学内容.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

freertos任务管理教学内容.docx

1、freertos任务管理教学内容freertos任务管理freertos是一个轻量级的rtos,它目前实现了一个微内核,并且port到arm7, avr, pic18, coldfire等众多处理器上;目前已经在rtos的市场上占有不少的份额。它当然不是一个与vxworks之类的rtos竞争的操作系统,它的目标在 于低性能小RAM的处理器上。整个系统只有3个文件,外加上port的和处理器相关的两个文件,实现是很简洁的。与ucosii不同,它是free的,ucosii不是free的,虽然它的代码是公开的。FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理。FreeRT

2、OS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、 优先级最高的任务先运行。FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下,同一优先级的任务共享CPU的使用时间。这一点是和ucosii不同的。另外一点不同是freertos既可以配置为可抢占内核也可以配置为不可抢占内核。当FreeRTOS被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行

3、任务主动释放CPU的使用权后才能获得运行,这 样可提高CPU的运行效率。这篇文章是以freertos v5.0版本的代码为例子分析下它的任务管理方面的实现。时间关系可能没有太多时间写的很详细了。1.链表管理freertos里面的任务管理,queue,semaphore管理等都借助于双向链表,它定义了个通用的数据结构/*定义链表节点?*/Struct xLIST_ITEM portTickType xItemValue; /链表节点的数据项,通常用在任务延时,表示一个任务延时的节拍数 volatile struct xLIST_ITEM * pxNext; /通过这两个成员变量将所有节点 vol

4、atile struct xLIST_ITEM * pxPrevious;/链接成双向链表 void * pvOwner;/指向该item的所有者,通常是任务控制块 void * pvContainer; /指向此链表结点所在的链表 ;/*定义一个链表?*/*一个优先级一个链表?*/这个数据结构定义了一个通用的链表节点;下面的数据结构定义了一个双向链表typedef struct xLIST volatile unsigned portBASE_TYPE uxNumberOfItems;/表示该链表中节点的数目 volatile xListItem * pxIndex;/用于遍历链表,指向上次

5、访问的节点 volatile xMiniListItem xListEnd;/链表尾结点 /*指向链表中的最后一个节点?*/ xList;而下面这个数据结构用在xList中,只是为了标记一个链表的尾,是一个markerstruct xMINI_LIST_ITEM portTickType xItemValue; volatile struct xLIST_ITEM *pxNext; volatile struct xLIST_ITEM *pxPrevious;typedef struct xMINI_LIST_ITEM xMiniListItem;对于链表的操作也定义了一系列的函数和宏,在li

6、st.c文件中。如初始化个链表,吧一个节点插入链表等。初始化链表:void vListInitialise( xList *pxList ) /* The list structure contains a list item which is used to mark the end of the list.To initialise the list the list endis inserted as the only list entry. */ pxList-pxIndex = ( xListItem * ) &(pxList-xListEnd ); /* The list end

7、value is the highest possible value in the list to ensure it remains at the end of the list. */ pxList-xListEnd.xItemValue = portMAX_DELAY; /* The list end next and previous pointers point to itselfso we know when the list is empty. */ pxList-xListEnd.pxNext = ( xListItem * ) &(pxList-xListEnd ); px

8、List-xListEnd.pxPrevious = ( xListItem * ) &(pxList-xListEnd ); pxList-uxNumberOfItems = 0;把一个节点插入到链表尾部:void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )volatile xListItem * pxIndex; /* Insert a new list item into pxList, but rather than sortthe list, makes the new list item the last it

9、em to be removed by acall to pvListGetOwnerOfNextEntry.This means it has to be theitem pointed to by the pxIndex member. */ pxIndex = pxList-pxIndex;/指向最后访问的节点 要被插入节点的前一个节点 pxNewListItem-pxNext = pxIndex-pxNext; pxNewListItem-pxPrevious = pxList-pxIndex; pxIndex-pxNext-pxPrevious = ( volatile xListI

10、tem * )pxNewListItem; pxIndex-pxNext = ( volatile xListItem * ) pxNewListItem; pxList-pxIndex = ( volatile xListItem * ) pxNewListItem; /* Remember which list the item is in. */ pxNewListItem-pvContainer = ( void * ) pxList; ( pxList-uxNumberOfItems )+;这些就不多说了。2.任务控制块typedef struct tskTaskControlBlo

11、ckvolatile portSTACK_TYPE *pxTopOfStack; /指向堆栈顶xListItem xGenericListItem; /通过它将任务连入就绪链表或者延时链表或者挂起链表中xListItem xEventListItem; /通过它把任务连入事件等待链表unsigned portBASE_TYPE uxPriority; /优先级portSTACK_TYPE *pxStack; /指向堆栈起始位置signed portCHAR pcTaskNameconfigMAX_TASK_NAME_LEN ;#if ( portCRITICAL_NESTING_IN_TCB=

12、 1 )unsignedportBASE_TYPE uxCriticalNesting;#endif#if (configUSE_TRACE_FACILITY = 1 )unsignedportBASE_TYPE uxTCBNumber; /用于trace,debug时候提供方便#endif#if ( configUSE_MUTEXES= 1 )unsignedportBASE_TYPE uxBasePriority; /当用mutex发生优先级反转时用#endif#if (configUSE_APPLICATION_TASK_TAG = 1 )pdTASK_HOOK_CODEpxTaskTa

13、g;#endif tskTCB;其中uxBasePriority用于解决优先级反转,freertos采用优先级继承的办法解决这个问题,在继承时,将任务原先的优先级保存在这个成员中,将来再从这里恢复任务的优先级。3.系统全局变量freertos将任务根据他们的状态分成几个链表。所有就绪状态的任务根据任务优先级加到对应的就绪链表中。系统为每个优先级定义了一个xList。如下:static xList pxReadyTasksLists configMAX_PRIORITIES ;/* Prioritised ready tasks. */此外,所有延时的任务加入到两个延时链表之一。static x

14、List xDelayedTaskList1;static xList xDelayedTaskList2;还定义了两个指向延时链表的指针:static xList * volatile pxDelayedTaskList;static xList * volatile pxOverflowDelayedTaskList;freertos弄出两个延时链表是因为它的延时任务管理的需要。freertos根据任务延时时间的长短按序将任务插入这两个链表之一。在插入前先把任务将要延时的xTicksToDelay数加上系统当前tick数,这样得到了一个任务延时due time(到期时间)的绝对数值。但是有

15、可能这个相加操作会导致溢出,如果溢出则加入到pxOverflowDelayedTaskList指向的那个链表,否则加入pxDelayedTaskList指向的链表。freertos还定义了个pending链表:static xList xPendingReadyList;这个链表用在调度器被lock(就是禁止调度了)的时期,如果一个任务从非就绪状态变为就绪状态,它不直接加到就绪链表中,而是加到这个pending链表中。等调度器重新启动(unlock)的时候再检查这个链表,把里面的任务加到就绪链表中static volatile xList xTasksWaitingTermination;/*

16、 Tasks that have been deleted- but the their memory not yet freed. */static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsignedportBASE_TYPE ) 0;一个任务被删除的时候加入到xTasksWaitingTermination链表中,uxTasksDeleted跟中系统中有多少任务被删除(即加到xTasksWaitingTermination链表的任务数目).static xList xSuspendedTaskList;/*Tasks th

17、at are currently suspended. */这个链表记录着所有被xTaskSuspend挂起的任务,注意这不是那些等待信号量的任务。staticvolatile unsigned portBASE_TYPE uxCurrentNumberOfTasks ;记录了当前系统任务的数目staticvolatile portTickType xTickCount;是自启动以来系统运行的ticks数staticunsigned portBASE_TYPE uxTopUsedPriority;记录当前系统中被使用的最高优先级,staticvolatile unsigned portBASE

18、_TYPE uxTopReadyPriority;记录当前系统中处于就绪状态的最高优先级。staticvolatile signed portBASE_TYPE xSchedulerRunning;表示当前调度器是否在运行,也即内核是否启动了4.任务管理freertos与ucosii不同,它的任务控制块并不是静态分配的,而是在创建任务的时候动态分配。另外,freertos的优先级是优先级数越大优先级越高,和ucosii正好相反。任务控制块中也没有任务状态的成员变量,这是因为freertos中的任务总是根据他们的状态连入对应的链表,没有必要在任务控制块中维护一个状态。此外freertos对任务的

19、数量没有限制,而且同一个优先级可以有多个任务。先看任务创建:/*参数: pvTaskCode-任务函数名称* pcName-任务名字,可选*ucStackDepth-任务堆栈的深度,即大小* pvParamenters-参数,即传给任务函数的参数,所有的任务函数原型是void task (void *pvParameters)* uxPriority任务优先级* pxCreatedTask可选,通过它返回被创建任务的tcb*/signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, constsigned portCHAR * cons

20、t pcName, unsigned portSHORT usStackDepth, void*pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask )signed portBASE_TYPE xReturn;tskTCB * pxNewTCB;#if ( configUSE_TRACE_FACILITY = 1 )static unsignedportBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this isgu

21、arded before use. */#endif/*动态分配tcb和任务堆栈*/pxNewTCB =prvAllocateTCBAndStack( usStackDepth );/*如果分配成功的话*/if( pxNewTCB != NULL )portSTACK_TYPE*pxTopOfStack;/*初始化tcb*/prvInitialiseTCBVariables(pxNewTCB, pcName, uxPriority );/*计算堆栈的顶*/#if portSTACK_GROWTHpxStack + ( usStackDepth - 1 );#elsepxTopOfStack=

22、pxNewTCB-pxStack;#endif/* 初始化任务堆栈,并将返回地址保存在tcb中的pxTopOfStack变量*/pxNewTCB-pxTopOfStack= pxPortInitialiseStack( pxTopOfStack, pvTaskCode, pvParameters );/*关中断*/portENTER_CRITICAL(); /*更新系统的任务数*/uxCurrentNumberOfTasks+;if(uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 1 )/*如果这是系统中第一个任务,则把它设为当前任务*/

23、pxCurrentTCB=pxNewTCB;/*如果这是系统中的第一个任务,那也就意味着内核刚准备启动,实际上这第一个任务一定是idle任务,这个时候我们要做一些系统初始化,即初始化那些全局链表*/prvInitialiseTaskLists();else/*如果内核还没有运行,则把当前任务设成已经创建的任务中优先级最高的那个,将来内核一旦运行,调度器会马上选择它运行*/if(xSchedulerRunning = pdFALSE )if(pxCurrentTCB-uxPriority uxPriority uxTopUsedPriority )uxTopUsedPriority= pxNew

24、TCB-uxPriority;#if (configUSE_TRACE_FACILITY = 1 )/*Add a counter into the TCB for tracing only. */pxNewTCB-uxTCBNumber= uxTaskNumber;uxTaskNumber+;#endif/*把新创建的任务加到就绪链表*/prvAddTaskToReadyQueue(pxNewTCB );xReturn =pdPASS;traceTASK_CREATE(pxNewTCB );portEXIT_CRITICAL();/*如果分配内存失败,我们返回错误*/elsexReturn

25、=errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;traceTASK_CREATE_FAILED(pxNewTCB );if( xReturn = pdPASS )if( ( void * )pxCreatedTask != NULL )/*将新创建任务的tcb返回给调用者*pxCreatedTask= ( xTaskHandle ) pxNewTCB;/*如果调度器已经运行*/if(xSchedulerRunning != pdFALSE )/*如果新创建的任务的优先级高于当前正在运行的任务,则调度 */if(pxCurrentTCB-uxPriority pxS

26、tack= ( portSTACK_TYPE * ) pvPortMalloc( ( ( size_t )usStackDepth ) * sizeof(portSTACK_TYPE ) );if(pxNewTCB-pxStack = NULL )/* Couldnot allocate the stack. Delete theallocated TCB. */vPortFree(pxNewTCB );pxNewTCB= NULL;else/* Justto help debugging. */memset(pxNewTCB-pxStack, tskSTACK_FILL_BYTE, usSt

27、ackDepth * sizeof( portSTACK_TYPE) );return pxNewTCB;再看任务删除:freertos的任务删除分两步完成,第一步在vTaskDelete中完成,FreeRTOS先把要删除的任务从就绪任务链表和事件等待链表中删除,然后把此任务添加到任务删除链表(即那个xTasksWaitingTermination),若删除的任务是当前运行任务,系统就执行任务调度函数.第2步则是在idle任务中完成,idle任务运行时,检查xTasksWaitingTermination链表,如果有任务在这个表上,释放该任务占用的内存空间,并把该任务从任务删除链表中删除。/*参数:pxTaskToDelete是一个指向被删除任务的句柄,这里其实就是等价于任务控制块*如果这个句柄=NULL,则表示要删除当前任务*

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1