FreeRTOS信号量与任务同步-2计数信号量

1. 计数信号量

上一节的二值信号量可能会发现,在用二值信号量同步任务与中断的例子中,串口输出的同步信息数量明显少于中断次数。这是由于TIM2更新中断时间短,在使用二值信号量同步任务与中断时,信号的传递还没有完成,新的中断又发生了,二值信号量显然无法保存多次中断的状态,采用计数信号量则可以解决这个问题。
计数信号量相当于长度大于1的队列,主要用于事件计数和资源管理。当计数信号量用于事件计数时,初值一般为0,事件处理函数每释放一次信号量其值加一,其他任务获取信号量其值减一。当计数信号量用于资源管理时,信号量代表资源可用的数量,初值为可用资源的最大值。

1.1· 创建计数信号量

xSemaphoreCreatcCounting()是用于动态创建计数信号量的宏,其定义如下。

#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) 

xQueueCreateCountingSemaphore( ( uxMaxCount ), 
                            ( uxInitialCount ) )

该宏有两个参数uxMaxCount 和uxInitialCount,用于给创建的计数信号量指定最大计数值和初值,实际用于创建计数信号量的是xQueueCreateCountingSemaphore()函数。创造成功会返回这个信号量的句柄,创建失败则返回NULL。

还有一个用于静态创建计数信号量的宏xSemaphoreCreateCountingStatic(),在使用该宏会创建计数信号量时需要由用户分配所需内存。
建成功会返回这个信号量的句柄,创建失败则返回NULL。

1.2 计数信号量的释放和获取

 计数信号量的释放和获取与二值信号量完全相同,使用相同的释放和获取函数,包括
中断版本的释放和获取也一样。

2. 用计数信号量进行任务同步

本示例改写自用二值信号量进行任务同步示例,将原示例中中断服务函数释放的二值
信号量替换成计数信号量,观察任务与中断同步的情况。

2.1 信号量及任务创建

本示例唯一的不同点是信号量的创建,其他代码均与原示例相同,信号量句柄名字可变可不变。

/**********************************************************************
函 数 名:appStartTask
功能说明:任务开始函数,用于创建其他函数并且开启调度器
形    参:pvParameters 是在创建该任务时传递的参数
返 回 值:无
**********************************************************************/
void appStartTask(void)
{
	
		/*创建一个长度为2,队列项大小足够容纳待输出字符的队列*/
		xQueuePrint = xQueueCreate(2,sizeof(pcToPrint));
		/*创造2个二值信号量,一个实现任务与任务之间的同步,一个用于实现任务与中断之间的同步*/
		binIRQSemaphore = xSemaphoreCreateCounting(255,0);	
		binKeySemaphore = xSemaphoreCreateBinary();
	
		if(xQueuePrint && binKeySemaphore && binIRQSemaphore)//如果队列信号量创建成功
		{
				
				taskENTER_CRITICAL();   /*进入临界段,关中断*/
	
				xTaskCreate(Led0Task,"Led0Task",128,NULL,3,&Led0TaskHandle);
				xTaskCreate(Led1Task,"Led1Task",128,NULL,3,&Led1TaskHandle);
				xTaskCreate(printTask,"printTask",128,NULL,3,&printTaskHandle);
				xTaskCreate(keyTask,"keyTask",128,NULL,4,&keyTaskHandle);
				taskEXIT_CRITICAL(); 	/*退出临界段,关中断*/
				vTaskStartScheduler();/*开启调度器*/	
		}
		
}

2.2 下载测试

由串口输出结果可以看出,中断同步任务2的操作滞后于计数信号量释放,但计数信号量较好地复原了中断发生的次数,以及中断同步任务2的次数。计数信号量在中断服务函数中被释放了多少次,在任务处理程序中就可以被获取多少次,这一点二值信号量是做不到的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值