首页 经典ucOS-II入门教程_第3章(共3章)

经典ucOS-II入门教程_第3章(共3章)

举报
开通vip

经典ucOS-II入门教程_第3章(共3章) Created with SmartPrinter trail version www.i-enet.com 第4章 任务的同步与通信 系统中的多个任务在运行时,经常需要互相 无冲突地访问同一个共享资源,或者需要互 相支持和依赖,甚至有时还要互相加以必要 的限制和制约,才保证任务的顺利运行。因 此,操作系统必须具有对任务的运行进行协 调的能力,从而使任务之间可以无冲突、流 畅地同步运行,而不致导致灾难性的后果。 与人们依靠通信来互相沟通,从而使人际关 系和谐、工作顺利的做法一样,计算机系统 是依靠任务之间的良...

经典ucOS-II入门教程_第3章(共3章)
Created with SmartPrinter trail version www.i-enet.com 第4章 任务的同步与通信 系统中的多个任务在运行时,经常需要互相 无冲突地访问同一个共享资源,或者需要互 相支持和依赖,甚至有时还要互相加以必要 的限制和制约,才保证任务的顺利运行。因 此,操作系统必须具有对任务的运行进行协 调的能力,从而使任务之间可以无冲突、流 畅地同步运行,而不致导致灾难性的后果。 与人们依靠通信来互相沟通,从而使人际关 系和谐、工作顺利的做法一样,计算机系统 是依靠任务之间的良好通信来保证任务与任 务的同步的。 例如,两个任务:任务A和任务B,它们 需要通过访问同一个数据缓冲区合作完 成一项工作,任务A负责向缓冲区写入 数据,任务B负责从缓冲区读取该数据。 显然,当任务A还未向缓冲区写入数据 时(缓冲区为空时),任务B因不能从 缓冲区得到有效数据而应该处于等待状 态,只有等任务A向缓冲区写入了数据 之后,才应该通知任务B去取数据。 例如,任务A和任务B共享一台打印机, 如果系统已经把打印机分配给了任务 A,则任务B因不能获得打印机的使用权 而应该处于等待状态,只有当任务A把 打印机释放后,系统才能唤醒任务B使 其获得打印机的使用权。如果这两个任 务不这样做,那么也会造成极大的混乱 。 总之,多个任务共享同一资源或有工作 顺序要求时,在正式工作之前要互相打 招呼。 黄宏:别走啊! 宋丹丹:我自己的腿,我爱走就走,你管不着! 黄宏:腿是你自己的,但手是咱俩的呀! Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 事件 任务间的同步依赖于任务间的通信。 在μC/OS-II中,是使用信号量、邮 箱(消息邮箱)和消息队列这些被 称作事件的中间环节来实现任务之 间的通信的。 宋丹丹黄宏 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 一个简单的信号量 1/0 收信方发信方 共享资源 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 事件控制块 为了把描述事件的数据结构统一起来, μC/OS-II使用叫做事件控制块ECB的数 据结构来描述诸如信号量、邮箱(消息 邮箱)和消息队列这些事件。事件控制 块中包含包括等待任务 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 在内的所有有 关事件的数据 typedef struct { INT8U OSEventType; //事件的类型 INT16U OSEventCnt; //信号量计数器 void *OSEventPtr; //消息或消息队列的指针 INT8U OSEventGrp; //等待事件的任务组 INT8U OSEventTbl[OS_EVENT_TBL_SIZE];//任务等待表 } OS_EVENT; 把 一 个 任 务 置 于 等 待 状 态 要 调 用 OS_EventTaskWait( )函数。该函数的原型为: void OS_EventTaskWait ( OS_EVENT *pevent //事件控制块的指针 ); 函数OS_EventTaskWait ( ),将在任务调用函数 OS×××Pend( ) 请 求 一 个 事 件 时 , 被 OS×××Pend( )所调用。 如果一个正在等待的任务具备了可以运行的条件,那么就要使 它进入就绪状态。这时要调用OS_EventTaskRdy( )函数。该函 数的作用就是把调用这个函数的任务在任务等待表中的位置清 0(解除等待状态)后,再把任务在任务就绪表中对应的位置 1,然后引发一次任务调度。 OS_EventTaskRdy( )函数的原型为: INT8U OS_EventTaskRdy ( OS_EVENT *pevent, //事件控制块的指针 void *msg, //未使用 INT8U msk //清除TCB状态标志掩码 ); 函数OS_EventTaskRdy ( )将在任务调用函数OS×××Post ( ) 发 送一个事件时,被函数OS×××Post ( )所调用。 如果一个正在等待事件的任务已经超过了等待的时间, 却仍因为没有获取事件等原因而未具备可以运行的条 件 , 却 又 要 使 它 进 入 就 绪 状 态 , 这 时 要 调 用 OS_EventTO( )函数。 OS_EventTO( )函数的原型为: void OS_EventTO ( OS_EVENT *pevent //事件控制块的指针 ); 函数OS_EventTO ( )将在任务调用OS×××Pend( ) 请求 一个事件时,被函数OS×××Pend( )所调用。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 空事件控制块链表 在μC/OS-II初始化时,系统会在初始化函数 OSInit( )中按应用程序使用事件的总数 OS_MAX_EVENTS(在文件OS_CFG.H中定 义),创建OS_MAX_EVENTS个空事件控制块 并借用成员OSEventPtr作为链接指针,把这些空 事件控制块链接成一个单向链表。由于链表中 的所有控制块尚未与具体事件相关联,故该链 表叫做空事件控制块链表。以后,每当应用程 序创建一个事件时,系统就会从链表中取出一 个空事件控制块,并对它进行初始化以描述该 事件。而当应用程序删除一个事件时,就会将 该事件的控制块归还给空事件控制块链表 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 信号量及其操作 在使用信号量之前,应用程序必须调用函数 OSSemCreate( ) 来 创 建 一 个 信 号 量 , OSSemCreate( )的原型为: OS_EVENT *OSSemCreate ( INT16U cnt //信号量计数器初值 ); 函数的返回值为已创建的信号量的指针。 任务通过调用函数OSSemPend( )请求信号量,函数 OSSemPend( )的原型如下: void OSSemPend ( OS_EVENT *pevent, //信号量的指针 INT16U timeout, //等待时限 INT8U *err); //错误信息 参数pevent是被请求信号量的指针。 为防止任务因得不到信号量而处于长期的等待状态,函 数OSSemPend允许用参数timeout设置一个等待时间的限 制,当任务等待的时间超过timeout时可以结束等待状态 而进入就绪状态。如果参数timeout被设置为0,则表明任 务的等待时间为无限长。 任务获得信号量,并在访问共享资源结束以后,必须要释放信 号量,释放信号量也叫做发送信号量,发送信号量需调用函数 OSSemPost ( )。OSSemPost ( )函数在对信号量的计数器操作之 前,首先要检查是否还有等待该信号量的任务。如果没有,就 把信号量计数器OSEventCnt加一;如果有,则调用调度器 OS_Sched( )去运行等待任务中优先级别最高的任务。 函数OSSemPost ( )的原型为: INT8U OSSemPost ( OS_EVENT *pevent //信号量的指针 ); 调用函数成功后,函数返回值为OS_ON_ERR,否则会根据具 体错误返回OS_ERR_EVENT_TYPE、OS_SEM_OVF。 应用程序如果不需要某个信号量了,那么可以调用函数 OSSemDel( )来删除该信号量,这个函数的原型为: OS_EVENT *OSSemDel ( OS_EVENT *pevent, //信号量的指针 INT8U opt, //删除条件选项 INT8U *err //错误信息 ); Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 互斥型信号量和 任务优先级反转 在可剥夺型内核中,当任务以独占 方式使用共享资源时,会出现低优 先级任务先于高优先级任务而被运 行的现象,这种现象叫做任务优先 级反转。在一般情况下是不允许出 现这种任务优先级反转现象的,下 面就对优先级的反转现象做一个详 细的分析,以期找出原因及解决方 法。 图4-15描述了A、B、C三个任务的运行 情况。其中,任务A的优先级别高于任 务B,任务B的优先级别高于任务C。任 务A和任务C都要使用同一个共享资源 S,而用于保护该资源的信号量在同一 时间只能允许一个任务以独占的方式对 该资源进行访问,即这个信号量是一个 互斥型信号量。 通过例子可以发现,使用信号量的任务是 否能够运行是受任务的优先级别和是否占 用信号量两个条件约束的,而信号量的约 束高于优先级别的约束。于是当出现低优 先级别的任务与高优先级别的任务使用同 一个信号量,而系统中还存有别的中等优 先级别的任务时,如果低优先级别的任务 先获得了信号量,就会使高级别的任务处 于等待状态,而那些不使用该信号量的中 等级别的任务却可以剥夺低优先级别的任 务的CPU使用权而先于高优先级别的任务而 运行了。 解决问题的办法之一,是使获得信号量任 务的优先级别在使用共享资源期间暂时提 升到所有任务最高优先级的高一个级别 上,以使该任务不被其他的任务所打断, 从而能尽快地使用完共享资源并释放信号 量,然后在释放了信号量之后再恢复该任 务原来的优先级别。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 互斥型信号量 在描述互斥型信号量的事件控制块中,除了 成员OSEventType要赋以常数 OS_EVENT_TYPE_MUTEX以表明这是一 个互斥型信号量和仍然没有使用成员 OSEventPtr之外,成员OSEventCnt被分成了 低8位和高8位两部分:低8位用来存放信 号值(该值为0xFF时,信号为有效,否则 信号为无效),高8位用来存放为了避免出 现优先级反转现象而要提升的优先级别prio。 创建互斥型信号量需要调用函数OSMutexCreate( )。函数 OSMutexCreate( )的原型如下: OS_EVENT *OSMutexCreate ( INT8U prio, //优先级别 INT8U *err //错误信息 ); 函数OSMutexCreate( )从空事件控制块链表获取一个事件控制 块,把成员OSEventType赋以常数OS_EVENT_TYPE_MUTEX 以表明这是一个互斥型信号量,然后再把成员OSEventCnt的高 8位赋以 prio(欲提升的优先级别),低 8位赋以常数 OS_MUTEX_AVAILABLE(该常数值为 0xFFFF)的低8位 (0xFF)以表明信号量尚未被任何任务所占用,处于有效状态。 当任务需要访问一个独占式共享资源时,就要调用函 数OSMutexPend( )来请求管理这个资源的互斥型信号 量,如果信号量有信号(OSEventCnt的低 8位为 0xFF),则意味着目前尚无任务占用资源,于是任务 可以继续运行并对该资源进行访问,否则就进入等待 状态,直至占用这个资源的其他任务释放了该信号量。 函数OSMutexPend( )的原型为: void OSMutexPend ( OS_EVENT *pevent, //互斥型信号量指针 INT16U timeout, //等待时限 INT8U *err //错误信息 ); 任务可以通过调用函数OSMutexPost( )发送一个互斥型信 号量,这个函数的原型为: INT8U OSMutexPost ( OS_EVENT *pevent //互斥型信号量指针 ); Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 消息邮箱及其操作 如果把数据缓冲区的指针赋给一个事件 控制块的成员OSEventPrt,同时使事件 控制块的成员OSEventType为常数 OS_EVENT_TYPE_MBOX,则该事件 控制块就叫做消息邮箱,消息邮箱是在 两个需要通信的任务之间通过传递数据 缓冲区指针的方法来通信的。 创建邮箱需要调用函数OSMboxCreate ( ),这个函 数的原型为: OS_EVENT *OSMboxCreate ( void *msg //消息指针 ); 函数中的参数msg为消息的指针,函数的返回值为 消息邮箱的指针。 调用函数OSMboxCreate ( )需先定义msg的初始值。 在一般的情况下,这个初始值为NULL;但也可以 事先定义一个邮箱,然后把这个邮箱的指针作为 参数传递到函数OSMboxCreate ( )中,使之一开始 就指向一个邮箱。 任务可以通过调用函数OSMboxPost ( )向消息邮箱发送 消息,这个函数的原型为: INT8U OSMboxPost ( OS_EVENT *pevent, //消息邮箱指针 void *msg //消息指针 ); 当一个任务请求邮箱时需要调用函数OSMboxPend( ),这 个函数的主要作用就是查看邮箱指针OSEventPtr是否为 NULL,如果不是NULL就把邮箱中的消息指针返回给调 用函数的任务,同时用OS_NO_ERR通过函数的参数err通 知任务获取消息成功;如果邮箱指针OSEventPtr是 NULL,则使任务进入等待状态,并引发一次任务调度。 函数OSMboxPend( )的原型为: void *OSMboxPend ( OS_EVENT *pevent, //请求消息邮箱指针 INT16U timeout, //等待时限 INT8U *err //错误信息 ); Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 消息队列及其操作 使用消息队列可以在任务之间传递多条消息。消 息队列由三个部分组成:事件控制块、消息队列 和消息。 当 把 事件 控制 块 成员 OSEventType的值 置为 OS_EVENT_TYPE_Q时,该事件控制块描述的就 是一个消息队列。 消息队列的数据结构如图4-21所示。从图中可以看 到,消息队列相当于一个共用一个任务等待列表 的消息邮箱数组,事件控制块成员OSEventPtr指向 了一个叫做队列控制块(OS_Q)的结构,该结构 管理了一个数组MsgTbl[ ],该数组中的元素都是 一些指向消息的指针。 其中,可以移动的指针为OSQIn和OSQOut,而指针 OSQStart和OSQEnd只是一个标志(常指针)。当可移动的 指针OSQIn或OSQOut移动到数组末尾,也就是与OSQEnd 相等时,可移动的指针将会被调整到数组的起始位置 OSQStart。也就是说,从效果上来看,指针OSQEnd与 OSQStart等值。于是,这个由消息指针构成的数组就头尾 衔接起来形成了一个如图所示的循环的队列。 为了对图所示的消息指针数组进行有效的管理, μC/OS-II把消息指针数组的基本参数都记录在一个 叫做队列控制块的结构中,队列控制块的结构如下: typedef struct os_q { struct os_q *OSQPtr; void **OSQStart; void **OSQEnd; void **OSQIn; void **OSQOut; INT16U OSQSize; INT16U OSQEntries; } OS_Q; 在μC/OS-II初始化时,系统将按文件 OS_CFG.H中的配置常数OS_MAX_QS定 义OS_MAX_QS个队列控制块,并用队列 控制块中的指针OSQPtr将所有队列控制块 链接为链表。由于这时还没有使用它们, 故这个链表叫做空队列控制块链表 创建一个消息队列首先需要定义一指针数组,然后把各 个消息数据缓冲区的首地址存入这个数组中,然后再调 用函数OSQCreate( )来创建消息队列。创建消息队列函数 OSQCreate( )的原型为: OS_EVENT OSQCreate( void**start, //指针数组的地址 INT16U size //数组长度 ); 请求消息队列的目的是为了从消息队列中获取消息。任务 请求消息队列需要调用函数OSQPend( ),该函数的原型为: void*OSQPend( OS_EVENT*pevent, //所请求的消息队列的指针 INT16U timeout, //等待时限 INT8U*err //错误信息 ); 任务需要通过调用函数OSQPost( )或OSQPostFront( )来向消 息队列发送消息。函数OSQPost( )以FIFO(先进先出)的方 式组织消息队列,函数OSQPostFront( )以LIFO(后进先出) 的方式组织消息队列。这两个函数的原型分别为: INT8U OSQPost( OS_EVENT*pevent, //消息队列的指针 void*msg //消息指针 ); 和 INT8U OSQPost( OS_EVENT*pevent, //消息队列的指针 void*msg //消息指针 ); 函数中的参数msg为待发消息的指针。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 信号量集 在实际应用中,任务常常需要与多个事件同步, 即要根据多个信号量组合作用的结果来决定任务 的运行方式。μC/OS-II为了实现多个信号量组合 的功能定义了一种特殊的数据结构——信号量集。 信号量集所能管理的信号量都是一些二值信号, 所有信号量集实质上是一种可以对多个输入的逻 辑信号进行基本逻辑运算的组合逻辑,其示意图 如图5-1所示 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 信号量集的标志组 不同于信号量、消息邮箱、消息队列等事件,μC/OS-II 不使用事件控制块来描述信号量集,而使用了一个叫做 标志组的结构OS_FLAG_GRP。 OS_FLAG_GRP结构如下: typedef struct{ INT8U OSFlagType; //识别是否为信号量集的标志 void *OSFlagWaitList;//指向等待任务链表的指针 OS_FLAGS OSFlagFlags; //所有信号列表 }OS_FLAG_GRP; 成员OSFlagWaitList是一个指针,当一个信号量集被创建 后,这个指针指向了这个信号量集的等待任务链表。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 等待任务链表 与其他前面介绍过的事件不同,信号量集用一个双向链表来 组织等待任务,每一个等待任务都是该链表中的一个节点 (Node)。标志组OS_FLAG_GRP的成员OSFlagWaitList就 指向了信号量集的这个等待任务链表。 等待任务链表节点OS_FLAG_NODE的结构如下: typedef struct { void *OSFlagNodeNext; //指向下一个节点的指针 void *OSFlagNodePrev; //指向前一个节点的指针 void *OSFlagNodeTCB; //指向对应任务控制块的指针 void *OSFlagNodeFlagGrp; //反向指向信号量集的指针 OS_FLAGS OSFlagNodeFlags; //信号过滤器 INT8U OSFlagNodeWaitType;//定义逻辑运算关系的数据 } OS_FLAG_NODE; 给等待任务链表添加节点的函数为OS_FlagBlock( ),这个函数 的原型为: static void OS_FlagBlock ( OS_FLAG_GRP *pgrp, //信号量集指针 OS_FLAG_NODE *pnode, //待添加的等待任务节点指针 OS_FLAGS flags, //指定等待信号的数据 INT8U wait_type, //信号与等待任务之间的逻辑 INT16U timeout //等待时限 ); 这个函数将在请求信号量集函数OSFlagPend ( )中被调用。 从 等 待 任 务 链 表 中 删 除 一 个 节 点 的 函 数 为 OS_FlagUnlink( ),这个函数的原型为: void OS_FlagUnlink (OS_FLAG_NODE *pnode); 这个函数将在发送信号量集函数OSFlagPost( )中被调用。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 信号量集的操作 任务可以通过调用函数OSFlagCreate ( )来创建一个 信号量集。OSFlagCreate ( )的函数原型为: OS_FLAG_GRP *OSFlagCreate ( OS_FLAGS flags, //信号的初始值 INT8U *err //错误信息 ); 任务可以通过调用函数OSFlagPend( )请求一个信号量 集,OSFlagPend( )函数的原型为: OS_FLAGS OSFlagPend ( OS_FLAG_GRP *pgrp, //所请求的信号量集指针 OS_FLAGS flags, //滤波器 INT8U wait_type, //逻辑运算类型 INT16U timeout, //等待时限 INT8U *err //错误信息 ); 任务可以通过调用函数OSFlagPost ( )向信号量集发信号, OSFlagPost ( )函数的原型为: OS_FLAGS OSFlagPost ( OS_FLAG_GRP *pgrp, //信号量集指针 OS_FLAGS flags, //选择所要发送的信号 INT8U opt, //信号有效的选项 INT8U *err //错误信息 ); 所谓任务向信号量集发信号,就是对信号量集标志组中的信 号进行置“1”(置位)或置“0”(复位)的操作。至于对信号量 集中的哪些信号进行操作,用函数中的参数flags来指定;对指 定的信号是置“1”还是置“0”,用函数中的参数opt来指定(opt = OS_FLAG_SET为置“1”操作;opt = OS_FLAG_CLR为置“0” 操作)。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 第6章 内存的 动态分配 应用程序在运行中为了某种特殊需要,经常 需要临时获得一些内存空间,因此作为一个 比较完善的操作系统必须具有动态分配内存 的能力。 能否合理、有效地对内存储器进行分配和管 理,是衡量一个操作系统品质的指标之一。 特别地对于实时操作系统来说,还应该保证 系统在动态分配内存时,它的执行时间必须 是可确定的。μC/OS-II改进了ANSI C用来动 态分配和释放内存的malloc( )和free( )函数, 使它们可以对大小固定的内存块进行操作, 从而使 malloc( )和free( )函数的执行时间成为 可确定的,满足了实时操作系统的要求。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 内存控制块 μC/OS-II对内存进行两级管理,即把一个大 片连续的内存空间分成了若干个分区,每个 分区又分成了若干个大小相等的内存块来进 行管理。操作系统以分区为单位来管理动态 内存,而任务以内存块为单位来获得和释放 动态内存。内存分区及内存块的使用情况则 由表——内存控制块来记录。 本节首先介绍内存分区和分区中的内存块, 然后再介绍内存控制块。 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 可动态分配内存的划分 应用程序如果要使用动态内存的话,则要首先在内存中划分 出可以进行动态分配的区域,这个划分出来区域叫做内存分 区,每个分区要包含若干个内存块。μC/OS-II要求同一个分 区中的内存块的字节数必须相等,而且每个分区与该分区的 内存块的数据类型必须相同。 在内存中划分一个内存分区与内存块的方法非常简单,只要 定义一个二维数组就可以了,其中的每个一维数组就是一个 内存块。例如,定义一个用来存储INT16U类型数据,有10个 内存块,每个内存块长度为10的内存分区的代码如下: INT16U IntMemBuf[10][10]; 需要注意的是,上面这个定义只是在内存中划分出了分区及 内存块的区域,还不是一个真正的可以动态分配的内存区, 如图6-1(a)所示。只有当把内存控制块与分区关联起来之后, 系统才能对其进行相应的管理和控制,它才能是一个真正的 动态内存区 为了使系统能够感知和有效地管理内存分区,μC/OS-II给每个 内存分区定义了一个叫做内存控制块(OS_MEM)的数据结构。 系统就用这个内存控制块来记录和跟踪每一个内存分区的状态。 内存控制块的结构如下: typedef struct { void *OSMemAddr; //内存分区的指针 void *OSMemFreeList; //内存控制块链表的指针 INT32U OSMemBlkSize; //内存块的长度 INT32U OSMemNBlks; //分区内内存块的数目 INT32U OSMemNFree; //分区内当前可分配的内存块的数目 } OS_MEM; 当应用程序调用函数OSMemCreate( )建立了一个内存分区之后, 内存控制块与内存分区和内存块之间的关系如图 Created with SmartPrinter trail version www.i-enet.com Created with SmartPrinter trail version www.i-enet.com 动态内存的管理 划分了欲使用的分区和内存块之后,应用程序可以通过 调用函数 OSMemCreate( )来建立一个内存分区, OSMemCreate( ) 函数的原型为: OS_MEM *OSMemCreate( void*addr, //内存分区的起始地址 INT32U nblks, //分区中内存块的数目 INT32U blksize, //每个内存块的字节数 INT8U *err //错误信息 ); 在应用程序需要一个内存块时,应用程序可以通过调用函 数OSMemGet( )向某内存分区请求获得一个内存块, OSMemGet( )函数的原型为: void *OSMemGet ( OS_MEM *pmem, //内存分区的指针 INT8U *err //错误信息 ); 当应用程序不再使用一个内存块时,必须要及时地将它 释放。应用程序通过调用函数OSMemPut( )来释放一个 内存块,OSMemPut( )函数的原型为: INT8U OSMemPut ( OS_MEM *pmem, //内存块所属内存分区的指针 void *pblk //待释放内存块的指针 ); 应用程序可以通过调用函数OSMemQuery( )来查询一个分区目 前的状态信息,函数函数OSMemQuery( )的原型为: INT8U OSMemQuery ( OS_MEM *pmem, //待查询的内存控制块的指针 OS_MEM_DATA *pdata//存放分区状态信息的结构的指针 ) 其中参数pdata是一个OS_MEM_DATA类型的结构,该结构的定 义如下: typedef struct { void *OSAddr; //内存分区的指针 void *OSFreeList; //分区内内存块链表的头指针 INT32U OSBlkSize; //内存块的长度 INT32U OSNBlks; //分区内内存块的数目 INT32U OSNFree; //分区内空闲内存块的数目 INT32U OSNUsed; //已被分配的内存块数目 } OS_MEM_DATA; Created with SmartPrinter trail version www.i-enet.com
本文档为【经典ucOS-II入门教程_第3章(共3章)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_553323
暂无简介~
格式:pdf
大小:704KB
软件:PDF阅读器
页数:18
分类:互联网
上传时间:2011-11-08
浏览量:27