FreeRTOS 线程同步及通信 -- 信号量、事件、消息队列

目录

一  FreeRTOS 信号量

二  FreeRTOS 事件组

三 FreeRTOS 消息队列


 

一  FreeRTOS 信号量

FreeRTOS信号量分为二值信号量、计数信号量、互斥信号量、递归互斥信号量

1. 信号量相关接口

创建二值信号量void vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore );
创建二值信号量SemaphoreHandle_t xSemaphoreCreateBinary( void );
创建静态二值信号量SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer );
创建计数信号量SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
                                                                                     UBaseType_t uxInitialCount );
创建静态计数信号量SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount,
                                                                                              UBaseType_t uxInitialCount,
                                                                                              StaticSemaphore_t pxSempahoreBuffer );
创建互斥信号量SemaphoreHandle_t xSemaphoreCreateMutex( void );
创建静态互斥信号量SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer );
创建递归互斥信号量SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );
创建递归静态互斥量SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( StaticSemaphore_t pxMutexBuffer );
删除信号量void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); 
获取信号量计数值UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
获取互斥量所有者TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
释放信号量BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
中断中释放信号量BaseType_t xSemaphoreGiveFromISR( SemaphoreHandle_t xSemaphore,
                                                                   BaseType_t *pxHigherPriorityTaskWoken );
释放递归互斥量BaseType_t xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex );
获取信号量BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );
中断中获取信号量BaseType_t xSemaphoreTakeFromISR( SemaphoreHandle_t xSemaphore,
                                                                   signed BaseType_t *pxHigherPriorityTaskWoken );
获取递归互斥量BaseType_t xSemaphoreTakeRecursive( SemaphoreHandle_t xMutex,
                                                                   TickType_t xTicksToWait );

2. 创建使用二值信号量

SemaphoreHandle_t BinarySem = NULL;

BinarySem = xSemaphoreCreateBinary();/*  创建 二值 信号量 */

xSemaphoreGive( BinarySem );         //发送信号量

xSemaphoreTake(BinarySem, portMAX_DELAY);//获取信号量

3. 创建使用计数信号量

SemaphoreHandle_t CountSem = NULL;

CountSem = xSemaphoreCreateCounting(10, 5); /* 创建计数信号量,信号量最大值为10,初始值为5 */

xSemaphoreGive( CountSem );//释放信号量,值加1

xSemaphoreTake(CountSem , 0);//获取信号量,值减1

4. 创建使用互斥信号量(互斥量不能在中断中使用)

SemaphoreHandle_t MuxSem = NULL;

MuxSem = xSemaphoreCreateMutex();        /*  创建 互斥信号量 */

xSemaphoreGive(MuxSem);                     //释放互斥量

xSemaphoreTake(MuxSem_Handle,portMAX_DELAY);//获取互斥量

二  FreeRTOS 事件组

1. 事件组相关接口

创建事件标志组EventGroupHandle_t xEventGroupCreate( void );
创建静态事件标志组EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer );
删除事件标志组void vEventGroupDelete( EventGroupHandle_t xEventGroup );
设置事件EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                                        const EventBits_t uxBitsToSet );
中断中设置事件BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
                                                                        const EventBits_t uxBitsToSet,
                                                                        BaseType_t *pxHigherPriorityTaskWoken );
事件同步EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
                                                    const EventBits_t uxBitsToSet,
                                                    const EventBits_t uxBitsToWaitFor,
                                                    TickType_t xTicksToWait );
等待事件EventBits_t xEventGroupWaitBits( const EventGroupHandle_t xEventGroup,
                                                          const EventBits_t uxBitsToWaitFor,
                                                          const BaseType_t xClearOnExit,
                                                          const BaseType_t xWaitForAllBits,
                                                          TickType_t xTicksToWait );
获取事件EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
中断中获取事件EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
清除事件EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
                                                           const EventBits_t uxBitsToClear );
中断中清除事件BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
                                                                           const EventBits_t uxBitsToClear );

2. 使用事件组进行中断与任务之间的同步

EventGroupHandle_t Event = NULL;

Event = xEventGroupCreate();/*  创建 事件组 */

void USART1_IRQHandler(void)
{
    接受到串口数据
    xEventGroupSetBitsFromISR(Event, 0x1); /*设置事件 */
}
 
