信号量进行中断上下文切换
信号量操作是原子操作
信号量能阻塞任务,同时也能解除任务的阻塞状态
信号量分类:
二值信号量:队列长度为1,处理中断频率低的事件,进行中断上下文切换
互斥信号量:针对共享数据的原子操作
计数信号量: 队列长度为N的二值信号量,对于中断频率较高的事件,可以用计数信号量,进行处理
信号量实现是队列:
typedef QueueHandle_t SemaphoreHandle_t; //信号量类型 typedef struct QueueDefinition * QueueHandle_t; typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ union { QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */ SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */ } u; List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */ UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ #endif #if ( configUSE_QUEUE_SETS == 1 ) struct QueueDefinition *pxQueueSetContainer; #endif #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxQueueNumber; uint8_t ucQueueType; #endif } xQUEUE;
二值信号量与计数信号量:
//二值信号量创建: SemaphoreHandle_t xSemaphoreCreateBinary( void ); SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer ); //eg: /* Attempt to create a semaphore. */ xSemaphore = xSemaphoreCreateBinary(); if( xSemaphore == NULL ) { /* There was insufficient FreeRTOS heap available for the semaphore to be created successfully. */ } else { /* The semaphore can now be used. Its handle is stored in the xSemaphore variable. Calling xSemaphoreTake() on the semaphore here will fail until the semaphore has first been given. */ } //static creat SemaphoreHandle_t xSemaphoreHandle; StaticSemaphore_t xSemaphoreBuffer; xSemaphoreHandle = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer ); //计数信号量创建方法 SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ); SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t pxSempahoreBuffer ); //eg: SemaphoreHandle_t xSemaphoreHandle; StaticSemaphore_t xSemaphoreBuffer; /* Create a counting semaphore without using dynamic memory allocation. The maximum value to which the semaphore can count in this example case is set to 10, and the initial value assigned to the count is set to 0. */ xSemaphoreHandle = xSemaphoreCreateCountingStatic( 10, 0, &xSemaphoreBuffer );
互斥信号量
//互斥信号量两种创建方法 SemaphoreHandle_t xSemaphoreCreateMutex( void ); SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer ); //eg: SemaphoreHandle_t xSemaphoreHandle; StaticSemaphore_t xSemaphoreBuffer; //由程序在RAM中分配 xSemaphore = xSemaphoreCreateMutex(); //由writer在RAM中分配 xSemaphoreHandle = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer );
//支持递归调用的互斥信号量:两种创建方式 xSemaphore = xSemaphoreCreateRecursiveMutex(); xSemaphoreHandle = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer ); //递归互斥信号量的PV操作接口 BaseType_t xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ); BaseType_t xSemaphoreTakeRecursive( SemaphoreHandle_t xMutex, TickType_t xTicksToWait ); //eg: xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreGiveRecursive( xMutex );
信号量操作:
//信号量删除: void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); //信号量的PV操作接口 BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore ); BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait ); //中断中信号量的操作接口 BaseType_t xSemaphoreGiveFromISR( SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken ); BaseType_t xSemaphoreTakeFromISR( SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken );
//eg:互斥信号量安全访问共享资源 /* Obtain the semaphore – don’t block if the semaphore is not immediately available (the specified block time is zero). */ if( xSemaphoreTake( xSemaphore, 0 ) == pdPASS ) { /* The semaphore was ‘taken’ successfully, so the resource it is guarding can be accessed safely. */ /* ... */ /* Access to the resource the semaphore is guarding is complete, so the semaphore must be ‘given’ back. */ if( xSemaphoreGive( xSemaphore ) != pdPASS ) { /* This call should not fail because the calling task has already successfully ‘taken’ the semaphore. */ } }
标签:queue,SemaphoreHandle,BaseType,中断,信号量,semaphore,xSemaphore From: https://www.cnblogs.com/zypprocess/p/18305295