5、FreeRTOS - 中断

中断,在任务函数运行的过程中,出现了特定的中断触发条件(中断源,其实就是识别到中断标志位发生改变),让 CPU 打断原本正在运行的程序,转而去处理紧急事件(ISR),执行中断服务函数,处理完后又返回原来被暂停的位置继续运行。

 

中断的执行机制:(从触发中断到结束的过程)

 中断请求:外设产生中断请求(GPIO外部中断、定时器中断等)

        ↓

响应中断:CPU停止执行当前程序,转而去执行中断处理程序(ISR)

        ↓

退出中断:执行完毕,返回被打断的程序处,继续往下执行

 

中断优先级:

当有多个中断源同时申请中断时,CPU 会根据中断源的优先级大小来进行裁决,决定哪个中断优先执行。中断优先级数值越小,越先执行,跟 FreeRTOS 任务优先级相反,任务优先级是越大越优先执行。

 

 ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器,所以中断优先级配置范围在 0~255,可配置的中断优先级范围很大。跟 ARM Cortex-M 相比,STM32 只用了中断优先级配置寄存器的高4位 [7 : 4](即 8 位寄存器中只用了 4~7 这4位,不使用低四位 0~3),所以STM32提供了最大16级(即 0~15)的中断优先等级,如下图

05a367153b844da18ad93d9d28d29afc.png

 

 STM32 的中断优先级可分为抢占优先级和子优先级:

抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断。

 

子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行。

 

两者区别:子优先级高的并不能打断正在执行的其他任务的,只能等待任务执行完才能轮到他。类似排队做核酸,子优先级高的是直接插入准备做核酸的下一位,而抢占优先级高的是直接把核酸做一半的人赶走,自己来做。

 

中断优先级共有5种优先级分组方式:(根据中断优先级配置寄存器的4位的不同配置来分组)

NVIC_PriorityGroup_0:0个bit 用于抢占优先级,4个bit 用于子优先级

NVIC_PriorityGroup_1:1个bit 用于抢占优先级,3个bit 用于子优先级

NVIC_PriorityGroup_2:2个bit 用于抢占优先级,2个bit 用于子优先级 

NVIC_PriorityGroup_3:3个bit 用于抢占优先级,1个bit 用于子优先级

NVIC_PriorityGroup_4:4个bit 用于抢占优先级,0个bit 用于子优先级

补充:在 STM32 中,用 NVIC 来专门管理所有中断(所有中断分配的工作都交给了NVIC,给不同的中断分配中断优先级的),是内核的一个外设,用来减轻 CPU 的负担。NVIC 总共有 16 个中断优先等级(0~15,由用户自己分配决定),为了处理不同形式的优先级, STM32 的 NVIC 对中断优先级进行了分组,分为了五组。

FreeRTOS 用的是 NVIC_PriorityGroup_4

 

FreeRTOS 中断优先级的特点:

1、低于 configMAX_SYSCALL_INTERRUPT_PRIORITY 优先级(即大于等于5的优先级,在5~15之间)的中断里才允许调用FreeRTOS 的API函数。

中断优先级要 >= 5,这样在中断函数里调用 FreeRTOS 的 API 函数才能用,因为 FreeRTOS 所管理的最高中断优先级大于 5 的(中断优先级里是越低越高)。

 

2、建议将所有优先级位指定为抢占优先级位(即 NVIC_PriorityGroup_4),方便FreeRTOS管理。

 

3、中断优先级数值越小越优先,任务优先级数值越大越优先。

