ucosiii之信号量

信号量用于资源共享、任务同步、任务和ISR(中断服务函数)间的同步,在现实实验中比较多用于任务同步和任务和ISR(中断服务函数)间的同步。

//信号量常用函数
在这里插入图片描述

//信号量用于资源共享例子如下:
//申请一个信号量和共享资源块

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

//创建信号量

	//创建一个信号量
	OSSemCreate ((OS_SEM*	)&MY_SEM_SHARE,
                 (CPU_CHAR*	)"MY_SEM_SHARE",
                 (OS_SEM_CTR)1,				//信号量为二进制信号量	
                 (OS_ERR*	)&err);

//使用信号量来访问共享资源,SemShare1_task()e和SemShare2_task()函数都访问共享资源share_resource[30],为防止其中一个任务在访问共享资源share_resource[30]时,另一个任务对共享资源share_resource[30]进行修改。
//阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后在进行操作。
//非阻塞操作的进程在不能进行设备操作时并不挂起,它或者被放弃,或者不停的查询,直到可以进行操作为止
//使用OSSemPost (&MY_SEM_SHARE,OS_OPT_POST_1,&err)时:信号量MY_SEM_SHARE.Ctr自加1
//OSSemPend(&MY_SEM_SHARE,0,OS_OPT_PEND_BLOCKING,0,&err)时:信号量MY_SEM_SHARE.Ctr自减1
//当信号量MY_SEM_SHARE.Ctr为0时,不能请求信号量

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

}
void SemShare2_task(void *p_arg)
{
	OS_ERR err;
	u8 task2_str[]="Sencond task Running!";
	
	while(1)
	{
		printf("Semshare:task2222\r\n");
		OSSemPend(&MY_SEM_SHARE,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量,阻塞
		memcpy(share_resource,task2_str,sizeof(task2_str));			//向共享资源区拷贝数据
		delay_ms(300);
		printf("%s\r\n",share_resource);							//串口输出共享资源区数据		
		OSSemPost (&MY_SEM_SHARE,OS_OPT_POST_1,&err);				//发送信号量
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   		//延时1s	
	}
}

//信号量用于任务同步:

//定义一个信号量,用于任务同步

OS_SEM	MY_SEM_SYNC;		//定义一个信号量,用于任务同步

//创建一个信号量

	//创建一个信号量,用于任务同步
	OSSemCreate ((OS_SEM*	)&MY_SEM_SYNC,
                 (CPU_CHAR*	)"MY_SEM_SYNC",
                 (OS_SEM_CTR)0,					//信号量数初始化为0;必须使用OSSemPost()函数来释放一个信号量
                 (OS_ERR*	)&err);

//使用信号量进行任务间的同步:使用SemSync1_task()函数来释放信号量给SemSync2_task()函数,从而达到任务同步。每释放一次信号量,MY_SEM_SYNC.Ctr自加1,每请求一次信号量MY_SEM_SYNC.Ctr自减1,直到减为0时就不能再请求信号量。
//阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后在进行操作。
//非阻塞操作的进程在不能进行设备操作时并不挂起,它或者被放弃,或者不停的查询,直到可以进行操作为止

void SemSync1_task(void *p_arg)
{
	OS_ERR err;
	static u8 count = 0;
	
	while(1)
	{
		if(count++ == 100)//判断语句可以根据项目的需求,判断什么时候任务同步
		{
			count = 0;
			OSSemPost(&MY_SEM_SYNC,OS_OPT_POST_1,&err);//发送信号量
			printf("SemSync111:SYNC_SEM.Ctr:%d\r\n",MY_SEM_SYNC.Ctr);
		}
		OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
	}
}

void SemSync2_task(void *p_arg)
{
	OS_ERR err;
	
	while(1)
	{	
		OSSemPend(&MY_SEM_SYNC,0,OS_OPT_PEND_BLOCKING,0,&err);//请求信号量,没有请求到信号量则阻塞
		printf("SemSync222:SYNC_SEM.Ctr:%d\r\n",MY_SEM_SYNC.Ctr);
		OSTimeDlyHMSM(0,0,2,0,OS_OPT_TIME_PERIODIC,&err);  
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值