void thread0(void* arg)
{
    rt_uint32_t recved;
    while(1)
    {
        /*  等待接收事件标志 */
        xEventGroupWaitBits(Event,  /*  事件对象句柄 */
                            0x01,   /*  接收 任务 感兴趣的事件 */
                            pdTRUE, /*  退出时清除事件位 */
                            pdTRUE, /*  满足感兴趣的所有事件 */
                            portMAX_DELAY);/*  指定超时事件, 一直等 */
        ...
        处理串口数据
    }
}

三 FreeRTOS 消息队列

1.消息队列常用接口

创建队列QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,UBaseType_t uxItemSize );
创建静态队列QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLength,
                                                               UBaseType_t uxItemSize,
                                                               uint8_t *pucQueueStorageBuffer,
                                                               StaticQueue_t *pxQueueBuffer );
删除队列void vQueueDelete( TaskHandle_t pxQueueToDelete );
复位(清空)队列BaseType_t xQueueReset( QueueHandle_t xQueue );
发送消息到队列尾

BaseType_t xQueueSend( QueueHandle_t xQueue,
                                            const void * pvItemToQueue,
                                            TickType_t xTicksToWait );

BaseType_t xQueueSendFromISR( QueueHandle_t xQueue,
                                                          const void *pvItemToQueue,
                                                          BaseType_t *pxHigherPriorityTaskWoken );

发送消息到队列尾

BaseType_t xQueueSendToBack( QueueHandle_t xQueue,
                                                       const void * pvItemToQueue,
                                                       TickType_t xTicksToWait );

BaseType_t xQueueSendToBackFromISR( QueueHandle_t xQueue,
                                                                      const void *pvItemToQueue,
                                                                      BaseType_t *pxHigherPriorityTaskWoken );

发送消息到队列首

BaseType_t xQueueSendToFront( QueueHandle_t xQueue,
                                                          const void * pvItemToQueue,
                                                          TickType_t xTicksToWait );

BaseType_t xQueueSendToFrontFromISR( QueueHandle_t xQueue,
                                                                      const void *pvItemToQueue,
                                                                      BaseType_t *pxHigherPriorityTaskWoken );

接受消息

并删除消息

BaseType_t xQueueReceive( QueueHandle_t xQueue,
                                                 void *pvBuffer,
                                                 TickType_t xTicksToWait );

 

BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
                                                               void *pvBuffer,
                                                               BaseType_t *pxHigherPriorityTaskWoken );

接受消息

但不删除消息

BaseType_t xQueuePeek( QueueHandle_t xQueue,
                                            void *pvBuffer, TickType_t
                                            xTicksToWait );

 

BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void *pvBuffer );

覆盖消息(当队列长度为1时,

调用该函数可以改变消息值)

BaseType_t xQueueOverwrite( QueueHandle_t xQueue, const void *pvItemToQueue );

 

BaseType_t xQueueOverwriteFromISR( QueueHandle_t xQueue,
                                                                   const void *pvItemToQueue,
                                                                   BaseType_t *pxHigherPriorityTaskWoken );

获取消息队列

已被使用的数量

UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );

UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue );

获取消息队列中

可供使用的空间

UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
消息队列是否为空BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t pxQueue );
消息队列是否已满BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t pxQueue );
  
创建队列集合QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength );

将队列或者信号量

添加到队列结合

BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
                                                    QueueSetHandle_t xQueueSet );

将队列或者信号量

从集合中移除

BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
                                                                QueueSetHandle_t xQueueSet );

从队列集合中选中

消息队列或者信号量

QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
                                                                                      const TickType_t xTicksToWait );

QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet );

2. 创建使用消息队列

QueueHandle_t      Queue = NULL;

/* Define the data type that will be queued. */
typedef struct A_Message
{
    char ucMessageID;
    char ucData[ 20 ];
} AMessage;

void task0(void* arg)
{
    AMessage xMessage;
    Queue = xQueueCreate(4,sizeof(AMessage));/*  创建一个消息队列,大小为4 */
    xMessage.ucMessageID = 0x01;
    
    while(1)
    {
        xQueueSend( Queue, &xMessage, 0 );
        vTaskDelay(500);
    }
}

void task1(void* arg)
{
    AMessage xMessage; /*  定义一个接收消息的结构体变量 */
    while(1)
    {
        if(xQueueReceive( Queue,&xMessage,portMAX_DELAY) == pdPASS)
        {
            //成功接受到消息
        }
        vTaskDelay(500);
    }
}

 

  • 10
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值