UCOS操作系统——任务内嵌信号量(十一)

UCOS操作系统

前言

前面我们使用信号量时都需要先创建一个信号量,不过在 UCOSIII 中每个任务都有自己的
内嵌的信号量,这种功能不仅能够简化代码,而且比使用独立的信号量更有效。任务信号量是
直接内嵌在 UCOSIII 中的,任务信号量相关代码在 os_task.c 中的。内嵌信号量是UCOS独有的,FreeRTOS中是没有的

一、任务内嵌信号量

在这里插入图片描述

二、使用方法

1.等待任务内嵌信号量

等待任务内嵌信号量使用函数 OSTaskSemPend(),OStaskSemPend()允许一个任务等待由其
他任务或者 ISR 直接发送的信号,使用过程基本和独立的信号量相同,OSTaskSemPend()函数
原型如下:

OS_SEM_CTR OSTaskSemPend ( OS_TICK timeout,
 OS_OPT opt,
 CPU_TS *p_ts,
 OS_ERR *p_err)

timeout: 如果在指定的节拍数内没有收到信号量任务就会因为等待超时而恢复运行,
如果 timeout 为 0 的话任务就会一直等待,直到收到信号量。

opt: 用于选择是否使用阻塞模式。
OS_OPT_PEND_BLOCKING 指定互斥信号量被占用时,任务挂起等待该互斥信号量。
OS_OPT_PEND_NON_BLOCKING 指定当互斥信号量被占用时,直接返回任务。
注意!当设置为 OS_OPT_PEND_NON_BLOCKING,是 timeout 参数就没有意义了,应该设置为 0。
p_ts: 指向一个时间戳,记录发送、终止或删除互斥信号量的时刻。
P_err: 调用此函数后返回的错误码。

2.发布任务信号量

OSTaskSemPost()可以通过一个任务的内置信号量向某个任务发送一个信号量,函数原型如 下:

OS_SEM_CTR OSTaskSemPost (OS_TCB *p_tcb,
 OS_OPT opt,
 OS_ERR *p_err)

p_tcb: 指向要用信号通知的任务的 TCB,当设置为 NULL 的时候可以向自己发送信量。
opt: 用来指定是否进行任务调度操作
OS_OPT_POST_NONE 不指定特定的选项
OS_OPT_POST_NO_SCHED 禁止在本函数内执行任务调度操作。
p_err: 调用此函数后返回的错误码。

三、完整代码

使用任务内嵌的信号量所以就不需要创建信号量

//任务 1 的任务函数
void task1_task(void *p_arg)
{
    
    
u8 key;
u8 num;
OS_ERR err;
while(1)
{
    
    
key = KEY_Scan(0); //扫描按键
if(key==WKUP_PRES)
{
    
    
OSTaskSemPost(&Task2_TaskTCB, (1)
OS_OPT_POST_NONE,&err); //使用系统内建信号量向任务 task2 发送信号量
LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //显示信号量值
}
num++;
if(num==50)
{
    
    
num=0;
LED0=~LED0;
}
OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err); //延时 10ms
} 
}
//任务 2 的任务函数
void task2_task(void *p_arg)
{
    
    
u8 num;
OS_ERR err;
while(1)
{
    
     
OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,\ (2)
0,&err); //请求任务内建的信号量
num++;
LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //显示任务内建信号量值
LCD_Fill(6,131,233,313,lcd_discolor[num%14]); //刷屏
LED1 = ~LED1;
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时 1s
} }

(1)、调用函数 OSTaskSemPost()向任务 task2_task 发送一个任务信号量。
(2)、任务 task2_task 一直请求任务信号量。
开机以后任务 task2_task 会由于请求不到信号量而阻塞
在这里插入图片描述
当我们按下 KEY_UP 键以后就会发送信号量,task2_task 任务内嵌信号量的值就会变化(增 加),我们多按几次 KEY_UP 键
在这里插入图片描述
此时 task2_task 任务的内嵌信号量的值为 12,说明 task2_task 任务可以请求 12 次任务内嵌的信号量。任务 task2_task 每隔 1s 就会请求一起内嵌信号量,直到任务内嵌的信号量值为 0

总结

UCOS中的任务内嵌信号量与其他信号量是有一定区别的,通过代码可以看出,该信号量不需要释放,在前面的学习中,信号量都是需要释放的。

猜你喜欢

转载自blog.csdn.net/qq_51963216/article/details/123926254