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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

本文(FreeRTOS任务.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至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提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理。F

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

3、等当前运行任务主动释放CPU的使用权后才能获得运行,这 样可提高CPU的运行效率。这篇文章是以freertos 版本的代码为例子分析下它的任务管理方面的实现。时间关系可能没有太多时间写的很详细了。1.链表管理freertos里面的任务管理,queue,semaphore管理等都借助于双向链表,它定义了个通用的数据结构struct xLIST_ITEM portTickType xItemValue; To initialise the list the list end is inserted as the only list entry. */ pxList-pxIndex = ( xLis

4、tItem * ) &( pxList-xListEnd ); /* The list end value is the highest possible value in the list to ensure it remains at the end of the list. */ pxList- = portMAX_DELAY; /* The list end next and previous pointers point to itself so we know when the list is empty. */ pxList- = ( xListItem * ) &( pxLis

5、t-xListEnd ); pxList- = ( 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 sort the list, makes the new list item the last ite

6、m to be removed by a call to pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by the pxIndex member. */ pxIndex = pxList-pxIndex; pxNewListItem-pxNext = pxIndex-pxNext; pxNewListItem-pxPrevious = pxList-pxIndex; pxIndex-pxNext-pxPrevious = ( volatile xListItem * ) pxNewListItem

7、; 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 tskTaskControlBlock volatile portSTAC

8、K_TYPE *pxTopOfStack;统全局变量freertos将任务根据他们的状态分成几个链表。所有就绪状态的任务根据任务优先级加到对应的就绪链表中。系统为每个优先级定义了一个xList。如下:static xList pxReadyTasksLists configMAX_PRIORITIES ; /* Prioritised ready tasks. */此外,所有延时的任务加入到两个延时链表之一。static xList xDelayedTaskList1; static xList xDelayedTaskList2; 还定义了两个指向延时链表的指针:static xList *

9、 volatile pxDelayedTaskList; static xList * volatile pxOverflowDelayedTaskList; freertos弄出两个延时链表是因为它的延时任务管理的需要。freertos根据任务延时时间的长短按序将任务插入这两个链表之一。在插入前先把任务将要延时的xTicksToDelay数加上系统当前tick数,这样得到了一个任务延时due time(到期时间)的绝对数值。但是有可能这个相加操作会导致溢出,如果溢出则加入到pxOverflowDelayedTaskList指向的那个链表,否则加入pxDelayedTaskList指向的链表。

10、freertos还定义了个pending链表:static xList xPendingReadyList;这个链表用在调度器被lock(就是禁止调度了)的时期,如果一个任务从非就绪状态变为就绪状态,它不直接加到就绪链表中,而是加到这个pending链表中。等调度器重新启动(unlock)的时候再检查这个链表,把里面的任务加到就绪链表中static volatile xList xTasksWaitingTermination; /* Tasks that have been deleted - but the their memory not yet freed. */static vola

11、tile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0;一个任务被删除的时候加入到xTasksWaitingTermination链表中,uxTasksDeleted跟中系统中有多少任务被删除(即加到xTasksWaitingTermination链表的任务数目).static xList xSuspendedTaskList; /* Tasks that are currently suspended. */这个链表记录着所有被xTaskSuspend挂起的任务,注意这不是那些等待信号量的任务。sta

12、tic volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks;记录了当前系统任务的数目static volatile portTickType xTickCount;是自启动以来系统运行的ticks数static unsigned portBASE_TYPE uxTopUsedPriority;记录当前系统中被使用的最高优先级,static volatile unsigned portBASE_TYPE uxTopReadyPriority;记录当前系统中处于就绪状态的最高优先级。static volatile signed portBA

13、SE_TYPE xSchedulerRunning ;表示当前调度器是否在运行,也即内核是否启动了4.任务管理freertos与ucosii不同,它的任务控制块并不是静态分配的,而是在创建任务的时候动态分配。另外,freertos的优先级是优先级数越大优先级越高,和ucosii正好相反。任务控制块中也没有任务状态的成员变量,这是因为freertos中的任务总是根据他们的状态连入对应的链表,没有必要在任务控制块中维护一个状态。此外freertos对任务的数量没有限制,而且同一个优先级可以有多个任务。先看任务创建:/*参数: pvTaskCode-任务函数名称* pcName-任务名字,可选*uc

14、StackDepth-任务堆栈的深度,即大小* pvParamenters-参数,即传给任务函数的参数,所有的任务函数原型是void task (void *pvParameters)* uxPriority任务优先级* pxCreatedTask可选,通过它返回被创建任务的tcb*/signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned

15、 portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask )signed portBASE_TYPE xReturn;tskTCB * pxNewTCB;#if ( configUSE_TRACE_FACILITY = 1 ) static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */#endif /*动态分配tcb和任务堆栈*/ pxNewTCB = prvAllocateT

16、CBAndStack( usStackDepth ); /*如果分配成功的话*/ if( pxNewTCB != NULL ) portSTACK_TYPE *pxTopOfStack; /*初始化tcb*/ prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority ); /*计算堆栈的顶*/ #if portSTACK_GROWTH pxStack + ( usStackDepth - 1 ); #else pxTopOfStack = pxNewTCB-pxStack; #endif /* 初始化任务堆栈,并将返回地址保存在tcb中的p

17、xTopOfStack变量*/ pxNewTCB-pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pvTaskCode, pvParameters ); /*关中断*/ portENTER_CRITICAL(); /*更新系统的任务数*/ uxCurrentNumberOfTasks+; if( uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 1 ) /*如果这是系统中第一个任务,则把它设为当前任务*/ pxCurrentTCB = pxNewTCB; /*如果这是系统中的第一个任务

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

19、gUSE_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(); /*如果分配内存失败,我们返回错误*/ else xReturn = errCOU

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

21、ity pxStack = ( portSTACK_TYPE * ) pvPortMalloc( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ); if( pxNewTCB-pxStack = NULL ) /* Could not allocate the stack. Delete the allocated TCB. */ vPortFree( pxNewTCB ); pxNewTCB = NULL; else /* Just to help debugging. */ memset( pxNewTCB-pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) ); return pxNewTCB;再看任务删除

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

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