第7章 任务的同步与通讯之信号量
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
.OSEventTbl[]
} OS_EVENT;
63 62 61 60 59 58 57 56
定义在文件µc/os-II.H中定义
事件类型OSEventType
• #define OS_EVENT_TYPE_UNUSED • #define OS_EVENT_TYPE_MBOX • #define OS_EVENT_TYPE_Q • #define OS_EVENT_TYPE_SEM • #define OS_EVENT_TYPE_MUTEX • #define OS_EVENT_TYPE_FLAG 0 1 2 3 4 5
0x000A
NULL 0x00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
一个刚创建且计数器初值为10的信号量
举例
Os_Event pevent .OS_Event_Type_SEM 3 .OSEventPtr 0x07
列表中删除一个任务的算法则正好相反,如下所示。 if ((pevent->OSEventTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) {
pevent->OSEventGrp &= ~OSMapTbl[prio >> 3];
} • 等待任务列表中查找最高优先级的任务程序清单如下。
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1. 信号量的值是多少? 2. 有任务等待信号灯?如 果有,优先级是多少?
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
建立一个信号量,OSSemCreate()
OSSemCreate()的原型如下: OS_EVENT *OSSemCreate(INT16U value);
• 返回值: OS_NO_ERR 表示调用成功。 OS_ERR_EVENT_TYPE 表示未向信号量传递指针。
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
第7章 任务的同步与通信
基本概念 µc/os-II的通讯方式
互斥与同步
并发任务之间必须建立一些制约关系。其中一种制约关系叫做直接制
约关系,另一种制约关系叫做间接制约关系。
互斥由资源共享 引起的
即对于某个共享资源,如果一个任务正在使用, 则其他任务只能等待,等到该任务释放该资源后, 等待的任务之一才能使用它,进程间的这种相互制 约关系称为互斥
y = OSUnMapTbl[pevent->OSEventGrp];
x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (y << 3) + x;
空事件控制块链表
μC/OS-II的初始化形成这个表
OS_CFG.H 中的#define OS_MAX_EVENTS定义最大事件
消息邮箱 消息队列 信号量 互斥信号量 信号量集
事件的等待任务列表
等待任务列表操作
将任务置于等待事件的任务列表中的代码如下: pevent->OSEventGrp |= OSMapTbl[prio >> 3]; pevent->OSEventTbl[prio >> 3] |= OSMapTbl[prio & 0x07];
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
等待一个信号量,OSSemPend()
OSSemPend()函数原型如下: void OSSemPend ( OS_EVNNT *pevent, INT16U timeout, int8u *err );
删除一个信号量,OSSemDel()
OSSemDel()的函数原型如下: OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *err);
• 参数:
pevent,指向信号量的指针。 opt,该项定义信号量的删除条件。若当等待任务表中已没有等待任务 时才删除信号量,opt选择OS_DEL_NO_PEND,若在等待任务表中无论是 否有等待任务都立即删除信号量,opt选择OS_DEL_ALWAYS。
INT8U OSEventGrp; /* 等待任务所在的组 */ INT16U OSEventCnt; /* 计数器(当事件是信号量时) */
void *OSEventPtr; /* 指向消息或者消息队列的指针 */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* 等待任务列表 */
OSSemQuery()函数原型如下: INT8U OSSemQuery(OS_EVENT *pevent, OS_SEM_DATA *pdata);
参数: pevent:一个指向信号量的指针。 pdata:一个指向数据结构OS_SEM_DATA的指针,该数据结构包含下 述域: • INT16U OSCnt; /* 当前信号量标识号码 */ • INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /*信号量等待队列*/ • INT8U OSEventGrp;
.OSEventTbl[]
0 0 0 0 0
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
• 信号量 • 邮箱 • 消息队列
第7章 任务的同步与通信
基本概念 µc/os-II的通讯方式
µc/os-II的通讯方式
• 信号量机制 • 互斥型信号量 • 信号量集机制 • 消息邮箱 • 消息队列
在µc/os-II中,任务之间的通信是利用事件来实现的
两个任务使用事件进行通信的示意图
发送事件
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
发出一个信号量OSSemPost()
.OSEventTbl[]
63
62
61
60
59
58
57
56
举例
OSSemCreate(10)
pevent OSEventCnt OSEventPtr OSEventGrp 0 任 务 等 待 表 0 0 OSEventTbl[ ] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 OS_EVENT_TYPE_SEM
参数:
pevent:指向信号量的指针。
timeout:允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的 信号量时恢复运行状态。如果该值为0则表示任务将持续的等待信号量。最大
的等待时间为65535个时钟节拍。 err: 指向包含错误码的变量的指针 OS_NO_ERR :信号量不为0。 OS_TIMEOUT :信号量没有在指定的周期数内置起。 OS_ERR_PEND_ISR :从中断调用该函数。虽然规定了不允许从中断 调用该函数,但μC/OS-Ⅱ仍然包含了检测这种情况的功能。 OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针。
Os_Event pevent .OSEventType .OSEventCnt .OSEventPtr .OSEventGrp
7 6 5 4 3 2 1 0
• 参数:
value表示建立的信号量的初始值,可 以是0~65535的任何值。 • 返回值:
OSSemCreate()返回指向事件控制块的 指针。如果没有可用的事件控制块, OSSemCreate()函数返回空指针。
同步由合作引起
相关的任务在执行上要有先后次序,一个任务要 等其伙伴发来通知,或建立了某个条件后才能继续 执行,否则只能等待。这种关系称为进程同步
通信
• 在多任务实时系统中,经常需要在任务之间或者中断服务之 间进行传递消息,这种消息传递机制被称为任务间的通信。
传递消息的办法:
全局变量 各种消息机制:
对事件控制块进行的操作一般包括:
初始化一个事件控制块。 使一个任务进入就绪态。 使一个任务进入等待某事件的状态。 因为等待超时而使一个任务进入就绪态。
以上的操作都隐含在不同的通讯方式的操作中!
主要内容
• 信号量机制 • 互斥型信号量 • 信号量百度文库机制 • 消息邮箱 • 消息队列
μC/OS-II信号量的数据结构
err, 指向包含错误码的变量的指针。返回的错误码可能为下述几种之一。 OS_NO_ERR,调用成功,信号量已被删除。 OS_ERR_DEL_ISR,试图在中断服务子程序中删除信号量。 OS_ERR_INVALID_OPT,没有将opt参数定义为2种合法参数之一。 OS_ERR_TASK_WAITING,有一个或一个以上的任务在等待信号量。
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
查询一个信号量的当前状态,OSSemQuery()
typedef struct { INT8U OSEventType; /* 事件类型 */
OS_EVENT_TYPE_SEM
INT8U OSEventGrp; /* 等待任务所在的组 */
INT16U OSEventCnt;
/* 计数器(当事件是信号量时) */
void *OSEventPtr; /* 指向消息或者消息队列的指针 */
请求事件
任务1
事件
任务2
每个事件用一个数据结构事件控制块ECB
事件控制块结构
typedef struct { INT8U OSEventType; /* 事件类型 */
pevent Os_Event .OSEventType .OSEventCnt .OSEventPtr .OSEventGrp
7 6 5 4 3 2 1 0
OS_ERR_EVENT_TYPE,pevent不是指向信号量的指针。
• 返回值: 如果信号量已被删除了,则返回空指针;若信号量没能被删除,则返回 pevent。后一种情况下,应该查看出错代码,以查明原因。
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemPost()函数原型如下: INT8U OSSemPost(OS_EVENT *pevent);
• 参数:
pevent:指向信号量的指针
• 返回值:
OS_NO_ERR :信号量成功的置起。 OS_SEM_OVF :信号量的值溢出。 OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针。
INT8U OSEventTbl[OS_EVENT_TBL_SIZE];
/* 等待任务列表 */
} OS_EVENT; μC/OS-II中的信号量由2部分组成:一部分是16位的无符号整型信号量 的计数值(0~65535);另一部分由等待该信号量的任务组成的等待任务表。
μC/OS-II信号量操作的函数
} OS_EVENT;
63 62 61 60 59 58 57 56
定义在文件µc/os-II.H中定义
事件类型OSEventType
• #define OS_EVENT_TYPE_UNUSED • #define OS_EVENT_TYPE_MBOX • #define OS_EVENT_TYPE_Q • #define OS_EVENT_TYPE_SEM • #define OS_EVENT_TYPE_MUTEX • #define OS_EVENT_TYPE_FLAG 0 1 2 3 4 5
0x000A
NULL 0x00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
一个刚创建且计数器初值为10的信号量
举例
Os_Event pevent .OS_Event_Type_SEM 3 .OSEventPtr 0x07
列表中删除一个任务的算法则正好相反,如下所示。 if ((pevent->OSEventTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) {
pevent->OSEventGrp &= ~OSMapTbl[prio >> 3];
} • 等待任务列表中查找最高优先级的任务程序清单如下。
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1. 信号量的值是多少? 2. 有任务等待信号灯?如 果有,优先级是多少?
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
建立一个信号量,OSSemCreate()
OSSemCreate()的原型如下: OS_EVENT *OSSemCreate(INT16U value);
• 返回值: OS_NO_ERR 表示调用成功。 OS_ERR_EVENT_TYPE 表示未向信号量传递指针。
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
第7章 任务的同步与通信
基本概念 µc/os-II的通讯方式
互斥与同步
并发任务之间必须建立一些制约关系。其中一种制约关系叫做直接制
约关系,另一种制约关系叫做间接制约关系。
互斥由资源共享 引起的
即对于某个共享资源,如果一个任务正在使用, 则其他任务只能等待,等到该任务释放该资源后, 等待的任务之一才能使用它,进程间的这种相互制 约关系称为互斥
y = OSUnMapTbl[pevent->OSEventGrp];
x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (y << 3) + x;
空事件控制块链表
μC/OS-II的初始化形成这个表
OS_CFG.H 中的#define OS_MAX_EVENTS定义最大事件
消息邮箱 消息队列 信号量 互斥信号量 信号量集
事件的等待任务列表
等待任务列表操作
将任务置于等待事件的任务列表中的代码如下: pevent->OSEventGrp |= OSMapTbl[prio >> 3]; pevent->OSEventTbl[prio >> 3] |= OSMapTbl[prio & 0x07];
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
等待一个信号量,OSSemPend()
OSSemPend()函数原型如下: void OSSemPend ( OS_EVNNT *pevent, INT16U timeout, int8u *err );
删除一个信号量,OSSemDel()
OSSemDel()的函数原型如下: OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *err);
• 参数:
pevent,指向信号量的指针。 opt,该项定义信号量的删除条件。若当等待任务表中已没有等待任务 时才删除信号量,opt选择OS_DEL_NO_PEND,若在等待任务表中无论是 否有等待任务都立即删除信号量,opt选择OS_DEL_ALWAYS。
INT8U OSEventGrp; /* 等待任务所在的组 */ INT16U OSEventCnt; /* 计数器(当事件是信号量时) */
void *OSEventPtr; /* 指向消息或者消息队列的指针 */
INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* 等待任务列表 */
OSSemQuery()函数原型如下: INT8U OSSemQuery(OS_EVENT *pevent, OS_SEM_DATA *pdata);
参数: pevent:一个指向信号量的指针。 pdata:一个指向数据结构OS_SEM_DATA的指针,该数据结构包含下 述域: • INT16U OSCnt; /* 当前信号量标识号码 */ • INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /*信号量等待队列*/ • INT8U OSEventGrp;
.OSEventTbl[]
0 0 0 0 0
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
• 信号量 • 邮箱 • 消息队列
第7章 任务的同步与通信
基本概念 µc/os-II的通讯方式
µc/os-II的通讯方式
• 信号量机制 • 互斥型信号量 • 信号量集机制 • 消息邮箱 • 消息队列
在µc/os-II中,任务之间的通信是利用事件来实现的
两个任务使用事件进行通信的示意图
发送事件
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
发出一个信号量OSSemPost()
.OSEventTbl[]
63
62
61
60
59
58
57
56
举例
OSSemCreate(10)
pevent OSEventCnt OSEventPtr OSEventGrp 0 任 务 等 待 表 0 0 OSEventTbl[ ] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 OS_EVENT_TYPE_SEM
参数:
pevent:指向信号量的指针。
timeout:允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的 信号量时恢复运行状态。如果该值为0则表示任务将持续的等待信号量。最大
的等待时间为65535个时钟节拍。 err: 指向包含错误码的变量的指针 OS_NO_ERR :信号量不为0。 OS_TIMEOUT :信号量没有在指定的周期数内置起。 OS_ERR_PEND_ISR :从中断调用该函数。虽然规定了不允许从中断 调用该函数,但μC/OS-Ⅱ仍然包含了检测这种情况的功能。 OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针。
Os_Event pevent .OSEventType .OSEventCnt .OSEventPtr .OSEventGrp
7 6 5 4 3 2 1 0
• 参数:
value表示建立的信号量的初始值,可 以是0~65535的任何值。 • 返回值:
OSSemCreate()返回指向事件控制块的 指针。如果没有可用的事件控制块, OSSemCreate()函数返回空指针。
同步由合作引起
相关的任务在执行上要有先后次序,一个任务要 等其伙伴发来通知,或建立了某个条件后才能继续 执行,否则只能等待。这种关系称为进程同步
通信
• 在多任务实时系统中,经常需要在任务之间或者中断服务之 间进行传递消息,这种消息传递机制被称为任务间的通信。
传递消息的办法:
全局变量 各种消息机制:
对事件控制块进行的操作一般包括:
初始化一个事件控制块。 使一个任务进入就绪态。 使一个任务进入等待某事件的状态。 因为等待超时而使一个任务进入就绪态。
以上的操作都隐含在不同的通讯方式的操作中!
主要内容
• 信号量机制 • 互斥型信号量 • 信号量百度文库机制 • 消息邮箱 • 消息队列
μC/OS-II信号量的数据结构
err, 指向包含错误码的变量的指针。返回的错误码可能为下述几种之一。 OS_NO_ERR,调用成功,信号量已被删除。 OS_ERR_DEL_ISR,试图在中断服务子程序中删除信号量。 OS_ERR_INVALID_OPT,没有将opt参数定义为2种合法参数之一。 OS_ERR_TASK_WAITING,有一个或一个以上的任务在等待信号量。
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemQuery()
OSSemAccept()
这些函数的使用须在OS_CFG.H中将配置常数OS_SEM_EN置为1。
查询一个信号量的当前状态,OSSemQuery()
typedef struct { INT8U OSEventType; /* 事件类型 */
OS_EVENT_TYPE_SEM
INT8U OSEventGrp; /* 等待任务所在的组 */
INT16U OSEventCnt;
/* 计数器(当事件是信号量时) */
void *OSEventPtr; /* 指向消息或者消息队列的指针 */
请求事件
任务1
事件
任务2
每个事件用一个数据结构事件控制块ECB
事件控制块结构
typedef struct { INT8U OSEventType; /* 事件类型 */
pevent Os_Event .OSEventType .OSEventCnt .OSEventPtr .OSEventGrp
7 6 5 4 3 2 1 0
OS_ERR_EVENT_TYPE,pevent不是指向信号量的指针。
• 返回值: 如果信号量已被删除了,则返回空指针;若信号量没能被删除,则返回 pevent。后一种情况下,应该查看出错代码,以查明原因。
μC/OS-II信号量操作的函数
OSSemCreat() OSSemDel() OSSemPend() OSSemPost()
OSSemPost()函数原型如下: INT8U OSSemPost(OS_EVENT *pevent);
• 参数:
pevent:指向信号量的指针
• 返回值:
OS_NO_ERR :信号量成功的置起。 OS_SEM_OVF :信号量的值溢出。 OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针。
INT8U OSEventTbl[OS_EVENT_TBL_SIZE];
/* 等待任务列表 */
} OS_EVENT; μC/OS-II中的信号量由2部分组成:一部分是16位的无符号整型信号量 的计数值(0~65535);另一部分由等待该信号量的任务组成的等待任务表。
μC/OS-II信号量操作的函数