S32K在FreeRTOS下的外设中断设置

文章讨论了在开发过程中遇到的外设中断优先级高于操作系统内核中断优先级导致的错误。当调用如LPSPI_DRV_MasterTransferBlocking的阻塞传输接口并在中断服务函数中尝试调用OSIF_SemaPost等内核接口时,由于中断抢占问题,系统可能出现错误。解决方案是设置外设中断优先级低于操作系统内核中断优先级,例如通过INT_SYS_SetPriority函数在S32K平台中调整中断优先级,确保正确抢占并避免冲突。

如果在开发过程中遇到如下报错,你就可以继续往下看:

configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

描述

在调用外设blocking数据传输接口时(比如LPSPI_DRV_MasterTransferBlocking),需要在外设中断产生时调用操作系统的信号量接口来传递传输状态,这里面其实存在一个中断优先级的问题。

在不设置该外设的中断优先级情况下,系统默认将其外设的中断优先级设置为0x00,可使用INT_SYS_GetPriority 接口进行查看。

此时,假如FreeRTOS配置中(FreeRTOSConfig.h),你的配置为:

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 0x01
configPRIO_BITS = 4
configMAX_SYSCALL_INTERRUPT_PRIORITY = 0x01 << (8-configPRIO_BITS)

那么,就表示操作系统内核中断优先级为0x10

处于以上情况时,就会出现一种现象:当外设中断产生,在中断服务函数中去调用操作系统内核接口(如OSIF_SemaPost)就会出现系统内核无法抢占当前中断的情况,从而导致系统出错。因为按照数字越小,优先级越高的规则,外设中断优先级(0x00) 高于 操作系统内核中断优先级 (0x10),低优先级无法抢占高优先级

解决方法

在初始化外设驱动之前,设置该外设的中断优先级,使得该外设中断优先级低于(数字大于)操作系统内核中断优先级。

在S32K中,使用接口 INT_SYS_SetPriority(IRQn_Type irqNumber, uint8_t priority) 来设置外设的中断优先级,设置值与配置FEATURE_NVIC_PRIO_BITS有关。

比如SDK\platform\devices\S32K148\include\S32K148_features.h FEATURE_NVIC_PRIO_BITS = 4,则设置:

INT_SYS_SetPriority(LPSPI2_IRQn, 0x02);

表示设置SPI2的中断优先级为:(0x02  << FEATURE_NVIC_PRIO_BITS) = (0x02 << 4) = 0x20。

此时SPI2的外设中断优先级(0x20) 低于 操作系统内核中断优先级 (0x10),中断抢占问题得以解决,调用操作系统内核接口(如OSIF_SemaPost)成功,外设blocking数据传输接口得以正常使用。

推荐默认将外设中断优先级设置为支持的最低优先级,然后按需地逐步增加其优先级。

S32K144微控制器上使用FreeRTOS时,修改串口中断(如LPUART)的优先级需要综合配置FreeRTOS中断优先级管理机制和S32K144的NVIC(嵌套向量中断控制器)。以下是一个系统性的实现方法: ### 1. 理解FreeRTOS中断优先级限制 FreeRTOS要求某些中断不能被屏蔽,尤其是与系统调度相关的中断。在Cortex-M4架构中,`BASEPRI`寄存器用于屏蔽低于特定优先级中断FreeRTOS通过宏`configMAX_SYSCALL_INTERRUPT_PRIORITY`定义系统调用可屏蔽的最高中断优先级。高于该优先级中断不会被FreeRTOS内核屏蔽,适用于需要快速响应的外设中断,例如串口中断。 ### 2. 配置串口(LPUART)中断优先级S32K144中,LPUART中断优先级通过NVIC_SetPriority函数设置优先级数值越小,优先级越高。例如: ```c NVIC_SetPriority(LPUART0_IRQn, 3); // 设置LPUART0中断优先级为3 ``` 确保所设置优先级高于`configMAX_SYSCALL_INTERRUPT_PRIORITY`,以避免被FreeRTOS内核屏蔽。如果LPUART中断优先级设置为比`configMAX_SYSCALL_INTERRUPT_PRIORITY`低(数值更大),则可能在调用系统函数(如`vTaskDelay`)时被屏蔽,导致中断响应延迟或丢失。 ### 3. 修改FreeRTOS配置 在`FreeRTOSConfig.h`中,检查并调整`configMAX_SYSCALL_INTERRUPT_PRIORITY`的值。例如: ```c #define configMAX_SYSCALL_INTERRUPT_PRIORITY (5 << 5) // 假设使用5作为最大系统调用中断优先级 ``` 该值的格式通常需要左移5位,因为Cortex-M4的优先级寄存器结构要求如此。确保串口中断优先级设置在该阈值之上。 ### 4. 避免中断优先级冲突 在某些情况下,如果未明确设置串口中断优先级,系统可能默认将其设为最高优先级(如0),这可能导致FreeRTOS在调用`vPortValidateInterruptPriority()`时检测到冲突,进而进入死循环[^2]。因此,必须显式地设置串口中断优先级,并确保其处于合理范围。 ### 5. 测试与调试 在实际任务中,可以通过切换GPIO引脚状态来验证任务调度是否正常。例如: ```c void vUartDataProcessingTask(void *p) { while(1) { PINS_DRV_TogglePins(PTE, 1 << 12); // 切换LED状态 vTaskDelay(200); } } ``` 如果LED能够正常闪烁,则表明任务调度没有被串口中断阻塞,说明中断优先级配置正确[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值