FreeRTOS中断与任务之间同步(Error:..\..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,422 )

前言:

FreeRTOS中,中断需要注意几点:

何时使用中断;中断服务函数(ISR)要处理的数据量有多大,通常我们希望中断的切换越快越好,也就是说,ISR尽量采用耗时较少的处理方式;那该如何操作呢?

一、延迟中断概念

所以为了中断服务函数应该尽量断,因此这里才用中断的前部和中断的后部来处理;

前部:负责处理不耗时的操作,比如任务的同步,发送信号量去通知任务;

后部:负责处理耗时的操作,这时候,中断已经恢复现场,实际执行可以视为软中断,即在一个Task任务中执行;

上述的方式也可以称之为延迟中断处理

思路是:

1)首先创建一个二值信号量去同步任务

2)进入中断发送信号量,让任务解除阻塞,这样在中断服务函数运行完就可以立即执行同步任务。

原理:

1)中断处理可以说是被推迟(deferred)到一个处理(handler)任务中;

2)如果某个中断处理要求特别紧急,其延迟处理任务的优先级可以设为最高,以保证延迟处理任务随时都抢占系统中的其它任务。

3)延迟处理任务就成为其对应的 ISR退出后第一个执行的任务,在时间上紧接着 ISR 执行,相当于所有的处理都在 ISR 中完成一样。

二、中断安全的API

通常需要在中断服务函数(ISR)中调用FreeRTOS的API函数,但许多的API在ISR中是不安全的,其中一些API会将调用的任务转换到阻塞态,如果在ISR中调用了这类API则会出现很多问题。FreeRTOS通过提供两个版本的API来解决这个问题,一个版本供任务调用,一个版本供ISR调用,用于ISR版本的API其函数名都带有"FromISR"后缀。

1)那么我同步的信号量的函数为:

xSemaphoreGiveFromISR( PHY_RX_xSemaphore, &xHigherPriorityTaskWoken);

PHY_RX_xSemaphore:定义的二值信号量

2)在中断内不会自动切换到高优先级的任务,需要应用程序设置变量以通知调度器执行上下文切换。中断安全版的API(以"FromISR"结尾的函数) 具有一个名为pxHigherPriorityTaskWoken的指针如果应该执行上下文切换,则中断安全版API函数将(*pxHigherPriorityTaskWoken)设置为pdTRUE,因此,pxHigherPriorityTaskWoken指向的变量必须在第一次使用前初始化为pdFALSE。

初始化:BaseType_t xHigherPriorityTaskWoken = pdFALSE;

API函数只能将(*pxHigherPriorityTaskWoken)设置为pdTRUE,如果ISR调用多个API函数,则可以给每个API传入一个pxHigherPriorityTaskWoken指向的变量,但必须在第一次使用前初始化为pdFALSE。

pxHigherPriorityTaskWoken参数是可选的。如果不需要,将pxHigherPriorityTaskWoken设置为NULL即可。

3)请求上下文切换的宏

taskYIELD() 是一个可以在任务中调用以请求上下文切换的宏。

portYIELD_FROM_ISR() 和portEND_SWITCHING_ISR() 以相同的方式使用,并执行相同的操作。 一些FreeRTOS移植仅提供两个宏中的一个。 较新的FreeRTOS移植提供两种宏。 本文将使用portYIELD_FROM_ISR()宏。

那么这个宏的作用就是:portYIELD_FROM_ISR()来执行上下文的切换,前提得根据xHigherPriorityTaskWoken;当xHigherPriorityTaskWoken为pdFALSE,

调用portYIELD_FROM_ISR()将不会发生上下文切换,否则就会发生上下文切换

三、实际应用

下面是我以太网中断应用:

void ETH_IRQHandler(void)//以太网中断

{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( PHY_RX_xSemaphore, &xHigherPriorityTaskWoken);

ETH_DMAClearITPendingBit(ETH_DMA_INT_R);

ETH_DMAClearITPendingBit(ETH_DMA_INT_NIS);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

}

/* 定义一个信号量用于PHY接受数据同步 */

SemaphoreHandle_t PHY_RX_xSemaphore;

void NETWORK_Task(void *pvParameters)

{

for(;;)

{

if(xSemaphoreTake(PHY_RX_xSemaphore,portMAX_DELAY) == pdTRUE)

{

//执行函数

}

}

}

注:如果在系统中断中要使用FreeRTOS的API函数,然后不带"FromISR"结尾的函数则会串口打印信息回出现

Error:..\..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,422

所以一定要使用API(以"FromISR"结尾的函数

相关推荐
追梦少年时8 小时前
STM32-Flash闪存
stm32·单片机·嵌入式硬件·51单片机
weixin_452600698 小时前
《青牛科技 GC6125:驱动芯片中的璀璨之星,点亮 IPcamera 和云台控制(替代 BU24025/ROHM)》
人工智能·科技·单片机·嵌入式硬件·新能源充电桩·智能充电枪
weixin_4526006910 小时前
【青牛科技】14W 高保真音频放大电路——D2030
科技·单片机·嵌入式硬件·音视频·电动工具·智能电表
小刘同学-很乖17 小时前
MQTT从入门到精通之MQTT Dashboard
spring boot·stm32·物联网·iot
YuCaiH17 小时前
【STM32】USART串口数据包
笔记·stm32·单片机·嵌入式硬件
Kasen's experience19 小时前
STM32 GPIO 配置
stm32·单片机·嵌入式硬件
知行电子-20 小时前
Proteus中数码管动态扫描显示不全(已解决)
单片机·proteus·嵌入式
学习路上_write20 小时前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
非概念21 小时前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
jjjxxxhhh1231 天前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发