FreeRTOS同步与互斥:(二)信号量

注:本文摘自韦东山《FreeRTOS完全开发手册》,如有侵权请告知

文章目录

  • 二、信号量
    • 2.1 信号量的特性
    • 2.2 信号量跟队列的区别
    • 2.3 信号量函数
      • 2.3.1 创建信号量
      • 2.3.2 删除信号量
      • 2.3.3 give/take

同步与互斥的概念:

  • 同步: A等待B做完某件事

  • 互斥: 某一资源同一时间仅能有一个用户访问

  • RTOS同步与互斥的方式: 任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)等。

二、信号量

信号量只能传递状态,不能传递具体的信息

2.1 信号量的特性

  • 信号:起通知作用

  • 量:还可以用来表示资源的数

    • 当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)
    • 当"量"只有0、1两个取值时,它就是"二进制信号量"(Binary Semaphores)
  • 支持的动作:"give"给出资源,计数值加1;"take"获得资源,计数值减1

2.2 信号量跟队列的区别

队列 信号量
可以容纳多个数据, 创建队列时有2部分内存: 队列结构体、存储数据的空间 只有计数值,无法容纳其他数据。 创建信号量时,只需要分配信号量结构体
生产者:没有空间存入数据时可以阻塞 生产者:不阻塞,计数值已经达到最大时 返回失败
消费者:没有数据时可以阻塞 消费者:没有资源时可以阻塞

2.3 信号量函数

使用信号量时,先创建、然后去添加资源、获得资源。使用句柄来表示一个信号量。

2.3.1 创建信号量

  • 二进制信号量
/* 创建二进制信号量
 * 返回值: 返回句柄,非NULL表示成功
 */
SemaphoreHandle_t xSemaphoreCreateBinary(void);

/* 创建一个二进制信号量
 * 此函数无需动态分配内存,所以需要先有一个StaticSemaphore_t结构体,并传入它的指针
 * 返回值: 返回句柄,非NULL表示成功
 */
SemaphoreHandle_t xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer );
  • 计数型信号量
/* 创建一个计数型信号量
 * uxMaxCount: 最大计数值
 * uxInitialCount: 初始计数值
 * 返回值: 返回句柄,非NULL表示成功
 */
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, 
                                           UBaseType_t uxInitialCount);

/* 创建一个计数型信号量
 * uxMaxCount: 最大计数值
 * uxInitialCount: 初始计数值
 * pxSemaphoreBuffer: StaticSemaphore_t结构体指针
 * 返回值: 返回句柄,非NULL表示成功
 */
SemaphoreHandle_t xSemaphoreCreateCountingStatic(UBaseType_t uxMaxCount,
                                                 UBaseType_t uxInitialCount,
                                                 StaticSemaphore_t
                                                 *pxSemaphoreBuffer );

2.3.2 删除信号量

对于动态创建的信号量,不再需要它们时,可以删除它们以回收内存

/* xSemaphore: 信号量句柄,你要删除哪个信号量 */
void vSemaphoreDelete(SemaphoreHandle_t xSemaphore );

2.3.3 give/take

  • give释放信号量
/* 释放信号量
 * xSemaphore:信号量句柄,释放哪个信号量
 * 返回值:pdTRUE表示成功,如果二进制信量的计数值已经是最大值,调用此函数则返回失败;
 */
BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore );

/* 释放信号量
 * xSemaphore:信号量句柄,释放哪个信号量
 * pxHigherPriorityTaskWoken:如果释放信号量导致更高优先级的任务变为了就绪态,
 *							  则*pxHigherPriorityTaskWoken = pdTRUE
 * 返回值:pdTRUE表示成功,如果二进制信量的计数值已经是最大值,调用此函数则返回失败;
 */
BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,
                                 BaseType_t *pxHigherPriorityTaskWoken);
  • take获取信号量
/* 获取信号量
 * xSemaphore:信号量句柄,获取哪个信号量
 * xTicksToWait:0:不阻塞,马上返回
 * 				portMAX_DELAY: 一直阻塞直到成功
 * 				其他值: 阻塞的Tick个数
 * 返回值:pdTRUE表示成功
 */
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait);

/* 获取信号量
 * xSemaphore:信号量句柄,获取哪个信号量
 * pxHigherPriorityTaskWoken:如果获取信号量导致更高优先级的任务变为了就绪态,
 * 							  则*pxHigherPriorityTaskWoken = pdTRUE
 * 返回值:pdTRUE表示成功
 */
BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,
                                 BaseType_t *pxHigherPriorityTaskWoken);

你可能感兴趣的:(FreeRTOS,stm32)