首页 > 其他分享 >中断——信号量

中断——信号量

时间:2024-07-17 14:29:25浏览次数:12  
标签:queue SemaphoreHandle BaseType 中断 信号量 semaphore xSemaphore

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

  信号量操作是原子操作

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

 

 信号量分类:

  二值信号量:队列长度为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

相关文章

  • STM32第二十课:FreeRTOS任务管理和信号量
    目录一、任务管理方式二、任务堆栈溢出检测三、二值信号量(任务同步)四、计数信号量五、互斥信号量六、队列一、任务管理方式1.任务创建成功后会添加到就绪链表中,开启调度器,此时任务调度器会去就绪链表中找优先级最高的任务执行。若优先级一样则按照创建任务的先后来......
  • F103VET6+HAL库+UART串口空闲中断+DMA收发数据
    声明串口接收一段数据需要进入中断的次数太多了,为了充分利用CPU,使用空闲中断是更好的选择步骤一、CubeMX生成有关串口的配置串口全局中断勾上、DMA和DMA的中断勾上二、在main函数里使能两个串口的中断        第一个空闲中断、第二个接收寄存器不为空中断(后面解......
  • stm32 HAL库 笔记 定时器(1) 中断实验
    单片机中的定时器主要用于控制时间,比如延时、定时等等。而计数器则主要用于统计事件或脉冲信号的数量。通过控制定时器和计数器的中断、清零等操作,我们可以完成各种复杂的定时、计数等操作,实现更加智能化的控制系统。单片机的定时器一般由计数器、预分频器、中断控制器、基准......
  • 【史上最全面ESP32】软件中断与硬件中断
    文章目录前言硬件中断硬件中断概念硬件中断的使用软件中断软件中断概念软件中断的使用总结前言ESP32是一款高度集成的芯片,具有强大的中断处理能力。在ESP32中,我们可以配置所有的GPIO引脚作为硬件中断源,通过附加它们到相应的中断服务例程(ISR)来启用中断。此外,ESP32......
  • 0166-BIOS 中断
    环境Time2022-11-09WSL-Ubuntu22.04QEMU6.2.0NASM2.15.05前言说明参考:《x86汇编语言:从实模式到保护模式》李忠参考:http://www.ablmcc.edu.hk/~scy/CIT/8086_bios_and_dos_interrupts.htm目标使用BIOS中断,来进行屏幕的输出。BIOS中断BIOS中断是BIOS启动后......
  • STM32中断(NVIC和EXIT)
    CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有76个中断,包括16个内核中断和60个可屏蔽中断,具有16级可编程的中断优先级。而常用的就是这60个......
  • HAL库源码移植与使用之HAL库中断机制剖析
    经过一段时间的学习,我对HAL库自带的中断回调机制深恶痛绝,个人认为你可以把HAL库当成标准库去编写,形成你自己的编译风格,不用执行HAL库官方给的模板。HAL库中断函数回调机制:首先每个芯片的中断处理机制都是一样的,一样的中断头,一样的存储地址块比如:HAL库中的voidTIM5_IRQHandl......
  • 51单片机嵌入式开发:7、 STC89C52RC 外部中断INT0和INT1 操作
    STC89C52RC外部中断INT0和INT1操作1外部中断1.1外部中断1.2中断介绍2STC89C52外部中断2.1外部中断引脚2.2外部中断寄存器说明3STC89C52外部中断演示3.1电平触发外部中断3.2边沿触发外部中断3.3Protues仿真4外部中断总结1外部中断1.1外部中断单片......
  • stm32串口接受定长和不定长数据的两种中断方式
    stm32串口有两种中断方式1.字节中断(定长数据接受)接收指定字节数的数据后产生中断:HAL_UART_Receive_IT(&huart3,rxBuffer,21);注意这里仍然是接受一个字节进入一次IRQ中断函数,这里指定的字节数指的是接受指定字节数量后进入一次回调函数,由于IRQ函数会关闭中断,如需重复接受定......
  • Java信号量semaphore的原理与使用方法
    Semaphore的基本概念在Java中,Semaphore是位于java.util.concurrent包下的一个类。它的核心就是维护了一个许可集。简单来说,就是有一定数量的许可,线程需要先获取到许可,才能执行,执行完毕后再释放许可。那么,这个许可是什么呢?其实,你可以把它想象成是对资源的访问权。比如,有5个......