FreeRTOS中断与同步

FreeRTOS为中断提供了丰富的API(),旨在保持中断服务例程尽量的短小。此时不再在中断服务程序中进行中断的处理,而是告知任务,此时需要某个任务进行中断服务例程的后续处理任务了。缩减中断服务程序出于如下的考虑:

  1. 一旦进入中断服务程序,即使最高优先级的任务都不能被执行
  2. 中断服务程序会打乱一个任务的开始、执行时间点
  3. 一旦进入中断,新的低优先级的中断将不能被响应,过长的中断服务例程会增加这个风险
  4. 如果中断处理都放到中断中进行,软件处理人员需要注意单片机的片上资源可能同时被任务/中断服务程序访问,比如变量、外设、内存缓冲区等
  5. 一些FreeRTOS允许中断嵌套,过长的中断服务程序增加了复杂度降低了程序执行可预测性

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

鉴于我们将中断发生的事件推迟到任务中进行处理,此时需要有一个机制来实现中断与任务的同步。

当事件发生,中断服务程序发送一个二值信号来解除阻塞中的处理任务。这个二值信号可以认为是由长度为1的队列实现。由于这个队列长度为1,因此它要么是空要么是满的状态。当一个中断事件发生,中断写入二值信号量,退出中断,处于阻塞的中断延迟处理任务将二值信号量取出,执行中断延迟服务程序,并在结束后进入下一次阻塞,等待这个二值信号量。

FreeRTOS中断与同步_第1张图片

 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

使用xSemaphoreCreateBinary()创建一个二值信号量,与队列使用相似的接口,传入的参数不同。因为是一个二值信号量,只是做为表征,无需向接口传入参数。创建二值信号量后返回这个信号量的操作句柄。

#define  xSemaphoreCreateBinary()    

xQueueGenericCreate((UBaseType_t) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE)

QueueHandle_t xQueueGenericCreate(const UBaseType_t uxQueueLength,

                                  const UBaseType_t uxItemSize,

                              const uint8_t ucQueueType )

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

使用xSemaphoreTake()取出二值信号量,使用创建二值信号量时生成的句柄拿到信号量,并给出阻塞时间。

#define  xSemaphoreTake(xSemaphore, xBlockTime )    

xQueueSemaphoreTake((xSemaphore), (xBlockTime))

BaseType_t xQueueSemaphoreTake(QueueHandle_t xQueue,

                           TickType_t xTicksToWait )

使用xSemaphoreGiveFromISR()由中断给出二值信号量。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

我们可以使用计数信号量来处理反复出现且每次出现都要进行一次处理的事件,计数信号量需要在FreeRTOSConfig.h中配置宏configUSE_COUNTING_SEMAPHORES,计数信号量可以认为是由长度大于1的队列,任务并不关注这个队列中存储的数据,只关注队列中的元素的个数,计数信号量的应用场景为:

  1. 记录事件个数,每次事件发生,都给出一次计数信号。任务将会每次都从这个计数信号量中取出一个信号量然后进入业务逻辑
  2. 资源管理,计数信号量可以用来指示可用的资源数量,为了占用一个资源,任务必须先取得一个信号量,而当结束占用后再将信号量返还

FreeRTOS中断与同步_第2张图片

 

 

 

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

在使用计数信号量之前,需要创建计数信号量,使用xSemaphoreCreateCounting()创建计数信号量,传入参数分别为最大的计数信号量的大小与初始的计数信号量的计数值,返回生成的信号量句柄,使用这个句柄来取出、放入信号量,取出、放入信号量的接口与二值信号量一致。

#define  xSemaphoreCreateCounting(uxMaxCount, uxInitialCount)    

xQueueCreateCountingSemaphore((uxMaxCount), (uxInitialCount))

QueueHandle_t xQueueCreateCountingSemaphore(const UBaseType_t uxMaxCount,

                                        const UBaseType_t uxInitialCount )

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

队列的中断API与中断嵌套不再展开。

你可能感兴趣的:(freertos)