信号量可以用来进行资源管理和任务同步,FreeRTOS中信号量又分为二值信号量、计算型信号量、互斥信号量和递归互斥信号量。

0x01 二值信号量

二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的,任务和中断不用在乎队列中存的是什么消息,只需要知道这个队列是满的还是空的,可以利用这个机制完成任务与中断之间的同步。

1. 创建二值信号量


vSemaphoreCreateBinary

vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
  • xSemaphore :保存创建成功的二值信号量
    此函数是老版本FreeRTOS创建二值信号量函数,新版本已经不再使用。

xSemaphoreCreateBinary:

SemaphoreHandle_t xSemaphoreCreateBinary( void )

此函数是新版本FreeRTOS中统一使用此函数来创建二值信号量,使用此函数创建二值信号量的话,信号量所需要的内存是有FreeRTOS的内存管理部分动态分配的,此函数创建好的二值信号量默认是空的,也就是说创建好的二值信号量使用函数xSemaphoreTask是获取不到的。

xSemaphoreCreateBinaryStatic

SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
  • pxSemaphoreBuffer :保存信号量结构体
    此函数创建二值信号量所需要的内存需要由用户分配
2. 释放信号量

xSemaphoreGive

xSemaphoreGive( SemaphoreHandle_t xSemaphore )
  • xSemaphore:要释放的信号量句柄
    此函数用于释放二值信号量、计数型信号量或互斥信号量

xSemaphoreGiveFromISR

 xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken)
  • xSemaphore:要释放的信号量句柄
  • BaseType_t *pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换,此值为pdTRUE的时候在退出中断之前一定要进行一次任务切换

此函数只能用来释放二值信号量和计数型信号量

3. 获取信号量


xSemaphoreTake

xSemaphoreTake(*                   SemaphoreHandle_t xSemaphore,*                   TickType_t xBlockTime*               )
  • SemaphoreHandle_t xSemaphore:要获取信号量的句柄
  • TickType_t xBlockTime:阻塞时间
    此函数用于获取二值信号量、计数型信号量或互斥信号量

xSemaphoreTakeFromISR

 xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken)
  • SemaphoreHandle_t xSemaphore:要获取信号量的句柄
  • BaseType_t *pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换,等于pdTURE一定进行任务切换
4. 验证

设计一个通过串口发送指定的指令来控制开发版上的LED1和BEEP开关的实验。指令如下:
LED1ON:打开LED1
LED1OFF:关闭LED1
BEEFON:打开BEEF
BEEFOFF:关闭BEEF
设计三个任务,功能如下:
start_task:用来创建其他2个任务
task1_task:控制LED0闪烁,提示系统正在运行
DataProcess_task:指令处理任务,根据接收到的指令来控制不同的外设
实验中还创建一个二值信号量BinarySemaphore用于完成串口中断和任务DataProcess_task之间的同步。

DataProcess_task函数

