《任务管理时间管理内存.ppt》由会员分享,可在线阅读,更多相关《任务管理时间管理内存.ppt(43页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计第八讲(3)任务管理 时间管理、内存管理授课教师:李英祥电邮地址:2022/11/201嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计主要内容1.任务管理2.时间管理3.内存管理2022/11/202嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计1.任务管理建立任务OSTaskCreate()堆栈检验 OSTaskStkChk()删除任务OSTaskDel()请求删除任务OSTaskDelReq()改变任务的优先级OSTaskChangePrio()挂起任务OSTaskSuspend()恢复任务OSTaskResume
2、()获得有关任务的信息OSTaskQuery()2022/11/203嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计任务管理机制任务管理用来实现对任务状态的直接控制和访问。内核的任务管理是通过系统调用来体现,主要包括任务创建、任务删除、任务挂起、任务唤醒、设置任务属性等内容。创建任务创建任务删除任务删除任务挂起任务挂起任务唤醒任务唤醒任务设置任务属性设置任务属性改变任务优先级改变任务优先级获取任务信息获取任务信息任务管理功能任务管理功能任务管理功能任务管理功能2022/11/204嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计建立任务OSTaskCreate()OSTask
3、Create()需要四个参数:task是指向任务代码的指针;Pdata指向一个数据结构,该结构用来在建立任务时向任务传递参数;ptos是分配给任务的堆栈的栈顶指针(任务堆栈);prio是分配给任务的优先级 2022/11/205嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计返回值OSTaskCreate()的返回值为下述之一:OS_NO_ERR:函数调用成功。OS_PRIO_EXIST:具有该优先级的任务已经存在。OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO。OS_NO_MORE_TCB:系统中没有OS_TCB可以分配给任务了。2022/11/20
4、6嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计注意/警告任务堆栈必须声明为OS_STK类型。在任务中必须调用C/OS提供的下述过程之一:延时等待、任务挂起、等待事件发生(等待信号量,消息邮箱、消息队列),以使其他任务得到CPU。用户程序中不能使用优先级0,1,2,3,以及OS_LOWEST_PRIO-3,OS_LOWEST_PRIO-2,OS_LOWEST_PRIO-1,OS_LOWEST_PRIO。这些优先级C/OS系统保留,其余的56个优先级提供给应用程序。2022/11/207嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计每个任务都有自己的堆栈空间。堆栈必须声明为O
5、S_STK类型,并且由连续的内存空间组成。用户可以静态分配堆栈空间(在编译的时候分配),静态堆栈声明应放置在函数的外面,这两种声明方式如下:2022/11/208嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计用户可以用C编译器提供的malloc()函数来动态地分配堆栈空间,如程序清单 L4.6所示。在动态分配中,用户要时刻注意内存碎片问题。2022/11/209嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计堆栈检验 OSTaskStkChk()OSTaskStkChk()检查任务堆栈状态,计算指定任务堆栈中的未用空间和已用空间;使用OSTaskStkChk()函数要求所检查
6、的任务是被OSTaskCreateExt()函数建立的,且opt参数中OS_TASK_OPT_STK_CHK操作项打开。参数参数prio为指定要获取堆栈信息的任务优先级,也可以指定参数OS_PRIO_SELF,获取调用任务本身的信息。pdata指向一个类型为OS_STK_DATA的数据结构 2022/11/2010嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2011嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计删除任务OSTaskDel()OSTaskDel()函数删除一个指定优先级的任务;任务可以传递自己的优先级给OSTaskDel(),从而删除自身如果
7、任务不知道自己的优先级,还可以传递参数OS_PRIO_SELF被删除的任务将回到休眠状态。任务被删除后可以用函数OSTaskCreate()或OSTaskCreateExt()重新建立参数参数prio为指定要删除任务的优先级,也可以用参数OS_PRIO_SELF代替,此时,下一个优先级最高的就绪任务将开始运行。2022/11/2012嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计范例范例2022/11/2013嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计请求删除任务OSTaskDelReq()如果任务A拥有内存缓冲区或信号量之类的资源,而任务B想删除该任务,这些资源就可能
8、由于没被释放而丢失。在这种情况下,用户可以让拥有这些资源的任务在使用完资源后,先释放资源,再删除自己。用户可以通过OSTaskDelReq()函数来完成该功能。发出删除任务请求的任务(任务B)和要删除的任务(任务A)都需要调用OSTaskDelReq()函数。例如,假设任务5要删除任务10,而任务10占有系统资源,此时任务5不能直接调用OSTaskDel(10)删除任务10,而应该调用OSTaskDelReq(10)向任务10发送删除请求。在任务10中调用OSTaskDelReq(OS_PRIO_SELF),并检测返回值。如果返回OS_TASK_DEL_REQ,则表明有来自其他任务的删除请求,
9、此时任务10应该先释放资源,然后调用OSTaskDel(OS_PRIO_SELF)删除自己。2022/11/2014嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计参数参数prio为要求删除任务的优先级。如果参数为OS_PRIO_SELF,则表示调用函数的任务正在查询是否有来自其他任务的删除请求。返回值返回值OSTaskDelReq()的返回值为下述之一:OS_NO_ERR:删除请求已经被任务记录。OS_TASK_NOT_EXIST:指定的任务不存。发送删除请求的任务可以等待此返回值,看删除是否成功。OS_TASK_DEL_IDLE:错误操作,试图删除空闲任务(Idle task)。O
10、S_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO或没有设定OS_PRIO_SELF的值。OS_TASK_DEL_REQ:当前任务收到来自其他任务的删除请求。2022/11/2015嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2016嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2017嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计改变任务的优先级OSTaskChangePrio()在用户建立任务的时候会分配给任务一个优先级。在程序运行期间,用户可以通过调用OSTaskChangePrio()来改变任务
11、的优先级;用户不能改变空闲任务的优先级,但用户可以改变调用本函数的任务或者其它任务的优先级;参数oldprio是任务原先的优先级。newprio 是任务的新优先级。2022/11/2018嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计挂起任务OSTaskSuspend()OSTaskSuspend()无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。任务的挂起是可以叠加到其他操作上的
12、。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。2022/11/2019嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计恢复任务 OSTaskResume()OSTaskResume()唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。参数参数prio指定要唤醒任务的优先级。返回值返回值OSTaskResume()的返回值为下述之一:OS_NO_ERR:函数调用成功。OS_TASK_RESUME_PRIO:要唤醒的任务不存在。OS_TASK_NOT_SUSPENDE
13、D:要唤醒的任务不在挂起状态。OS_PRIO_INVALID:参数指定的优先级大于或等于OS_LOWEST_PRIO。2022/11/2020嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计获得有关任务的信息OSTaskQuery()用户的应用程序可以通过调用OSTaskQuery()来获得自身或其它应用任务的信息。参数参数prio为指定要获取TCB内容的任务优先级,也可以指定参数OS_PRIO_SELF,获取调用任务的信息。pdata指向一个OS_TCB类型的数据结构,容纳返回的任务TCB的一个拷贝。2022/11/2021嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2.
14、时间管理任务延时函数OSTimeDly()按时分秒延时函数 OSTimeDlyHMSM()结束任务延时OSTimeDlyResume()系统时间OSTimeGet()和OSTimeSet()2022/11/2022嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计任务延时函数OSTimeDly()OSTimeDly()将一个任务延时若干个时钟节拍。如果延时时间大于0,系统将立即进行任务调度。延时时间的长度可从0到65535个时钟节拍。延时时间0表示不进行延时,函数将立即返回调用者。延时的具体时间依赖于系统每秒钟有多少时钟节拍(由常量OS_TICKS_PER_SEC设定)。参数参数tick
15、s为要延时的时钟节拍数。注意注意/警告:警告:为了确保设定的延时时间,建议用户设定的时钟节拍数加1。例如,希望延时10个时钟节拍,可设定参数为11。2022/11/2023嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计按时分秒延时函数 OSTimeDlyHMSM()OSTimeDlyHMSM()将一个任务延时若干时间。延时的单位是小时、分、秒、毫秒。调用OSTimeDlyHMSM()后,如果延时时间不为0,系统将立即进行任务调度。参数参数hours为延时小时数,范围从0-255。minutes为延时分钟数,范围从0-59。seconds为延时秒数,范围从0-59milli为延时毫秒数
16、,范围从0-999。返回值返回值OSTimeDlyHMSM()的返回值为下述之一:OS_NO_ERR:函数调用成功。OS_TIME_INVALID_MINUTES:参数错误,分钟数大于59。OS_TIME_INVALID_SECONDS:参数错误,秒数大于59。OS_TIME_INVALID_MILLI:参数错误,毫秒数大于999。OS_TIME_ZERO_DLY:四个参数全为0。2022/11/2024嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计结束任务延时OSTimeDlyResume()OSTimeDlyResume()唤醒一个用OSTimeDly()或OSTimeDlyHM
17、SM()函数延时的任务。参数参数prio为指定要唤醒任务的优先级。注意注意/警告警告不应该用OSTimeDlyResume()去唤醒一个设置了等待超时操作,并且正在等待事件发生的任务。操作的结果是使该任务结束等待,除非的确希望这么做。2022/11/2025嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计系统时间OSTimeGet()和OSTimeSet()OSTimeGet()获取当前系统时钟数值。系统时钟是一个32位的计数器,记录系统上电后或时钟重新设置后的时钟计数。参数参数无返回值返回值当前时钟计数(时钟节拍数)2022/11/2026嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌
18、入式系统设计OSTimeSet()设置当前系统时钟数值。参数参数ticks要设置的时钟数,单位是时钟节拍数。返回值返回值无。无。2022/11/2027嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计3.内存管理内存控制块建立一个内存分区 OSMemCreate()分配一个内存块 OSMemGet()释放一个内存块 OSMemPut()查询一个内存分区的状态OSMemQuery()2022/11/2028嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计内存控制块在ANSI C中可以用malloc()和free()两个函数动态地分配内存和释放内存;在嵌入式实时操作系统中,多次这样
19、做会把原来很大的一块连续内存区域,逐渐地分割成许多非常小而且彼此又不相邻的内存区域,也就是内存碎片;由于这些碎片的大量存在,使得程序到后来连非常小的内存也分配不到;在C/OS-II中,操作系统把连续的大块内存按分区来管理,每个分区中包含有整数个大小相同的内存块。利用这种机制,C/OS-II 对malloc()和free()函数进行了改进,使得它们可以分配和释放固定大小的内存块;2022/11/2029嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2030嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计在C/OS-II中使用内存控制块(memory contro
20、l blocks)的数据结构来跟踪每一个内存分区;2022/11/2031嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计OSMemAddr是指向内存分区起始地址的指针。它在建立内存分区建立一个内存分区,OSMemCreate()时被初始化,在此之后就不能更改了。OSMemFreeList是指向下一个空闲内存控制块或者下一个空闲的内存块的指针,具体含义要根据该内存分区是否已经建立来决定。OSMemBlkSize是内存分区中内存块的大小,是用户建立该内存分区时指定的。OSMemNBlks是内存分区中总的内存块数量,也是用户建立该内存分区时指定的。OSMemNFree是内存分区中当前可以得
21、空闲内存块数量。2022/11/2032嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计C/OS-II 在启动时就会对内存管理器进行初始化由OSInit()调用OSMemInit()实现。该初始化主要建立一个图 F7.3所示的内存控制块链表 其中的常数OS_MAX_MEM_PART定义了最大的内存分区数2022/11/2033嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计建立一个内存分区 OSMemCreate()OSMemCreate()函数建立并初始化一块内存区;一块内存区包含指定数目的大小确定的内存块,程序可以包含这些内存块并在用完后释放回内存区;该函数共有4个参数:内
22、存分区的起始地址分区内的内存块总块数每个内存块的字节数和一个指向错误信息代码的指针返回值:如果OSMemCreate()操作失败,它将返回一个NULL指针。否则,它将返回一个指向内存控制块的指针;对内存管理的其它操作,象OSMemGet(),OSMemPut(),OSMemQuery()函数等,都要通过该指针进行;OS_MEM*OSMemCreate(void*addr,INT32U nblks,INT32U blksize,INT8U*err)2022/11/2034嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2035嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入
23、式系统设计分配一个内存块 OSMemGet()应用程序可以调用OSMemGet()函数从已经建立的内存分区中申请一个内存块;该函数的唯一参数是指向特定内存分区的指针,该指针在建立内存分区时,由OSMemCreate()函数返回;显然,应用程序必须知道内存块的大小,并且在使用时不能超过该容量2022/11/2036嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计参数参数pmem 是指向内存区控制块的指针,可以从OSMemCreate()函数返回得到。Err 是指向包含错误码的变量的指针。OSMemGet(函数返回的错误码可能为下述几种:wOS_NO_ERR:成功得到一个内存块。wOS_M
24、EM_NO_FREE_BLKS:内存区已经没有空间分配给内存块。返回值返回值OSMemGet()函数返回指向内存区块的指针。如果没有空间分配给内存块,OSMemGet()函数返回空指针。2022/11/2037嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计释放一个内存块 OSMemPut()当用户应用程序不再使用一个内存块时,必须及时地把它释放并放回到相应的内存分区中。这个操作由OSMemPut()函数完成。必须注意的是,OSMemPut()并不知道一个内存块是属于哪个内存分区的。2022/11/2038嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计参数参数pmem 是指向
25、内存区控制块的指针,可以从OSMemCreate()函数 返回得到。Pblk 是指向将被释放的内存块的指针。返回值返回值OSMemPut()函数的返回值为下述之一:OS_NO_ERR:成功释放内存块OS_MEM_FULL:内存区已经不能再接受更多释放的内存块。这种情况说明用户程序出现了错误,释放了多于用OSMemGet()函数得到的内存块。2022/11/2039嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2040嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计查询一个内存分区的状态OSMemQuery()OSMemQuery()函数得到内存区的信息;该函数返回OS_MEM结构包含的信息,但使用了一个新的OS_MEM_DATA的数据结构;OS_MEM_DATA数据结构还包含了正被使用的内存块数目的域;2022/11/2041嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计参数参数pmem 是指向内存区控制块的指针,可以从OSMemCreate()函数 返回得到。Pdata 是指向OS_MEM_DATA数据结构的指针,该数据结构包含了以下的域:返回值返回值OSMemQuery()函数返回值总是OS_NO_ERR。2022/11/2042嵌入式系统设计嵌入式系统设计嵌入式系统设计嵌入式系统设计2022/11/2043
限制150内