信号量

Pursue

二值信号量

二值信号量通常只有空和满两种情况,通常用于互斥访问和任务同步。

API函数

使用过程:创建二值信号量–>释放二值信号量–>获取二值信号量

函数 描述
OSSemCreat() 创建一个信号量
OSSemDel() 删除一个信号量
OSSemPend() 获取信号量资源
OSSemPendAbort() 终止任务挂起等待信号量资源
OSSemPost() 释放信号量资源
OSSemet() 强制设置信号量资源数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//创建信号量
void OSSemCreate (OS_SEM *p_sem, //指向信号量结构体指针
CPU_CHAR *p_name, //信号量名字
OS_SEM_CTR cnt, //信号量资源数初始值
OS_ERR *p_err) //错误代码

//释放信号量
OS_SEM_CTR OSSemPost (OS_SEM *p_sem, //指向信号量结构体指针
OS_OPT opt, //POST_1:仅一个最高优先级任务;POST_ALL:所有等待该信号量任务
OS_ERR *p_err) //错误代码

//获取信号量
OS_SEM_CTR OSSemPend (OS_SEM *p_sem, //指向信号量结构体指针
OS_TICK timeout,//任务挂起等待信号量最大时间
OS_OPT opt, //OS_OPT_PEND_BLOCKING or OS_OPT_PEND_NON_BLOCKING
CPU_TS *p_ts, //指向接收时间戳变量指针
OS_ERR *p_err) //错误代码

示例

1
2
3
4
5
6
7
OS_SEM key_status;


OSSemCreate(&key_status, "key_status", 1, &err);

OSSemPost(&key_status, OS_OPT_POST_1, &err);
ctr1 = OSSemPend(&key_status, 0, OS_OPT_PEND_BLOCKING, 0, &err);

优先级反转

高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度,但其他中等优先级却能抢到CPU资源。
stm-6u1.png

计数型信号量

同二值信号量

互斥信号量

为解决二值信号量导致的优先级反转的问题,uCOS3引入互斥信号量,互斥信号量可理解为一种特殊的二值信号量。将优先级翻转的危害降到最低。

当一个互斥信号量正被一个低优先级的任务持有时,如果此时有一个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会因获取不到互斥锁而被挂起,不过接下来,高优先级的任务会将持有互斥信号量的低优先级任务的任务优先级提成到与高优先级任务的任务优先级相同的任务优先级,这个过程就是优先级继承。

API函数

互斥信号量不能用于中断服务函数中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//创建互斥信号量
void OSMutexCreate (OS_MUTEX *p_mutex, //指向互斥信号量结构体指针
CPU_CHAR *p_name, //名字
OS_ERR *p_err) //错误代码

//获取信号量
void OSMutexPend (OS_MUTEX *p_mutex, //指向互斥信号量结构体指针
OS_TICK timeout, //任务挂起等待时间
OS_OPT opt, //PEND_BLOCKING or NON_BLOCKING
CPU_TS *p_ts, //接收信号量时间戳变量指针
OS_ERR *p_err) //错误代码

//释放信号量
void OSMutexPost (OS_MUTEX *p_mutex, //指向互斥信号量结构体指针
OS_OPT opt, //POST_NONE
OS_ERR *p_err); //错误代码

示例

1
2
3
4
5
6
7
8
OS_MUTEX mutex_sem;


OSMutexCreate(&mutex_sem, "mutex_sem", &err);

OSMutexPend(&mutex_sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err);

OSMutexPost(&mutex_sem, OS_OPT_POST_NONE, &err);
评论