void DataProcess_task(void *pvParameters)
{u8 len = 0;u8 CommandValue = COMMANDERR;BaseType_t err = pdFALSE;u8 *CommandStr;POINT_COLOR = BLUE;while(1){if(BinarySemaphore!=NULL){err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY); //获取信号量if(err==pdTRUE)                                        //获取信号量成功{len=USART_RX_STA&0x3fff;                     //得到此次接收到的数据长度CommandStr=mymalloc(SRAMIN,len+1);              //申请内存sprintf((char*)CommandStr,"%s",USART_RX_BUF);CommandStr[len]='\0';                           //加上字符串结尾符号LowerToCap(CommandStr,len);                      //将字符串转换为大写     CommandValue=CommandProcess(CommandStr);       //命令解析if(CommandValue!=COMMANDERR){LCD_Fill(10,90,210,110,WHITE);              //清除显示区域LCD_ShowString(10,90,200,16,16,CommandStr); //在LCD上显示命令printf("命令为:%s\r\n",CommandStr);switch(CommandValue)                       //处理命令{case LED1ON: LED1=0;break;case LED1OFF:LED1=1;break;case BEEPON:BEEP=0;break;case BEEPOFF:BEEP=1;break;}}else{printf("无效的命令,请重新输入!!\r\n");}USART_RX_STA=0;memset(USART_RX_BUF,0,USART_REC_LEN);            //串口接收缓冲区清零myfree(SRAMIN,CommandStr);                       //释放内存}}else if(err==pdFALSE){vTaskDelay(10);      //延时10ms,也就是10个时钟节拍 }}
}

DataProcess_task是用来申请获取信号量,如果申请到了,就往下执行,如果没事申请到,就会一直阻塞,申请到之后,对数据做处理,然后做出相应的回应。

串口1中断服务程序

//串口1中断服务程序
void USART1_IRQHandler(void)
{ u32 timeout=0;u32 maxDelay=0x1FFFF;BaseType_t xHigherPriorityTaskWoken;HAL_UART_IRQHandler(&UART1_Handler); //调用HAL库中断处理公用函数timeout=0;while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪{timeout++;超时处理if(timeout>maxDelay) break;      }  timeout=0;while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1{timeout++; //超时处理if(timeout>maxDelay) break;    }//释放二值信号量if((USART_RX_STA&0x8000)&&(BinarySemaphore!=NULL))//接收到数据,并且二值信号量有效{xSemaphoreGiveFromISR(BinarySemaphore,&xHigherPriorityTaskWoken); //释放二值信号量portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换}
}

串口1中断服务程序是用来接收串口发送的数据,如果接收完毕,将会释放二值信号量,DataProcess_task才能往下执行,如果没有接收完数据或者没有接收到数据,DataProcess_task会一直阻塞。

FreeRTOS信号量---二值信号量相关推荐

  1. FreeRTOS教程——二值信号量(四)

    二值信号量 信号量简介 目的:共享资源访问.与任务同步 信号量类型:二值信号量.计数型信号量.互斥信号量.递归互斥信号量 本质上是一种只包含一个项数的队列 二值信号量 0 和 1,一种内核机制. 内核 ...

  2. bufferedreader接收不到数据_FreeRTOS例程3-串口中断接收不定长的数据与二值信号量的使用

    1 基础知识点 1.1 串口中断种类 串口中断属于STM32本身的资源,不涉及到FreeRTOS,但可与FreeRTOS配合使用. 串口接收中断 中断标志为:USART_IT_RXNE,即rx non ...

  3. 35 freertos任务通知-代替二值信号量

    三十五. freertos任务通知-代替二值信号量 /** ********************************************************************** ...

  4. FreeRTOS信号量详解第二讲(全网最全)——二值信号量

    一.二值信号量简介 二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承.因此二值信号另更适合用于同步(任 ...

  5. 二值信号量和互斥锁到底有什么区别?

    原文链接:https://www.cnblogs.com/codescrew/p/8970514.html 在说明之前我先抛出结论:互斥锁和二值信号量在使用上非常相似,但是互斥锁解决了优先级翻转的问题 ...

  6. 二值信号量解决任务间资源共享问题

    文章目录 1 二值信号量解决任务间资源共享问题 1.1 信号量定义 1.2 工作原理 1.3 任务访问流程 1.4 分析 1 二值信号量解决任务间资源共享问题 1.1 信号量定义 1.2 工作原理 实 ...

  7. Linux内核信号量:二值信号量/互斥信号量,计数信号量,读写信号量

    <semaphore信号量:一个简单的示例程序>用户态程序 目录 概念 应用场景 使用方法 内核信号量的构成 信号量的API 初始化 PV操作 获取信号量(P) 释放内核信号量(V) 补充 ...

  8. freeRtos学习笔记 (7)信号量

    freeRtos学习笔记 freeRtos信号量 信号量种类 信号量分为四种:二值信号量,互斥信号量,计数信号量和递归互斥信号量,其中计数信号量用于管理系统多个共享资源,用计数值表示可用资源数目;二值 ...

  9. FreeRTOS学习五(信号量)

    信号量是操作系统中重要的一部分,信号量一般用来进行资源管理和任务同步.信号量分为二值信号量.计数型信号量.互斥信号量.不同信号量的应用场景也不同,但是有些应用场景是可以互换着使用的. 信号量简介 信号 ...

最新文章

  1. Docker介绍与安装使用(一)
  2. MATLAB 长度和像素_Matlab中短时傅里叶变换 spectrogram和stft的用法
  3. Google Cloud TPUs支持Pytorch框架啦!
  4. 使用OC进行iOS截屏,同时保证清晰度
  5. 应用虚拟化IT:需要决策支持做后盾
  6. ios 高德地图加载瓦片地图_OpenLayers加载高德地图离线瓦片地图
  7. 华为hg255d+Openwrt锐捷认证在某农业公园
  8. idea 2022年使用教程
  9. Mysql通过sql添加字段
  10. 多目标优化(三)简单的 MOEA/D
  11. 用C为密集运算函数加速
  12. WordCloud 中英文词云图绘制,看这一篇就够了
  13. [堆利用:TCache机制]HITB CTF 2018:gundam
  14. SVN文件夹对号图标(更新、冲突等)不显示
  15. java用jimi.jar实现图片格式转换
  16. 关于“质量”概念的理解
  17. iOS小知识: 使用bugly上报自定义错误信息进行数据监控
  18. windows批量删除指定后缀文件
  19. 在Wireshark中过滤UDS和OBD诊断ISO13400(DoIP)数据
  20. tor浏览器官网地址

热门文章

  1. java list作为参数传递_Java 程序将lambda表达式作为方法参数传递
  2. 超大超长图片居中显示且放大缩小无影响
  3. java IO流小结
  4. Linux ifconfig 配置网络接口
  5. HBuilder的快捷操作
  6. 【目录】《剑指Offer》Java实现
  7. 《Linux命令行与shell脚本编程大全 第3版》创建实用的脚本---10
  8. java基础----数字签名算法的介绍
  9. BZOJ 1898: [Zjoi2005]Swamp 沼泽鳄鱼 [矩阵乘法]
  10. 使用delphi 开发多层应用(十)安全访问服务器