Live2d Test Env

中断——信号量

信号量进行中断上下文切换

  信号量操作是原子操作

  信号量能阻塞任务,同时也能解除任务的阻塞状态

 

 信号量分类:

  二值信号量:队列长度为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. */   } }
复制代码

 

 

posted @   爬上那个坡  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示