<think>嗯,用户让我介绍一下FreeRTOS-LTS的移植说明,我需要先回想一下相关知识。FreeRTOS-LTS是FreeRTOS的长期支持版本,适合需要稳定性的项目。移植说明应该包括硬件准备、移植步骤、配置和验证这些部分吧。 首先,用户可能需要知道移植的基本概念,即如何让FreeRTOS在目标硬件上运行。需要从官方获取源码,特别是LTS版本。然后硬件方面,处理器架构支持很重要,比如ARM Cortex-M,RISC-V这些,用户可能用的MCU是什么?需要确认是否支持。内存和时钟配置也是关键,启动文件和链接脚本可能需要修改。 接下来是移植步骤,应该分点说明。添加内核源码到项目,复制必要的文件,比如源文件和头文件。然后是移植层,需要处理与硬件相关的部分,比如上下文切换、系统时钟、中断处理。可能需要修改port.c和portmacro.h这些文件。接着是内存管理,FreeRTOS提供了几种堆分配方案,用户需要根据硬件选择,比如heap_4.c比较常用。 然后是配置FreeRTOS,修改FreeConfig.h文件,设置任务数量、堆大小、调度策略等。还有时钟配置,系统节拍定时器的初始化,比如SysTick。之后是编写测试任务,验证任务调度是否正常,可能需要用串口输出调试信息。 验证部分,编译下载到硬件,观察任务是否运行,是否有错误。常见问题可能包括堆栈溢出、中断配置错误、系统时钟不正确。这些需要检查堆大小,中断优先级,时钟频率是否正确。 用户可能的身份是嵌入式开发者,正在考虑将FreeRTOS-LTS移植到他们的项目中,可能是工业控制或物联网设备,需要长期稳定性。他们可能已经有一定的嵌入式开发经验,但对FreeRTOS的具体移植步骤不太熟悉,需要详细的指导。深层需求可能是确保移植过程顺利,避免常见陷阱,保证系统稳定运行。因此,除了步骤外,还需要强调注意事项和常见问题排查,帮助他们节省时间,减少错误。</think>以下是 **FreeRTOS-LTS(Long Term Support)移植**的简要说明,帮助开发者将系统适配到目标硬件平台: --- ### **1. 移植前的准备工作** - **获取源码** 从 [FreeRTOS 官网](https://www.freertos.org/) 或 GitHub 仓库下载 FreeRTOS-LTS 版本的源码,确保使用官方长期支持的稳定版本。 - **硬件平台确认** - 确认目标 MCU/MPU 的架构(如 ARM Cortex-M、RISC-V、ESP32 等),FreeRTOS 支持多种处理器。 - 检查硬件资源(RAM、ROM、时钟频率)是否满足 FreeRTOS 的最小需求。 - 准备硬件对应的启动文件(如 `startup_xxx.s`)和链接脚本(`Linker Script`)。 --- ### **2. 移植核心步骤** #### **(1) 添加 FreeRTOS 源码到工程** -FreeRTOS-LTS 的以下核心文件复制到工程目录: - `FreeRTOS/Source/` 下的所有 C 文件(如 `tasks.c`、`queue.c`、`list.c` 等)。 - 硬件相关的移植层代码:`FreeRTOS/Source/portable/[编译器]/[架构]/`(如 `port.c` 和 `portmacro.h`)。 #### **(2) 移植层适配** - **上下文切换** 修改 `port.c` 中的汇编代码,适配目标处理器的寄存器操作(如任务堆栈初始化、上下文切换函数 `vPortYield()`)。 - **系统时钟配置** 实现系统节拍定时器(SysTick 或其他硬件定时器),在 `port.c` 中配置 `xPortSysTickHandler()` 中断服务函数。 - **中断处理** - 确保 FreeRTOS中断优先级配置与硬件匹配(如 Cortex-M 的 NVIC 优先级)。 -中断服务程序(ISR)中使用 FreeRTOS 的 API 时,需调用带 `FromISR` 后缀的函数(如 `xQueueSendFromISR`)。 #### **(3) 内存管理** - 选择 FreeRTOS 的堆内存管理方案(如 `heap_1.c`~`heap_5.c`),根据硬件调整堆大小(`configTOTAL_HEAP_SIZE`)。 - 若使用动态内存,需在 `FreeRTOSConfig.h` 中启用 `pvPortMalloc()` 和 `vPortFree()`。 --- ### **3. 配置 FreeRTOS** - **修改 `FreeRTOSConfig.h`** 根据硬件资源调整关键配置项: ```c #define configUSE_PREEMPTION 1 // 启用抢占式调度 #define configCPU_CLOCK_HZ (SystemCoreClock) // 系统主频 #define configTICK_RATE_HZ 1000 // 系统节拍频率(通常 1kHz) #define configMAX_PRIORITIES 5 // 任务优先级数量 #define configMINIMAL_STACK_SIZE 128 // 空闲任务栈大小 #define configTOTAL_HEAP_SIZE (1024 * 4) // 堆内存大小 ``` - **实现硬件抽象函数** - 若使用特定外设(如串口调试),需实现 `vAssert()` 或自定义日志输出函数。 --- ### **4. 验证与测试** 1. **编译与链接** - 确保编译器路径、头文件包含正确,无符号冲突。 - 检查链接脚本是否预留足够的栈空间和堆空间。 2. **创建测试任务** ```c void vTask1(void *pvParameters) { while(1) { printf("Task1 is running!\n"); vTaskDelay(pdMS_TO_TICKS(1000)); } } int main() { xTaskCreate(vTask1, "Task1", 128, NULL, 1, NULL); vTaskStartScheduler(); // 启动调度器 while(1); } ``` 3. **调试与优化** - 使用调试工具(如 J-Link、OpenOCD)观察任务切换和中断行为。 - 检查堆栈溢出(启用 `configCHECK_FOR_STACK_OVERFLOW`)。 --- ### **5. 常见问题** - **系统无法启动** - 检查启动文件中的堆栈指针初始化。 - 确认系统节拍定时器配置正确。 - **任务调度异常** - 检查任务优先级和调度策略(抢占式/协作式)。 - 确保中断优先级未屏蔽 FreeRTOS 的核心中断- **内存不足** - 增大 `configTOTAL_HEAP_SIZE` 或优化任务栈大小。 --- ### **6. 扩展支持** - **第三方库集成** 若需使用 FreeRTOS 的 TCP/IP 协议栈(如 FreeRTOS+TCP)、文件系统(FreeRTOS+FAT),需额外移植对应模块。 - **调试工具** 使用 Tracealyzer 或 SystemView 可视化任务调度和系统运行状态。 --- 通过以上步骤,可完成 FreeRTOS-LTS 在目标硬件的移植。建议参考官方文档和社区资源(如 FreeRTOS 论坛)获取具体芯片的移植示例。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值