概念
作用:信号量一般用来进行资源管理和任务同步,FreeRTOS中信号量又分为二值信号量、计数型信号量、互斥信号量和递归互斥信号量
- 信号量常常用于控制对共享资源的访问和任务同步。
实例理解:
停车场停车数量加一、减一。也就是说信号量加一减一。
电话亭打电话或者没人打电话
发送信号量来通知任务它所期待的事件发生了,当退出中断服务函数以后在任务调度器的调度下同步的任务就会执行。
二值性信号量
在创建的时候二值信号量的使命就是同步,完成任务与任务或中断与任务之间的同步。大多数情况下都
是中断与任务之间的同步。
感觉概念比较简单就是裸机中中断置位、这里是发了以后在任务中收,其工作流程就是
- 创建二值信号量
- 需要同步的地方,或者置位给其他地方处理的时候调用API释放信号量
- 在需要接收的地方调用API接收信号量,完成了二值信号量的工作流程
实例代码:
信号量发,函数参数创建句柄,和切换的变量
信号量收
比较简单,在于灵活使用,实际开发需要使用多处跳转执行多创建几个二值信号量就可以
计数型信号量
计数型信号量分两种
- 事件型,实现任务间同步。同步运行指定次数。
释放了信号,数值加一,阻塞的读信号的就会获取信号量,数值减一。数值的加减是在创建设置的时候的值。
实例代码解析:
老套路,一个发一个阻塞收,发释放信号量数值加,收接收信号量数值减,LCD刷屏,收完了LCD停止刷屏,
作用就是两个任务实现按键同步运行了几次
void SemapGive_task(void *pvParameters)
{
u8 key,i=0;
u8 semavalue;
BaseType_t err;
while(1)
{
key=KEY_Scan(0); //扫描按键
if(CountSemaphore!=NULL) //计数型信号量创建成功
{
switch(key)
{
case WKUP_PRES:
err=xSemaphoreGive(CountSemaphore);//释放计数型信号量
if(err==pdFALSE)
{
printf("信号量释放失败!!!\r\n");
}
semavalue=uxSemaphoreGetCount(CountSemaphore); //获取计数型信号量值
LCD_ShowxNum(155,111,semavalue,3,16,0); //显示信号量值
break;
}
}
i++;
if(i==50)
{
i=0;
LED0=!LED0;
}
vTaskDelay(10); //延时10ms,也就是10个时钟节拍
}
}
//获取计数型信号量任务函数
void SemapTake_task(void *pvParameters)
{
u8 num;
u8 semavalue;
while(1)
{
xSemaphoreTake(CountSemaphore,portMAX_DELAY); //等待数值信号量
num++;
semavalue=uxSemaphoreGetCount(CountSemaphore); //获取数值信号量值
LCD_ShowxNum(155,111,semavalue,3,16,0); //显示信号量值
LCD_Fill(6,131,233,313,lcd_discolor[num%14]); //刷屏
LED1=!LED1;
vTaskDelay(1000); //延时1s,也就是1000个时钟节拍
}
}