UCOS学习日(7)信号量集AND内存管理

信号量集的结构

有时候一个任务需要多个信号资源才可以进行,这时候我们就需要信号量
多个信号量之间也可以有逻辑运算,比如全0有效,一个0就有效。全1有效,一个1就有效

信号量的结构体叫标记组
UCOS学习日(7)信号量集AND内存管理
OSFlagFlags
是一个U16的变量,它是一个位图也就是说可以有16个信号

OSFlagType
是一个固定的宏OS_EVENT_TYPE_FLAGS

OSFlagWaitList
指向了该信号量集的所有等待任务 ,他们是一个链表

信号量集不是这一个结构体这么单纯
他还有一个结构体信号量集节点结构体。按照我的理解每一个等待信号量集的任务都是一个节点,这个节点里面有如下成员
UCOS学习日(7)信号量集AND内存管理
OSFlagNodeFlagGrp
该指针指向标记组结构体(也就是信号量集的指针)

OSFlagNodeFlags
信号过滤器

OSFlagNodeWaitType
定义逻辑运算关系

信号过滤器、逻辑运算关系、信号量位图三者之间的关系如下
UCOS学习日(7)信号量集AND内存管理
位图就算有信号也要过滤器允许,然后运算逻辑运算后任务才能获得信号量集,继续执行。
UCOS学习日(7)信号量集AND内存管理
UCOS学习日(7)信号量集AND内存管理

==信号量集链表的创建也是根据OS_MAX_FLAGS创建一个空白链表,如前面的一些任务链表,消息队列链表一样。

信号量集的操作

创建

UCOS学习日(7)信号量集AND内存管理
创建一个标记组,传入的形参flags是信号量位图的初始值
调用这个函数之前要创建一个全局OS_FLAG_GRP指针来指向这个标记组

请求信号量集

UCOS学习日(7)信号量集AND内存管理
请求那个位图的信号量,就在哪一位置1,比如请求第0位和第8位的信号量
falgs=9;
重点是滤波器和运算类型
运算类型
UCOS学习日(7)信号量集AND内存管理

发送信号量集

UCOS学习日(7)信号量集AND内存管理
发送信号和信号的有效选项是这样操作的
opt可以为OS_FLAG_SET置1或者OS_FLAG_CLR置0
flags为被操作位图中的位。
例如要对位图中第0位和第8位置1 那么
flags = 9;
opt = OS_FLAG_SET;

查询信号量

UCOS学习日(7)信号量集AND内存管理
查询的结果返回 16位的 位图

删除信号量

UCOS学习日(7)信号量集AND内存管理

动态内存管理

UCOS中的内存管理更具实时性,UCOS中把储存器的内存进行两级管理,操作系统将内存分成若干个分区,各个分区又有很多内存块。
内存分区和内存块的使用情况由内存控制块来记录

UCOS学习日(7)信号量集AND内存管理

UCOS中用一个OS_MEM(内存控制块)的结构体来管理控制

先定义一个二维数组int a[10][10],就表示这个内存分区有是个内存块,每个内存块40个字节。
UCOS学习日(7)信号量集AND内存管理
OSMemAddr 指向内存分区
OSMemFreeList 指向内存块链表的头链表

内存控制块链表

和信号量集,消息队列这些一样,都是在os_cfg.h中OS_MAX_MEM_PART定义好有多少个内存控制块,然后在OSInit()的时候就创建一个空白的内存控制块链表,需要内存控制块的时候就去,空白内存控制链表里取出一个,不用的时候就归还。

空白的内存控制块链表

UCOS学习日(7)信号量集AND内存管理

内存控制块操作函数

创建

UCOS学习日(7)信号量集AND内存管理
分区内存块至少要有两个,二是每个内存块的空间至少要能存放一个指针,因为内存分区中的内存块是一个链表,他们链接在一起

请求一个内存空间

UCOS学习日(7)信号量集AND内存管理
调用成功后,返回的指针是内存块的指针,如果调用失败这个指针就是一个NULL指针

释放一个内存块

UCOS学习日(7)信号量集AND内存管理
如果释放成功返回的宏就是OS_NO_ERR,或者是返回具体的错误宏。

查询一个内存分区的状态

UCOS学习日(7)信号量集AND内存管理
UCOS学习日(7)信号量集AND内存管理
调用成功后返回OS_NO_ERR宏,查询的信息结果放在上面这个结构体中。