UCOSIII信号量详解

目录

​编辑

前言

一、信号量的类型

二、信号量的使用方法

2.1创建信号量

2.2请求信号量:

2.3释放信号量:

三、信号量的作用

四、注意事项

五、信号量的API函数

六、代码实现

6.1 创建信号量

6.2 使用信号量


前言

UCOSIII信号量是UCOSIII操作系统中用于任务同步和互斥访问共享资源的一种重要机制。下面我将详细解释UCOSIII信号量的类型、使用方法,以及它在UCOSIII操作系统中的作用。

一、信号量的类型

UCOSIII中的信号量主要分为两种类型:

二进制信号量:

1.只有0和1两个值

2.当信号量为1时,表示资源可用;当信号量为0时,表示资源不可用。

3.一次只能有一个任务使用这个资源。

计数型信号量

1.可以有多个值,表示资源的数量

2.允许多个任务同时访问资源,但数量受信号量当前值的限制。

二、信号量的使用方法

在UCOSIII中,信号量的使用通常包括以下几个步骤:

2.1创建信号量

使用系统提供的函数(如OSSemCreate)来创建信号量,并指定信号量的类型和初始值。

2.2请求信号量:

当任务需要访问共享资源时,会请求(或等待)信号量。

如果信号量有效(对于二进制信号量,即值为1;对于计数型信号量,即值大于0),则任务获取信号量并继续执行。

如果信号量无效,则任务会被阻塞,直到其他任务释放信号量或超时。

2.3释放信号量:

当任务完成对共享资源的访问后,必须释放信号量。

释放信号量(如使用OSSemPost函数)会使信号量的值增加,并可能唤醒等待该信号量的任务。

三、信号量的作用

信号量在UCOSIII操作系统中扮演着重要的角色,主要用于以下几个方面:

1. 任务同步:信号量可以用于实现任务之间的同步。例如,一个任务可能需要等待另一个任务完成某个操作后才能继续执行。

2. 互斥访问共享资源: 通过信号量,可以确保同一时刻只有一个任务能够访问共享资源,从而避免数据竞争和冲突。

3. 中断与任务同步: 在中断服务程序中释放信号量,可以通知任务中断已发生,并允许任务继续执行。

四、注意事项

1.在使用信号量时,需要确保正确管理信号量的创建、使用和删除,以避免资源泄露或死锁等问题。

2.应注意信号量的使用场景,合理选择二进制信号量或计数型信号量。

五、信号量的API函数

UCOSIII提供了几个关键的API函数来管理信号量,包括创建信号量、删除信号量、等待信号量和释放信号量等:

  • 创建信号量OSSemCreate(),用于创建一个信号量。
  • 删除信号量OSSemDel(),用于删除一个信号量。如果信号量正在被任务等待,则不能删除。
  • 等待信号量OSSemPend(),任务通过这个函数等待信号量变为可用。
  • 释放信号量OSSemPost(),任务在访问完共享资源后释放信号量,使其他等待该信号量的任务可以继续执行。

六、代码实现

下面写一个关于使用信号量访问共享资源的代码,给大家展示信号量的简单使用。

6.1 创建信号量

OS_SEM	MY_SEM;		    //定义一个信号量,用于访问共享资源
OS_ERR err;
u8 share_resource[30];  //共享资源区

//创建一个信号量
	OSSemCreate ((OS_SEM*	)&MY_SEM,
                 (CPU_CHAR*	)"MY_SEM",
                 (OS_SEM_CTR)1,		
                 (OS_ERR*	)&err);

6.2 使用信号量

//任务1的任务函数
void task1_task(void *p_arg)
{
	OS_ERR err;
	u8 task1_str[]="First task Running!";
	while(1)
	{
		printf("\r\n任务1:\r\n");
		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量
		memcpy(share_resource,task1_str,sizeof(task1_str)); //向共享资源区拷贝数据
		delay_ms(200);
		printf("%s\r\n",share_resource);	//串口输出共享资源区数据	
		OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);				//发送信号量
		LED0=!LED0;
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   //延时1s
	}
}

//任务2的任务函数
void task2_task(void *p_arg)
{	
	OS_ERR err;
	u8 task2_str[]="Second task Running!";
	while(1)
	{
		printf("\r\n任务2:\r\n");
		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量
		memcpy(share_resource,task2_str,sizeof(task2_str));	//向共享资源区拷贝数据
		delay_ms(200);
		printf("%s\r\n",share_resource);	//串口输出共享资源区数据		
		OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);				//发送信号量
		LED1=!LED1;
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   //延时1s
	}
}

上面是两个任务,分别对资源数据share_resource进行访问,为避免两个任务同时操作共享资源区造成混乱,给他们加了信号量,只有一个任务发送了信号量,另外一个任务才能对共享资源区进行操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千千道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值