freeRTOS使用方法 freertos从入门到精通

在操作系统系统中,信号量通常用于控制对共享资源的访问和任务之间进行同步,信号量在操作系统中是很常用的,也是学习freeRTOS操作系统必须要掌握的 。
freeRTOS中最常用到的信号量有:二值信号量、计数信号量、互斥信号量 。
有关这几个信号量分别如下:
1、二值信号量(1)二值信号量
二值信号量是指所创建的信号量只有两个值(0 和 1),通常用于互斥访问或者同步 。
二值信号量在某处被占有使用之后,其他地方想要申请这个二值信号量是无法成功申请的,只有当这个被占有的二值信号量被使用完毕并释放之后,才能被再次申请占有使用!
总而言之,二值信号量被使用之后会变为无效状态,需要被重新释放才能进入有效状态 。
二值信号量就像是路口的红绿灯一样,只有两个状态:能通行和不能通行 。在freeRTOS中就是能使用和不能使用 。如下图示例:

freeRTOS使用方法 freertos从入门到精通

文章插图

在freeRTOS中,二值信号量的创建和使用的API管理函数分别如下:
(2)创建二值信号量
函数原型:
SemaphoreHandle_t xSemaphoreCreateBinary(void)函数描述:函数 xSemaphoreCreateBinary 用于创建二值信号量 。
返回值:如果创建成功会返回二值信号量的句柄,创建失败会返回 NULL 。
(3)等待二值信号量
在freeRTOS中,信号量的获取是进行了区分的,在任务或者函数中获取与在中断中是不一样的,freeRTOS中给出了不同API函数 。
1)在任务代码中等待信号量
函数原型:
xSemaphoreTake(SemaphoreHandle_t xSemaphore, /* 信号量句柄 */ TickType_t xTicksToWait ); /* 等待信号量可用的最大等待时间 */函数描述:
函数 xSemaphoreTake 用于在任务代码中获取信号量 。第 1 个参数是信号量句柄 。第 2 个参数是没有信号量可用时,等待信号量可用的最大等待时间,单位系统时钟节拍 。返回值:如果创建成功会获取信号量返回 pdTRUE,否则返回 pdFALSE 。使用这个函数要注意以下问题:
此函数是用于任务代码中调用的,不可以在中断服务程序中调用此函数,中断服务程序使用的是xSemaphoreTakeFromISR 。
2)在中断中等待信号量
xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )函数描述:函数xSemaphoreTakeFromISR用于在中断中获取信号量 。
第 1 个参数是要获取的信号量的句柄 。这是创建信号量时返回的句柄 。第 2 个参数是如果采用信号量导致任务取消阻止,并且未阻止的任务的优先级高于当前运行的任务,则xSemaphoreTakeFromISR()会将pxHigherPriorityTaskWoken设置为pdTRUE 。如果xSemaphoreTakeFromISR()将此值设置为pdTRUE,则应在退出中断之前请求上下文切换 。返回值:如果创建成功会获取信号量返回 pdTRUE,否则返回 pdFALSE 。
(4)释放二值信号量
1)用于在任务代码中释放二值信号量
函数原型:
xSemaphoreGive( SemaphoreHandle_t xSemaphore ); /* 信号量句柄 */函数描述:释放信号量 。函数 xSemaphoreGive 用于在任务代码中释放信号量 。
xSemaphore:是信号量句柄 。返回值,如果信号量释放成功返回 pdTRUE,否则返回 pdFALSE,因为信号量的实现是基于消息队列,返回失败的主要原因是消息队列已经满了 。注意:此函数是用于任务代码中调用的,不可以在中断服务程序中调用此函数 。
2)用于在中断中释放二值信号量
函数原型:
xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)函数描述:函数 xSemaphoreGiveFromISR 用于中断服务程序中释放信号量 。
xSemaphore:是信号量句柄 。pxHigherPriorityTaskWoken:用于保存是否有高优先级任务准备就绪 。如果函数执行完毕后,此参数的数值是pdTRUE,说明有高优先级任务要执行,否则没有 。返回值:如果信号量释放成功返回 pdTRUE,否则返回 errQUEUE_FULL 。
2、计数信号量计数信号量是一个相当于长度大于1的队列,用于任务之间的同步和共享资源的保护 。
计数信号量与二值信号量的不同在于,二值信号量只能被一个地方申请使用,只有在这个申请使用的地方了释放了才能被其他处申请使用 。而计数信号量是可以创建一定数量的信号量的,多个地方可以同时申请使用,直到达到最大的计数信号量的阈值 。
计数信号量相关的API函数: