uCOS-II任务堆栈检验(OSTaskStkChk())
- 格式:doc
- 大小:30.00 KB
- 文档页数:3
北航ARM9实验报告:实验3uCOS-II实验北航 ARM9 实验报告:实验 3uCOSII 实验一、实验目的本次实验的主要目的是深入了解和掌握 uCOSII 实时操作系统在ARM9 平台上的移植和应用。
通过实际操作,熟悉 uCOSII 的任务管理、内存管理、中断处理等核心机制,提高对实时操作系统的理解和应用能力,为后续的嵌入式系统开发打下坚实的基础。
二、实验环境1、硬件环境:ARM9 开发板、PC 机。
2、软件环境:Keil MDK 集成开发环境、uCOSII 源代码。
三、实验原理uCOSII 是一个可裁剪、可剥夺型的多任务实时内核,具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点。
其基本原理包括任务管理、任务调度、时间管理、内存管理和中断管理等。
任务管理:uCOSII 中的任务是一个独立的执行流,每个任务都有自己的堆栈空间和任务控制块(TCB)。
任务可以处于就绪、运行、等待、挂起等状态。
任务调度:采用基于优先级的抢占式调度算法,始终让优先级最高的就绪任务运行。
时间管理:通过系统时钟节拍来实现任务的延时和定时功能。
内存管理:提供了简单的内存分区管理和内存块管理机制。
中断管理:支持中断嵌套,在中断服务程序中可以进行任务切换。
四、实验步骤1、建立工程在 Keil MDK 中创建一个新的工程,选择对应的 ARM9 芯片型号,并配置相关的编译选项。
2、导入 uCOSII 源代码将 uCOSII 的源代码导入到工程中,并对相关的文件进行配置,如设置任务堆栈大小、系统时钟节拍频率等。
3、编写任务函数根据实验要求,编写多个任务函数,每个任务实现不同的功能。
4、创建任务在主函数中使用 uCOSII 提供的 API 函数创建任务,并设置任务的优先级。
5、启动操作系统调用 uCOSII 的启动函数,使操作系统开始运行,进行任务调度。
6、调试与测试通过单步调试、查看变量值和输出信息等方式,对系统的运行情况进行调试和测试,确保任务的执行符合预期。
µCOS-II中的任务µC/OS-II操作系统主要做三件事:任务,内存、外设。
其他要开发⼈员去实现。
µC/OS-II操作系统内核的主要⼯作就是对多任务进⾏管理和调度。
因此掌握任务的结构和µC/OS-II对任务的管理⽅法极其重要。
µC/OS-II的任务就是⼀个函数。
由三部分组成:1、任务程序代码:就是C的函数;2、任务堆栈:⽤来保存任务的⼯作环境;3、任务控制块:关联任务代码的程序控制块。
实际上就是程序控制块,记录任务的各个属性;µC/OS-II任务有⼆种:⽤户任务和系统任务(⽬前系统任务有2个:空闲任务和统计任务)。
µC/OS-II最多可以含有64个任务。
µC/OS-II任务的状态有:睡眠状态:程序代码驻留在内存中没有交给操作系统的状态;就绪状态;已经就绪登记,任务具备运⾏的条件,任务就进⼊就绪状态;运⾏状态;获得cpu的使⽤权任务进⼊运⾏状态。
任何时刻只有⼀个任务处于运⾏状态。
就绪的任务只有所有优先级⾼于本任务的任务转⼊等待状态,才能进⼊运⾏状态;等待状态:该任务把cpu的使⽤权让给其他任务就进⼊等待状态;中断服务状态:执⾏中断服务程序,这时任务的状态就是中断服务状态;⽤户任务代码的⼀般结构:void MyTask(void * pdata){for(;;){可以被中断的⽤户代码;OS_ENTER_CRITICAL();//关中断;是µC/OS-II 的宏不可中断的⽤户代码;OS_EXIT_CRITICAL();//开中断;是µC/OS-II 的宏可以中断的⽤户代码;}}⼀般把任务的参数定义成⼀个void类型的指针。
主程序和传统的基本没有区别:void main(){OSInit();//初始化是µC/OS-IIOSTaskCreate(MyTask1,......);//⾃⼰定义的任务......OSStart();//启动是µC/OS-II......}既然任务,那么有⼀个任务的优先权和优先级别。
uc/os—II下的九个C语言文件功能函数大全一、OS_CORE.C(1)void OSInit (void)(2)void OSIntEnter (void)(3)void OSIntExit (void)(4)void OSSchedLock (void) // 给调度器上锁(5)void OSSchedUnlock (void) // 给调度器解锁,成对使用(6)void OSStart (void) // 启动多任务过程,在启动之前必须调用OSInit(),并已建立一个任务。
其中OSStartHighRdy()必须调用OSTaskSwHook(),并令OSRunning = TRUE.(7)void OSStatInit (void) // 确定CPU 使用率(8)void OSTimeTick (void) // 时钟节拍服务函数,在每个时钟节拍了解每个任务的延时情况,使其中已经到了延时时限的非挂起任务进入就绪状态(9)INT16U OSVersion (void) // 返回uc/os的版本号*100(10)void OS_Dummy (void) // 不做任何事情,被OSTaskDel() 所调用(11)INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)// 使一个正在等待的任务进入就绪状态,在调用函数OS***Post发送一个事件时被调用(12)void OS_EventTaskWait (OS_EVENT *pevent)// 因为一个事件未发生而挂起一个任务时被调用(13)void OS_EventTO (OS_EVENT *pevent)// 使一个等待超时的任务进入就绪状态(14)void OS_EventWaitListInit (OS_EVENT *pevent)// 把OSEventGrp及任务等待表中的每一位清零,即令ECB中不含任务等待,被OS***Create()调用(15)void OS_Sched (void) // 实现任务级的调度(16)void OS_TaskIdle (void *pdata) // 空闲任务,为使CPU 在没有用户任务时有事可做(17)void OS_TaskStat (void *pdata) // 统计任务,每秒计算一次CPU在单位时间内的使用时间,并将计算结果以百分数的形式存放在OSCPUUsage中,以便应用程序访问它来了解cpu的利用率(18)INT8U OS_TCBInit (INT8U prio, // 任务的优先级别,存于OSTCBPrioOS_STK *ptos, // 任务堆栈顶指针,存于OSTCBStkPtrOS_STK *pbos, // 任务堆栈栈底指针,存于OSTCBStkBottomINT16U id, // 任务的标识符,存于OSTCBIDINT32U stk_size, // 任务堆栈长度,存于OSTCBStkSizevoid *pext, // 任务控制块的扩展指针,存于OSTCBExtPtrINT16U opt) // 任务控制块的选择项,存于OSTCBOpt// 为用户程序分配任务控制块及对其进行初始化备注:INT8U const OSUnMapTbl[ ] 是uc/os 为提高查找速度而定义的一个数组二、OS_FLAG.C(1)OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, // 信号量的初始值INT8U *err) // 错误信息// 信号量集的创建函数(2)void OS_FlagInit (void) // initialize the event flag module,是uc/os的内部函数,应用程序不得调用该函数(3)OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, // 所要删除的信号量集指针INT8U opt, // 选择项INT8U *err)// 删除信号量集(4)OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, // 所要请求的信号量集的指针OS_FLAGS flags, // 滤波器INT8U wait_type, // 等待类型INT16U timeout, // 延时时限INT8U *err) // 错误信息// 请求信号量集(5)OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, // 所请求的信号量集指针OS_FLAGS flags, // 请求的信号INT8U wait_type, // 逻辑运算类型INT8U *err) // 错误信息// 无等待的请求一个信号量集(6)OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp,OS_FLAGS flags, // 所要选择发送的信号INT8U opt, // 信号有效的选项INT8U *err)// 向信号量集发送信号(7)OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, // 待查询的信号量集的指针INT8U *err)// 查询信号量的状态,返回被查询信号量集标志组的成员OSFlagFlags(8)static void OS_FlagBlock (OS_FLAG_GRP *pgrp, // 信号量集指针OS_FLAG_NODE *pnode, // 待添加的等待任务节点指针OS_FLAGS flags, // 指定等待信号的数据INT8U wait_type, // 信号与等待之间的逻辑INT16U timeout) // 等待时限// 添加节点,在请求信号量集函数OSFlagPend()中被调用(9)static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode,OS_FLAGS flags_rdy)// 期望的事件标志为已经置位,从而使一个任务准备运行(10)void OS_FlagUnlink (OS_FLAG_NODE *pnode)// 删除节点,在OSFlagPost() 中被调用三、OS_MBOX.C(1)void *OSMboxAccept (OS_EVENT *pevent)// 无等待的请求消息邮箱(2)OS_EVENT *OSMboxCreate (void *msg)// 创建一个消息邮箱(3)OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *er r)// 删除消息邮箱(4)void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)// 请求消息邮箱,查看OSEventPtr是否为NULL (5)INT8U OSMboxPost (OS_EVENT *pevent, void *msg)// 向消息邮箱发送消息(6)INT8U OSMboxPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)// 以广播形式向事件等待任务表中的所有任务发送消息(7)INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *pdata)// 状态查询四、OS_MEM.C(1)OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)// 创建动态内存(2)void *OSMemGet (OS_MEM *pmem, INT8U *err)// 请求获得一个内存块(3)INT8U OSMemPut (OS_MEM *pmem, void *pblk)// 释放一个内存块(4)INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata)// 查询动态内存的状态(5)void OS_MemInit (void) // 初始化动态内存五、OS_MUTEX.C(1)INT8U OSMutexAccept (OS_EVENT *pevent, INT8U *err)// 无等待时间的请求信号量(2)OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)// 创建互斥型信号量(3)OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *er r)// 删除互斥型信号量(4)void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)// 有等待时间的请求信号量(5)INT8U OSMutexPost (OS_EVENT *pevent)// 发送(释放)互斥型信号量(6)INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *pdat a)// 获取互斥型信号量的当前状态六、OS_Q.C(1)void *OSQAccept (OS_EVENT *pevent)// 无等待的请求一个消息队列(2)OS_EVENT *OSQCreate (void **start, INT16U size)// 创建一个消息队列(3)OS_EVENT *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *err)// 删除消息队列(4)INT8U OSQFlush (OS_EVENT *pevent)// 清空消息队列(5)void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)// 有等待的请求一个消息队列(6)INT8U OSQPost (OS_EVENT *pevent, void *msg)// 以“先进先出”的方式向消息队列发送消息(7)INT8U OSQPostFront (OS_EVENT *pevent, void *msg)// 以“后进先出”的方式向消息队列发送消息(8)INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)// 以“广播”方式向消息队列发送消息(9)INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata)// 获取消息队列的当前状态(10)void OS_QInit (void)// 消息队列初始化七、OS_SEM.C(1)INT16U OSSemAccept (OS_EVENT *pevent)// 无等待的请求信号量(2)OS_EVENT *OSSemCreate (INT16U cnt)// 创建信号量(3)OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)// 删除信号量(4)void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)// 有等待的请求信号量(5)INT8U OSSemPost (OS_EVENT *pevent)// 发送(释放)信号量(6)INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)// 获取信号量的当前状态八、OS_TASK.C(1)INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)// 任务优先级别的改变(2)INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *pt os, INT8U prio)// 任务的创建(3)INT8U OSTaskCreateExt (void (*task)(void *pd), // 指向任务的指针void *pdata, // 传递给任务的参数OS_STK *ptos, // 指向任务堆栈栈顶的指针INT8U prio, // 创建任务的优先级INT16U id, // 任务的标识OS_STK *pbos, // 任务堆栈栈底的指针INT32U stk_size, // 任务堆栈的长度void *pext, // 指向附加数据域的指针INT16U opt) // 用于设定操作的选项// 任务的另一种创建函数,更加灵活,但也增加了额外的开销(4)INT8U OSTaskDel (INT8U prio) // 任务的删除(5)INT8U OSTaskDelReq (INT8U prio) // 请求删除任务函数(6)INT8U OSTaskResume (INT8U prio) // 任务的恢复(7)INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *pdata)// 校核空余内存的数量(8)INT8U OSTaskSuspend (INT8U prio) // 任务的挂起,可用来挂起自身或除空闲任务之外的任何任务(9)INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata)// 任务的查询九、OS_TIME.C(1)void OSTimeDly (INT16U ticks) // 以时钟节拍数为单位延时(2)INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U second s, INT16U milli)// 用时、分、秒、毫秒为单位延时(3)INT8U OSTimeDlyResume (INT8U prio)// 取消延时,若任务比正在运行的任务级别高,则立即引发一次调度(4)INT32U OSTimeGet (void) // 获取OSTime 值(5)void OSTimeSet (INT32U ticks) // 设置OSTime 值注:INT32U OSTime // 全局变量,用以记录系统发生的时钟节拍。
uCOS-II任务及其结构
正如前⾯所介绍,在uC/OS-II中,任务包括任务控制块、任务堆栈以及任务代码组成,
其中任务控制块包括程序控制块+链表(前⼀篇内容):指向前⼀个任务控制块的指针,后⼀⼽任务控制块的指针,指向任务指针,指向任务堆栈的指针以及任务的优先级等等,
任务堆栈是⽤来保存任务的环境,
任务代码即为需要执⾏的任务内容,
介绍下线程与进程的定义:
线程,不占有私有空间的任务
进程,占有私有任务的任务
在uC/OS-II中,任务可分为⽤户任务和系统任务,系统中,最多可以含有64个任务(包括系统任务和⽤户任务),其中⼀个具体的时刻只可以存在⼀个任务占⽤CPU(运⾏状态),⽽其他任务只可以出于其他状态,系统任务的状态主要有:
睡眠状态:没有配备任务控制块或被剥夺了任务控制块
就绪状态:配备了任务控制块且在任务就绪表中登记
运⾏状态:处于就绪状态且获得了CPU的使⽤权,
等待状态:正在运⾏的任务,需要等待⼀段时间或者需要等待⼀个事件的触发再运⾏,此时CPU的使⽤权将让给其他的任务:使该任务进⼊等待状态,
中断服务状态:⼀个正在运⾏的任务⼀旦响应中断申请就会中⽌运⾏,转⽽执⾏中断服务程序(需要保存断点)
任务代码是⼀个⽆限循环结构,并且在循环中可以响应中断,这种结构是超循环结构,⽤户任务是需要调度才会被执⾏的,操作系统在管理⽤户任务的同时会处理⼀些内部事务(系统任务),为了使CPU在没有⽤户任务可执⾏时,有事可做,uC/OS-II提供了⼀个空闲任务(OSTaskIdle())的系统任务(简单说就是任务运⾏次数计数器),还包含统计任务(CPU使⽤率),即每秒计算⼀次CPU在单位时间内被使⽤的时间,并把计算结果以百分⽐形式存放在OSCPUsage中。
第4章任务管理 (1)4.0建立任务,OSTaskCreate() (2)4.1建立任务,OSTaskCreateExt() (6)4.2任务堆栈 (9)4.3堆栈检验,OSTaskStkChk() (11)4.4删除任务,OSTaskDel() (14)4.5请求删除任务,OSTaskDelReq() (17)4.6改变任务的优先级,OSTaskChangePrio() (20)4.7挂起任务,OSTaskSuspend() (23)4.8恢复任务,OSTaskResume() (25)4.9获得有关任务的信息,OSTaskQuery() (26)第4章任务管理在前面的章节中,笔者曾说过任务可以是一个无限的循环,也可以是在一次执行完毕后被删除掉。
这里要注意的是,任务代码并不是被真正的删除了,而只是µC/OS-Ⅱ不再理会该任务代码,所以该任务代码不会再运行。
任务看起来与任何C函数一样,具有一个返回类型和一个参数,只是它从不返回。
任务的返回类型必须被定义成void型。
在本章中所提到的函数可以在OS_TASK文件中找到。
如前所述,任务必须是以下两种结构之一:void YourTask (void *pdata){for (;;) {/* 用户代码 */调用µC/OS-Ⅱ的服务例程之一:OSMboxPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/* 用户代码 */}}或void YourTask (void *pdata){/* 用户代码 */OSTaskDel(OS_PRIO_SELF);}本章所讲的内容包括如何在用户的应用程序中建立任务、删除任务、改变任务的优先级、挂起和恢复任务,以及获得有关任务的信息。
µC/OS-Ⅱ可以管理多达64个任务,并从中保留了四个最高优先级和四个最低优先级的任务供自己使用,所以用户可以使用的只有56个任务。
uC/OS-II简介u C / O S 是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。
μC/OS-II 的前身是μC/OS,最早出自于1992 年美国嵌入式系统专家Jean brosse 在《嵌入式系统编程》杂志的5 月和6 月刊上刊登的文章连载,并把μC/OS 的源码发布在该杂志的B B S 上。
μC/OS 和μC/OS-II 是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。
CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。
用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌人到开发的产品中。
μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至2KB 。
μC/OS-II 已经移植到了几乎所有知名的CPU 上。
严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。
没有提供输入输出管理,文件系统,网络等额外的服务。
但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。
uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。
任务管理uC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,改任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,改任务负责统计当前cpu 的利用率。
uC/OS-II 的任务:从任务的存储结构来看,uC/OS-II的任务由三个部分构成:1任务程序代码,任务的执行部分2任务堆栈,用来保存任务工作环境3任务控制块,用来保存任务属性每一个任务都作为一个节点,组成一个双向的任务链表。
用户任务:从程序代码上看,用户任务似乎就是一个C语言函数,但是这个函数不是一般的C语言函数,它是一个任务(线程)。
因此,它不是被主函数或其他函数调用的,主函数mian()只是负责创建和启动它们,而由操作系统负责来调度它们。
系统任务:uC/OS-II预定义了两个为应用程序服务的系统任务:4空闲任务(OSTaskIdle)5统计任务(OSTaskStat)其中空闲任务是每个应用程序必须使用的。
OSTaskIdle由系统自动创建,在系统初始化时,∙OSInit --> OS_InitTaskIdle --> OSTaskIdle如果用户应用程序要使用统计任务,则必须把定义在OS_CFG.H 中的OS_TASK_STAT_EN设置为1,并且必须在创建统计任务之前调用函数OSStatInit( )对统计任务进行初始化。
任务优先级:优先级数目通过OS_CFG.H中的OS_LOWEST_PRIO配置。
固定地,系统总是把最低优先级别OS_LOWEST_PRIO自动赋给空闲任务。
如果应用程序中还使用了统计任务,则系统会把OS_LOWEST_PRIO - 1自动赋给统计任务。
由于每个任务都具有唯一的优先级别,因此uC/OS-II通常也用任务的优先级别来作为这个任务的标识。
任务堆栈:堆栈的增长方向随系统所使用的处理器不同而不同,为提高应用程序的可移植性,可利用OS_CFG.H中的OS_STK_GROWTH作为选择开关。
把CPU启动任务时所需的初始数据事先存放在任务的堆栈中,当任务获得CPU使用权时,就可以把堆栈中的初始数据复制到CPU 的各寄存器中,使任务顺利地启动并运行。
任务堆栈的初始化工作是由系统通过在OSTaskCreate ( )中调用OSTaskStkInit ( )来完成的。
事件标志管理 (EVENT FLAGS MANAGEMENT)* OSFlagAccept()检查事件标志组函数(标志组的指针、事件标志位、等待事件标志位的方式、错误码指针)* OSFlagCreate()建立一个事件标志组(初值、错误码)* OSFlagDel()删除一个事件标志组(指针、条件值、错误值)* OSFlagPend() 等待事件标志组的事件标志位(事件组指针、需要检查的标志位、等待事件标志位的方式、允许等待的时钟节拍、出错代码的时钟节拍)* OSFlagPost()置位或清0事件标志组中的标志位(指针、标志位、条件值、错误码)operating system\flag标记\accept接受\create创建\pend悬而未决\post布置消息邮箱管理 (MESSAGE MAILBOX MANAGEMENT)* OSMboxAccept ()查看消息邮箱(消息邮箱指针)* OSMboxCreate ()建立并初始化一个消息邮箱(msg 参数不为空含内容)* OSMboxDel ()删除消息邮箱(消息邮箱指针、删除条件、出错代码指针)* OSMboxPend ()等待一个消息邮箱函数(消息邮箱指针、允许等待的时钟节拍、代码错误指针)* OSMboxPost ()发送消息函数(消息邮箱指针、即将实际发送给任务的消息)* OSMboxPostOpt() 向邮箱发送一则消息(邮箱指针、消息、条件)* OSMboxQuery () 查询一个邮箱的当前状态(信号量指针、状态数据结构指针)Mail邮件\box盒子\opt选择\query询问内存管理项 (MEMORY MANAGEMENT)* OSMemCreate ()建立并初始化一块内存区(起始地址、需要的内存块数目、内存块大小、返回错误的指针)* OSMemGet ()从内存区分配一个内存块* OSMemPut () 释放一个内存块,内存块必须释放回原先申请的内存区* OSMemQuery ()得到内存区的信息Get获得\put放互斥型信号量项管理 (MUTUAL EXCLUSION SEMAPHORE MANAGEMENT)* OSMutexAccept ()无等待地获取互斥型信号量[任务不挂起](信号量指针、错误代码)* OSMutexCreate () 建立并初始化一个互斥型信号量(优先级继承优先级(PIP)、出错代码指针)* OSMutexDel ()删除互斥型信号量(信号指针、删除条件、错误指针)* OSMutexPend ()等待一个互斥型信号量(指针、等待超时时限、出错代码指针)* OSMutexPost () 释放一个互斥型信号量(互斥型信号量指针)* OSMutexQuery () 查询一个互斥型信号量的当前状态(互斥型信号量指针,状态数据结构指针)消息队列管理 (MESSAGE QUEUE MANAGEMENT)* OSQAccept ()检查消息队列中是否已经有需要的消息(消息队列的指针)* OSQCreate ()建立一个消息队列(消息内存区的基地址(指针数组)、消息内存区的大小)* OSQDel ()删除一个消息队列(消息队列指针、删除条件、错误指针)* OSQFlush ()清空消息队列(指向得到消息队列的指针)* OSQPend ()任务等待消息队列中的消息(消息队列指针、允许等待的时钟节拍、代码错误指针)* OSQPost ()向消息队列发送一则消息FIFO(消息队列指针、发送的消息)* OSQPostFront ()向消息队列发送一则消息LIFO(消息队列指针、发送的消息)* OSQPostOpt ()向消息队列发送一则消息LIFO(消息队列指针、发送的消息、发送条件)Flush清洗\front前面信号量管理 (SEMAPHORE MANAGEMENT)* OSSemAccept()无条件地等待请求一个信号量函数* OSSemCreate()建立并初始化一个信号量(输入一个信号量值)* OSSemDel()删除一个信号量(信号指针、删除条件、错误指针)* OSSemPend ()等待一个信号量函数(信号量指针、允许等待的时钟节拍、代码错误指针)* OSSemPost () 发出一个信号量函数(信号量指针)* OSSemQuery ()查询一个信号量的当前状态(信号量指针、状态数据结构指针)任务管理 (TASK MANAGEMENT)* OSTaskChangePrio()改变一个任务的优先级(任务旧的优先级、任务新的优先级)* OSTaskCreate ()建立任务(任务代码指针、传递参数指针、分配任务堆栈栈顶指针、任务优先级)* OSTaskCreateExt ()建立扩展任务(任务代码指针/传递参数指针/分配任务堆栈栈顶指针/分配任务优先级* OSTaskDel ()删除任务(任务的优先级)* OSTaskDelReq ()请求一个任务删除其它任务或自身?(任务的优先级)* OSTaskResume ()唤醒一个用OSTaskSuspend()函数挂起的任务(任务的优先级)* OSTaskStkChk ()检查任务堆栈状态(任务优先级、检验堆栈数据结构)* OSTaskSuspend () 无条件挂起一个任务(任务优先级)change改变\priority优先权\extend扩展\req请求\resume继续\check检查\suspend延缓时钟管理项 (TIME MANAGEMENT)* OSTimeDly ()任务延时函数(时钟节拍数)* OSTimeDlyHMSM ()将一个任务延时若干时间(设定时、分、秒、毫秒)* OSTimeDlyResume ()唤醒一个用OSTimeDly()或OSTimeDlyHMSM()函数的任务(优先级)* OSTimeGet ()获取当前系统时钟数值* OSTimeSet () 设置当前系统时钟数值混杂函数定义* OSInit()初始化UCOS-II函数* OSIntEnter()中断函数正在执行* OSIntExit()中断函数已经完成(脱离中断)* OSSchedLock()给调度器上锁* OSSchedUnlock()给调度器解锁* OSStart() 启动多个任务* OSStatInit()统计任务初始化* OSVersion()获得版本号Version版本\ lock锁定\unlock解锁各变量初始化情况变量值类型变量的说明*OSPrioCur 0 INT8U 正在运行的任务的优先级*OSPrioHighRdy 0 INT8U 具有最高优先级别的就绪任务的优先级*OSTCBDly INT16U 允许任务等待时的最多节拍数*OSTCBPrioTbl[ ] 任务控制块优先级表*OSTime 0L INT32U 表示系统当前时间(节拍数)*OSIntNesting 0 INT32U 存放中断嵌套的层数(0~255)*OSLockNesting 0 INT8U 调用了OSSchededLock的嵌套数*OSCtxSwCtr 0 INT32U 上下文切换的次数(统计任务计数器)*OSTtaskCtr 2 INT8U 已经建立的任务数*OSRunning FALSE BOOLEAN OS-II是否正在运行的标志*OSCPUUsage 0 INT8S 存放CPU的利用率(%)的变数*OSIdleCtrMax 0L INT32U 表示每秒空闲任务计数的最大值*OSIdleCtrRun 0L INT32U 表示空闲任务计数器每秒的计数值-----精心整理,希望对您有所帮助!。
uC/OS-II任务堆栈检验(OSTaskStkChk())
使用OSTaskStkChk()可以返回一个记录所检查堆栈空间的使用情况,包括已使用空间及
空闲空间的大小。
但只有用OSTaskCreateExt()建立的任务的堆栈才正常使用OSTaskStkChk()。
这个堆栈检验功能的原理很简单,因为OSTaskCreateExt()已经把任务堆栈
每个字节初始为0了,所以只需要从栈底依次扫描每个字节并计数直到当一个字节的内容不
为0,也即从这个字节起的空间已经至少被任务使用过了,得到的计数就是空闲空间的大小,使用空间的大小由栈的总大小减去空闲空间的大小就可以得到。
OSTaskStkChk(INT8U prio,OS_STK_DATA *pdata)
/*检查优先级为prio的任务的堆栈使用情况,并把结果存入OS_STK_DATA类型的单元中*/ INT8U OSTaskStkChk(INT8U prio,OS_STK_DATA *pdata)
{
OS_TCB *ptcb; /*用于执行所要堆栈检测任务的TCB*/
OS_STK *pchk; /*用于指向所要堆栈检测的任务的堆栈*/
INT32U free; /*存放未使用的堆栈容量*/
INT32U size; /*存放堆栈总容量*/
pdata->OSFree=0; /*将用于存放堆栈检测结果的单元进行清零*/
pdata->OSUsed=0;
if(prio>OS_LOWEST_PRIO &&prio != OS_PRIO_SELF)/*查看优先级是否在有效范围内*/ {
return(OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();/*在对任务的TCB内容读取的过程中需要关中断,即TCB是临界资源,不可多个进程同时访问*/
if (prio==OS_PRIO_SELF) /*如果prio的值为OS_PRIO_SELF 即prio==0xFF,系统规定优
先级为当前正在执行的任务*/
{
prio=OSTCBCur->OSTCBPrio;/*需要将prio的值更改为当前正在执行任务的优先级*/ }
ptcb=OSTCBPrioTbl[prio];/*根据任务的优先级和TCB优先级表,找到所要进程堆栈检测
任务的TCB*/
if(ptcb==(OS_TCB *)0) /*判断任务是否存在,这个是针对,如果所要检查的任务并不是正在执行的任务*/
{
OS_EXIT_CRITICAL(); /*任务不存在的话,要先开中断,然后再返回*/
return (OS_TASK_NOT_EXIST);
}
if((ptcb->OSTCBopt&OS_TASK_OPT_STK_CHK)==0) /*在任务存在的前提下,再查看该任务是否允许堆栈检测*/
{ /*OSTCBopt中的内容为0的话
OS_TACK_OPT_STK_CHK一定为零*/
OS_EXIT_CRITICAL(); /*而OS_TACK_OPT_STK_CHK为零的话,OSTCBopt不一定为零*/
return (OS_TASK_OPT_ERR);
}
/*通过上面的操作顺利找到了TCB,下面的操作就是读取TCB中相关的信息*/
free = 0; /*将需要存放空闲堆栈大小的单元清零*/ size = ptcb->OSTCBStkSize; /*读取任务的堆栈的大小*/
pchk = ptcb->OSTCBStkBottom; /*读取栈底堆栈的值*/
OS_EXIT_CRITICAL(); /*TCB中需要的信息已经读取完毕了,此时不需要再霸占TCB了,所以开中断*/
#if OS_STK_GROWTH == 1 /*根据系统硬件的情况,进行空闲堆栈的计算*/
while(*pchk++ == 0)
{
free++;
}
#else
while(*pchk-- == 0)
{
free++;
}
#endif
/*堆栈使用情况计算完毕,填写到所要存储的单元中,并返回堆栈查询没有出错*/
pdata->OSFree = free *sizeof(OS_STK);
pdata->OSUsed = (size-free) * sizeof(OS_STK);
return (OS_NO_ERR);
}
小结:
1.堆栈检查做了哪些事情:主要就是对所要堆栈检查的任务进行堆栈检查,并把检查结果存储在一个单元中*/
①堆栈检查需要的一些临时变量:指向TCB的指针,执行堆栈的指针,堆栈的大小的单元,空闲堆栈大小的单元
②操作:查找到TCB,通过TCB查找到任务的堆栈,对任务堆栈的情况进行计算。
2.堆栈检查具体执行的顺序:
①根据优先级以及TCB优先级表找到TCB,要判断:优先级是否有效;任务是否存在;任务是否允许进行堆栈检测;
②读取TCB中关于堆栈的信息:栈底的位置;堆栈的大小;
③计算空闲的堆栈,和以及使用的堆栈,并写入到给定的存储单元中。