嵌入式操作系统 2026 春季学期的重点。
本文连载于嵌入式操作系统-2026sp-重点 | HeZzz.
答案来源于 GPT-5.5 和 NotebookLM,并由我校对,可能不完全准确,仅供参考。
🙇♂️🙇♂️🙇♂️时间仓促,有不足之处烦请及时告知。邮箱hez2z@foxmail.com 或者在 速通之家 群里 @9¾。
第 2 章 uC/OS-II 中的任务
1. 任务的基本概念
- 定义与本质:从应用程序设计角度,μC/OS-II 的任务等同于一个线程。它是一个能对任务运行进行管理和调度的多任务操作系统。(来源:课件第2章 P.6)
- 任务的组成:μC/OS-II 的任务由以下三部分组成:
- 任务代码:任务的实际执行部分。
- 任务堆栈:用于保存任务运行时的上下文(即工作环境)。
- 任务控制块(OS_TCB):用于保存任务的属性信息。(来源:课件第2章 P.6)
- 任务的分类:分为用户任务(由应用程序设计者编写,用以解决应用问题)和系统任务(系统提供,为应用程序提供服务)。(来源:课件第2章 P.7)
- 数量上限:μC/OS-II V2.52 最多可管理 64 个任务,其中系统任务(预留) 8 个,用户任务最多可创建 56 个。(来源:课件第2章 P.7)
任务状态属性表
| 任务状态 | 英文名词 | 状态说明 |
|---|---|---|
| 睡眠状态 | Dormant | 任务代码驻留在存储器中,但尚未交给操作系统进行管理 |
| 就绪状态 | Ready | 任务已做好准备,等待分配 CPU 的使用权 |
| 运行状态 | Running | 任务获得了 CPU 的使用权,正在执行其代码 |
| 等待状态 | Waiting | 任务因延时、等待事件或手工挂起等原因,暂时让出 CPU 使用权 |
| 中断服务状态 | ISR | 正在运行的任务被中断打断,CPU 正在执行中断服务子程序 |
(来源:课件第2章 P.8, P.9)
- 用户任务一般结构:带有临界段保护的无限循环结构。在进入不可中断代码前使用 OS_ENTER_CRITICAL() 关中断,退出时使用 OS_EXIT_CRITICAL() 开中断。(来源:课件第2章 P.10)
- 系统任务详述:
- 空闲任务(
OSTaskIdle()):优先级被固定为最低的 OS_LOWEST_PRIO。当无任何用户任务可运行时系统便执行它。其主要工作是在临界区内递增计数器 OSIdleCtr。(来源:课件第2章 P.13, P.14) - 统计任务(
OSTaskStat()):每秒计算一次 CPU 的利用率,计算结果以百分比形式存放在变量 OSCPUUsage 中。启用此任务需将OS_CFG.H中的配置常数 OS_TASK_STAT_EN 设置为 1,且必须在创建此任务前调用 OSStatInit() 进行初始化。(来源:课件第2章 P.15)
- 空闲任务(
- 优先级规则:每个任务必须有唯一的优先级别。文件
OS_CFG.H中的常数 OS_LOWEST_PRIO 代表最低优先级。最低优先级OS_LOWEST_PRIO自动赋给空闲任务,次低优先级OS_LOWEST_PRIO-1自动赋给统计任务。(来源:课件第2章 P.16)
2. 任务堆栈
- 定义与作用:堆栈是存储器中按数据后进先出(LIFO)原则组织的连续存储空间。作用是满足任务切换和响应中断时保护 CPU 寄存器内容及存储任务私有数据的需要。(来源:课件第2章 P.18)
- 声明与关联:通过数据类型 OS_STK 声明堆栈数组(例如
OS_STK TaskStk[TASK_STK_SIZE])。在调用任务创建函数 OSTaskCreate() 时,将数组栈顶指针传递给参数ptos,从而将堆栈与任务关联。(来源:课件第2章 P.19) - 增长方向:随处理器不同而不同。分为“从低地址向高地址方向增长”(OS_STK_GROWTH=0)和“从高地址向低地址方向增长”(OS_STK_GROWTH=1)。(来源:课件第2章 P.22, P.10)
- 初始化函数:OSTaskStkInit() 在创建任务时被调用。其作用是预置任务堆栈的寄存器状态,使堆栈结构如同任务已经被中断打断过一样,以便任务首次调度时能通过出栈指令恢复执行。(来源:课件第2章 P.25, P.26)
3. 任务控制块
- 任务控制块 (OS_TCB):用来记录任务的堆栈指针、状态、优先级等与任务管理相关的属性表。(来源:课件第2章 P.27)
- OS_TCB 核心成员字段:
OSTCBStkPtr:指向任务堆栈栈顶的指针。OSTCBNext/OSTCBPrev:双向链表指针,用于连接所有处于非睡眠态的任务。OSTCBDly:任务等待的时限(单位:节拍数)。OSTCBStat:任务的当前状态标志。OSTCBPrio:任务的优先级别。OSTCBX/OSTCBY/OSTCBBitX/OSTCBBitY:用于快速访问就绪表的辅助数据。(来源:课件第2章 P.28)
- 任务状态取值 (OSTCBStat):包括 OS_STAT_RDY(就绪)、OS_STAT_SEM(等信号量)、OS_STAT_MBOX(等邮箱)、OS_STAT_Q(等队列)、OS_STAT_SUSPEND(挂起)、OS_STAT_MUTEX(等互斥信号量)。(来源:课件第2章 P.29)
- 双链表管理:初始化时系统创建单向的空任务控制块链表(OSTCBFreeList);当调用
OSTaskCreate()时,系统从空闲链表中取出一个节点,填入任务属性后,链入双向的任务控制块链表(OSTCBList)的头部。(来源:课件第2章 P.30, P.32) - OSTCBPrioTbl[]:以任务优先级为下标保存任务控制块指针的数组,用于快速检索指定优先级的 TCB。(来源:课件第2章 P.31)
4. 任务就绪表及其操作
-
就绪表结构:就绪表包含 1 字节的变量 OSRdyGrp 和大小为 8 字节的数组 OSRdyTbl[8]。(来源:课件第2章 P.36)
-
优先级映射:使用 6 位二进制数表示 0~63 优先级别。高 3 位代表数组元素的下标(组号),低 3 位代表数组元素中具体的数据位(位号)。(来源:课件第2章 P.40)
-
登记操作(将任务置为就绪):
OSRdyGrp |= OSMapTbl[prio >> 3];OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];(来源:课件第2章 P.43)
-
注销操作(使任务脱离就绪):
if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) OSRdyGrp &= ~OSMapTbl[prio >> 3];(来源:课件第2章 P.44)
-
快速检索最高优先级:为加快计算速度,系统使用预先定义好的大小为 256 的辅助数组 OSUnMapTbl[] 进行查表:
y = OSUnMapTbl[OSRdyGrp];prio = (y << 3) + OSUnMapTbl[OSRdyTbl[y]];(来源:课件第2章 P.45)
5. 任务调度、任务切换
- 调度思想:抢占式内核机制,每时每刻总是让优先级最高的就绪任务处于运行状态。(来源:课件第2章 P.35)
- 调度器的分类:
- 任务级调度器:由函数 OSSched() 运行。(来源:课件第2章 P.51)
- 中断级调度器:由函数 OSIntExit() 运行。(来源:课件第2章 P.51)
- 任务切换动作:由汇编编写的函数 OSCtxSw() 执行,包含以下 7 步:
- 被中止任务的断点指针 PC 压入任务堆栈。
- 通用寄存器内容保存至当前堆栈。
- 将堆栈指针 SP 当前值保存到对应 TCB 的
OSTCBStkPtr中。 - 获取待运行高优先级任务的 TCB 指针。
- 使 CPU 通过任务控制块获得待运行任务的堆栈指针,更新系统 SP。
- 恢复待运行任务堆栈中保存的通用寄存器内容。
- 出栈断点指针并跳转执行(RETI)。(来源:课件第2章 P.56, P.57)
6. 任务调度器函数 OSSched()
-
执行条件:当前没有在中断服务程序内(
OSIntNesting == 0)且调度器未被锁定(OSLockNesting == 0)。(来源:课件第2章 P.52) -
核心源码执行逻辑:
void OSSched(void) { // 关中断并保存状态 OS_ENTER_CRITICAL(); if ((OSLockNesting | OSIntNesting) == 0) { // 检查条件 y = OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); // 找最高优先级 if (OSPrioHighRdy != OSPrioCur) { // 若非当前运行任务 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; // 上下文切换计数器加 1 OS_TASK_SW(); // 激发切换宏 } } OS_EXIT_CRITICAL(); }(来源:课件第2章 P.52)
7. 任务创建
- 创建函数:主要使用 OSTaskCreate() 函数。其原型为:
INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);(来源:课件第2章 P.20) - 执行限制:在调用启动函数 OSStart() 之前,必须已经创建了至少一个用户任务。(来源:课件第2章 P.60)
- 一般方法:调用
OSStart()之前先创建一个最高优先级的起始任务TaskStart,在TaskStart中安装时钟并创建其他各个应用任务。(来源:课件第2章 P.60, P.61)
8. 任务的挂起和恢复
- 挂起任务 (OSTaskSuspend):强行剥夺当前任务的运行权并从就绪表中删除,使其进入等待状态。函数参数若为
OS_PRIO_SELF(0xFF),则表示挂起调用该函数自身。不能挂起空闲任务。(来源:课件第2章 P.67) - 恢复任务 (OSTaskResume):让被挂起的任务清除挂起标志。如果该任务已处于就绪状态,且优先级高于当前运行的任务,系统将引发一次调度。(来源:课件第2章 P.68)
9. 请求删除任务函数
- 安全删除原因:被动删除的任务往往存在其动态分配的局部资源未被释放的风险。(来源:课件第2章 P.75)
- 联络机制流程:
- 提出删除请求的任务 A 调用 OSTaskDelReq(prio),使目标任务 B 的 TCB 成员 OSTCBDelReq 被置为 OS_TASK_DEL_REQ。(来源:课件第2章 P.75, P.77)
- 被删除任务 B 在运行中查询
OSTCBDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ。一旦符合,B 任务主动释放占用的内存、信号量等资源,最后调用OSTaskDel(OS_PRIO_SELF)实施自我删除。(来源:课件第2章 P.75, P.78)
10. 任务初始化
- 初始化动作:由 OSInit() 函数完成。该函数执行以下操作:
- 对所有的全局变量和数据结构进行初始化。
- 创建空闲任务
OSTaskIdle并设置为最低优先级。 - 创建包括空任务控制块链表在内的 5 个空数据缓冲区链表。
- 建立数组
OSTCBPrioTbl[]。(来源:课件第2章 P.81)
第 3 章 uC/OS-II 的中断和时钟
1. 中断响应过程
- 流程步骤:CPU 接收到可屏蔽中断 -> 挂起当前任务 -> 将寄存器内容压入当前任务堆栈 -> 运行 OSIntEnter() -> 记录中断嵌套层数加 1 -> 保存 SP 指针 -> 重新开中断 -> 执行用户的 ISR 中断代码 -> 运行 OSIntExit()。 (来源:课件第3章 P.5, P.6)
- 中断级切换机制:如果就绪表中出现更高优先级就绪任务,
OSIntExit()将不会返回原先被中断的任务,而是调用 OSIntCtxSw() 切换至更高优先级的任务执行。(来源:课件第3章 P.3, P.9)
2. 临界段的概念
- 概念定义:在应用程序中,必须不受任何干扰地连续运行的代码段称为临界段。CPU 只有在中断开放期间才能响应中断请求。(来源:课件第3章 P.12)
- 实现方式:μC/OS-II 用 OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL() 两个宏来实现中断的开放和关闭。共有三种实现方法:
临界段保护三种方法对比表
| 选项方法 | 实现方式与编译设置 | 特点及潜在风险说明 |
|---|---|---|
| 方法 1 | 置 OS_CRITICAL_METHOD == 1;关中断 asm("DI"),开中断 asm("EI") | 直接进行开闭中断,若进入临界段前中断本就是关闭状态,退出时会强行开启中断 |
| 方法 2 | 置 OS_CRITICAL_METHOD == 2;进入时 asm("PUSH PSW"),退出时 asm("POP PSW") | 通过压栈/出栈恢复中断允许标志,可维持进入临界段前的原有状态 |
| 方法 3 | 置 OS_CRITICAL_METHOD == 3;进入时 cpu_sr = get_processor_psw(),退出时 set_processor_psw(cpu_sr) | 将状态保存在局部变量 cpu_sr 中,需编译器支持特定汇编语句与寄存器读取 |
(来源:课件第3章 P.13, P.14, P.15)
3. 时钟中断
- 节拍产生:时钟是任何系统处理时间相关事件(如延时)所必需的周期性信号源。系统采用硬件定时器产生毫秒级中断来实现时钟,最小时钟单位称为时钟节拍。(来源:课件第3章 P.16)
- 时钟服务函数 OSTimeTick() 的工作:
- 给时钟节拍计数器 OSTime 加 1。
- 遍历所有非空闲任务的 TCB,将其内部的延时递减常数 OSTCBDly 减 1。
- 若减至 0 且任务未被挂起,将其恢复为就绪态,并修改就绪表登记。(来源:课件第3章 P.16)
4. 延时函数
- 延时作用:主动调用延时可以让高优先级任务暂停运行并进行一次调度,防止其独占 CPU,让出使用权给其他就绪任务。(来源:课件第3章 P.20)
- OSTimeDly() 延时实现原理:
- 判断延时节拍数大于 0 后,进入临界段。
- 取消当前任务在就绪表中的就绪状态。
- 将延时节拍数
ticks写入当前任务控制块的OSTCBDly成员中。 - 退出临界段,调用调度器
OSSched()。(来源:课件第3章 P.21)
- 时分秒毫秒延时 OSTimeDlyHMSM():提供时、分、秒、毫秒为单位的更具可读性的延时输入方式。(来源:课件第3章 P.20)
- 恢复延时 OSTimeDlyResume():可手动使某个因延时而处于等待状态的任务取消延时,提前进入就绪态,若其优先级高于当前任务则立即引发调度。(来源:课件第3章 P.22)
第 4 章 任务的同步与通信
1. 任务同步
- 直接制约关系:源于任务之间相互合作,执行上具有先后次序。(来源:课件第4章 P.3)
- 间接制约关系:源于对共享资源的竞争,需要各任务间具有一种互斥关系。(来源:课件第4章 P.3)
- 同步定义:这种制约性的合作运行机制称为同步,系统中通过发送消息/信号来保证。(来源:课件第4章 P.3)
2. 事件
- 概念:在 μC/OS-II 中,使用信号量(计数器)、互斥信号量(二值)、邮箱(消息邮箱)和消息队列这些被称为事件的中间环节来实现任务间的同步与通信。(来源:课件第4章 P.4)
3. 事件控制块 (ECB)
-
核心结构体 OS_EVENT:
typedef struct { INT8U OSEventType; // 事件类型 INT16U OSEventCnt; // 信号量计数器 void *OSEventPtr; // 指向消息或消息队列的指针 INT8U OSEventGrp; // 等待事件的任务组变量 INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; // 等待事件的任务等待表 } OS_EVENT;(来源:课件第4章 P.12)
OSEventType 类型值可取范围表
| 事件常数 | 常数值说明 |
|---|---|
| OS_EVENT_TYPE_SEM | 表明事件是信号量 |
| OS_EVENT_TYPE_MUTEX | 表明事件是互斥信号量 |
| OS_EVENT_TYPE_MBOX | 表明事件是消息邮箱 |
| OS_EVENT_TYPE_Q | 表明事件是消息队列 |
| OS_ENENT_TYPE_UNUSED | 空事件控制块(未被使用的事件控制块) |
(来源:课件第4章 P.14)
- 空事件控制块链表:在
OSInit()初始化时由系统建立,数量为 OS_MAX_EVENTS 个,借用成员OSEventPtr将它们串联成一个单向空闲链表。(来源:课件第4章 P.23)
4. 事件的操作(创建、发送、请求)——以信号量为例
-
创建 OSSemCreate():
OS_EVENT *OSSemCreate(INT16U cnt);- 从空控制块链表中取出一个,将
OSEventType置为OS_EVENT_TYPE_SEM,OSEventCnt赋予计数初值cnt,并清空等待表。(来源:课件第4章 P.28, P.29)
- 从空控制块链表中取出一个,将
-
请求 OSSemPend():
void OSSemPend(OS_EVENT *pevent, INT16U timeout, INT8U *err);- 若计数器
OSEventCnt > 0,使其递减 1,任务继续运行。 - 若计数器为 0,则将当前任务加入到该事件的等待表
OSEventTbl中,置入等待状态,将等待时间timeout写入 TCB,然后执行调度。系统也提供了非堵塞查询获取函数OSSemAccept()。(来源:课件第4章 P.31, P.32)
- 若计数器
-
发送 OSSemPost():
INT8U OSSemPost(OS_EVENT *pevent);- 如果有任务在等待该信号量,唤醒其中优先级最高的一员,使其进入就绪表并调度;若无任务等待,则仅使计数器加 1。(来源:课件第4章 P.33)
-
删除 OSSemDel():仅能在任务中删除信号量,无法在中断服务程序中执行。(来源:课件第4章 P.34)
5. 优先级反转
- 概念:在可剥夺型内核中,当某任务以独占方式共享资源时,因低优先级任务占有了该资源且被中等优先级任务打断抢占,导致请求该资源的最高优先级任务因得不到资源而长期处于挂起状态。最终结果表现为低、中优先级任务反常地先于高优先级任务运行。(来源:课件第4章 P.37)
- 解决方案:使用具有优先级继承特性的互斥型信号量(Mutex)。当高优先级任务请求已被低优先级任务占有的资源时,临时提升低优先级任务的优先级至最高等级,使其快速运行完并释放资源后,再恢复原本优先级。其
OS_EVENT的OSEventCnt成员高 8 位用于存放防反转提起的优先级 prio,低 8 位存放可用标志(0xFF)。(来源:课件第4章 P.39, P.40)
6. 相关例题(例 8、例 9)
- 例 8(Slide 52):定义任务
MyTask和YouTask。MyTask内使用Times记录运行次数,将其指针作为消息发送至邮箱Str_Box:OSMboxPost(Str_Box, &Times)。YouTask调用OSMboxPend挂起接收,一旦获取此数据立即显示。 - 例 9(Slide 64~67):定义消息队列指针数组
Str_Q。在StartTask中利用OSTimeGet()的取值判定当前节拍,满足条件后分别将消息s0、s100、s1、s500发送至队列。任务MyTask与YouTask并行挂起调用OSQPend竞争获取打印。
第 5 章 信号量集
1. 信号量集
-
定义:又称事件标志组。任务可根据多个信号的组合状态(如多个事件同时发生或任意一个发生)进行同步。(来源:课件第5章 P.3)
-
信号量集标志组 (OS_FLAG_GRP):
typedef struct { INT8U OSFlagType; // 标志组标识 void *OSFlagWaitList; // 指向等待任务链表的双向节点头指针 OS_FLAGS OSFlagFlags; // 事件标志状态值(16位) } OS_FLAG_GRP;(来源:课件第5章 P.5)
-
等待节点结构 (OS_FLAG_NODE):用于组织正在等待信号量集的任务。其结构体包含双向节点指针、指向等待任务 TCB 的指针、信号过滤器(OSFlagNodeFlags)及逻辑运算关系(OSFlagNodeWaitType)。(来源:课件第5章 P.7, P.8)
信号量集逻辑关系与常数对照表
| 常用常数名 | 信号有效状态(标志位) | 等待任务就绪条件说明 |
|---|---|---|
| OS_FLAG_WAIT_CLR_ALL | 0 | 请求的所有标志位必须全为 0 |
| OS_FLAG_WAIT_CLR_ANY | 0 | 请求的标志位中,只要任意一个或一个以上为 0 即可 |
| OS_FLAG_WAIT_SET_ALL | 1 | 请求的所有标志位必须全为 1 |
| OS_FLAG_WAIT_SET_ANY | 1 | 请求的标志位中,只要任意一个或一个以上为 1 即可 |
(来源:课件第5章 P.9, P.15)
2. 信号量集的操作(创建、请求和发送)
-
创建 OSFlagCreate():
OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U *err);- 从空标志组链表中申请节点,给
OSFlagType填入标识,对当前状态标志值OSFlagFlags赋予初值,并将等待表头置为空指针。(来源:课件第5章 P.12)
- 从空标志组链表中申请节点,给
-
请求 OSFlagPend():
OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err);- 阻断或放行请求任务。如果不满足逻辑同步条件,则创建
OS_FLAG_NODE节点并链入该信号量集的等待链表,引发调度。(来源:课件第5章 P.14)
- 阻断或放行请求任务。如果不满足逻辑同步条件,则创建
-
发送 OSFlagPost():
OS_FLAGS OSFlagPost(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err);- 设置或清除
flags所指定的位。opt = OS_FLAG_SET为置 1 操作;opt = OS_FLAG_CLR为置 0 操作。之后系统重新检索链表并唤醒满足就绪条件的所有任务。(来源:课件第5章 P.16)
- 设置或清除
3. 相关例题(例 1、例 3)
- 例 1(Slide 18~21):任务
MyTask请求第 0 位和第 1 位标志必须同时为 1(OS_FLAG_WAIT_SET_ALL)。中等优先级的YouTask延时 8s 运行,将第 1 位置 1(值 2)。低优先级的HerTask每 1s 将第 0 位置 1(值 1)。当系统到达第 8s 时刻,YouTask 将第 1 位置 1,此时第 0 位和第 1 位标志皆为 1,MyTask立即获得运行机会。 - 例 3(Slide 23):通过分析黑板手绘的多任务状态转移逻辑,推算并验证在复杂的逻辑组合触发以及不同的任务延时配置下系统的优先级抢占时序。
第 6 章 内存的动态分配
1. 内存的管理
- 二级管理机制:为了克服在嵌入式系统中使用 C 标准
malloc函数产生大量内存碎片及分配时间不确定的弊端,系统将一大片连续的内存空间划分为若干个分区,每个分区又划分成若干个大小相等的内存块进行管理。(来源:课件第6章 P.2) - 分配准则:系统以分区为单位进行动态内存初始化,用户任务则以内存块为单位索取和释放动态内存。(来源:课件第6章 P.2)
2. 内存分区的组织
-
组织结构:同一个分区内所有未被申请的空闲内存块,通过单向链表连接在一起,块内存储下一块的首地址。(来源:课件第6章 P.4)
-
内存控制块 (OS_MEM) 成员:
typedef struct { void *OSMemAddr; // 内存分区的起始地址 void *OSMemFreeList; // 指向下一个空闲块单链表表头的指针 INT32U OSMemBlkSize; // 块长度 INT32U OSMemBlks; // 块总数 INT32U OSMemNFree; // 分区中目前可分配的空闲块数 } OS_MEM;(来源:课件第6章 P.5)
-
控制块初始化:系统在初始化阶段调用
OS_MemInit()创建包含 OS_MAX_MEM_PART 个空闲内存控制块单链表。(来源:课件第6章 P.6)
3. 动态内存的管理(创建、请求、释放)
-
创建内存分区 OSMemCreate():
OS_MEM *OSMemCreate(void *addr, INT32U nblks, INT32U blksize, INT8U *err);- 创建条件限制:分区内部包含的块数必须多于 1 个(
nblks > 1),且每个块的大小必须能至少存放一个指针(blksize >= sizeof(void *))。(来源:课件第6章 P.8, P.9)
- 创建条件限制:分区内部包含的块数必须多于 1 个(
-
请求内存块 OSMemGet():
void *OSMemGet(OS_MEM *pmem, INT8U *err);- 从指定的内存分区获取一内存块,若无空闲块返回空指针。(来源:课件第6章 P.11, P.12)
-
释放内存块 OSMemPut():
INT8U OSMemPut(OS_MEM *pmem, void *pblk);- 任务使用完缓冲区后将其归还到其所属的内存分区中,计数器递增。(来源:课件第6章 P.14)
-
例 1 与例 2 详述:
- 例 1(分区的定义与声明,Slide 10):定义
INT8U CommTxPart[50][64]划分 50 个 64 字节块。主函数调用CommTxBuffer = OSMemCreate(CommTxPart, 50, 64, &err)完成关联和初始化。 - 例 2(获取,Slide 13):定义
INT8U *BlkPtr接收申请。在任务循环中调用BlkPtr = OSMemGet(CommTxBuffer, &err),写入数据,使用完毕后调用OSMemPut(CommTxBuffer, BlkPtr)进行释放归还。
- 例 1(分区的定义与声明,Slide 10):定义