w(゚Д゚)w499 2025-07-26 18:33 采纳率: 0%
浏览 25

在FreeRTOS管理的项目中添加了一段新代码了之后,can2接受中断无法正常 进入,求佬解答

我在由FreeRTOS管理的项目中添加了一段新的代码后发现can2进不了接受中断了,但是can1正常

img


这是新添加的代码所在的任务函数(该任务优先级最高)

img


这是新添加的代码片段(在Remote_Mode_Control ()函数里调用)新添加的代码是用来解算DBUS传回来的数据的
而且我发现了只要我只解算2个及以下的数据can2就能进接受中断,高于就不行

img


附中断优先级
求解答

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-07-26 18:34
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    在使用 FreeRTOS 的项目中,添加新代码后导致 CAN2 接收中断无法正常进入,而 CAN1 正常,这是一个典型的 中断优先级冲突、任务抢占或资源竞争问题。结合你提供的信息(如“只解算2个及以下的数据可以进中断,高于就不行”),我们可以推测出可能的原因和解决方法。


    一、问题分析

    1. 任务优先级过高

    • 你提到该任务是 优先级最高的任务,这可能导致 其他中断服务程序(ISR)被抢占
    • 在 FreeRTOS 中,任务优先级越高,越容易抢占低优先级任务,但 不能直接抢占中断(除非设置了 configMAX_SYSCALL_INTERRUPT_PRIORITY)。
    • 如果该任务执行时间过长(尤其是涉及大量运算或阻塞操作),可能会导致 中断延迟或丢失

    2. 中断优先级配置错误

    • CAN2 和 CAN1 的中断优先级可能不一致,或者你的新代码影响了 CAN2 的中断优先级设置。
    • 如果 CAN2 的中断优先级低于某个任务(特别是高优先级任务),那么 该中断会被延迟处理甚至被屏蔽

    3. 资源竞争或共享变量未加锁

    • 如果新代码中使用了全局变量或共享资源(如 DMA、寄存器等),而没有使用 互斥量(mutex)临界区保护,可能会导致 数据不一致或中断逻辑异常

    4. 堆栈溢出

    • 高优先级任务如果执行复杂计算,可能导致 堆栈溢出,进而引发 系统崩溃或中断失效

    5. DMA 或 CAN 接收配置被修改

    • 新代码可能无意中修改了 CAN2 的接收配置(如 FIFO 设置、中断使能位等),导致 接收中断无法触发

    二、解决方案(有序列表)

    1. 检查并调整任务优先级

    • 确保任务优先级不会干扰中断服务程序的执行
    • 建议将高优先级任务与中断优先级保持合理差距,例如:
      • 使用 configMAX_SYSCALL_INTERRUPT_PRIORITY 来限制任务对中断的抢占。
      • 将任务优先级设置为 稍低于 CAN2 的中断优先级(根据芯片手册调整)。

    注意: 在 STM32 中,中断优先级分为 抢占优先级(preemption priority)子优先级(subpriority),需确保 CAN2 的中断优先级高于任务优先级。

    2. 检查 CAN2 中断优先级配置

    • 确认 CAN2 的中断优先级是否正确配置。
    • 示例代码(STM32):
    NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0x0F); // 设置 CAN1 中断优先级
    NVIC_SetPriority(CAN2_RX0_IRQn, 0x0E);       // 设置 CAN2 中断优先级
    

    重点: 如果 CAN2 的中断优先级低于任务优先级,会导致中断无法及时响应。

    3. 检查 CAN2 接收中断使能状态

    • 确保在初始化时启用了 CAN2 的接收中断:
    CAN_ITConfig(CAN2, CAN_IT_RX_FIFO0_MSG_PEND, ENABLE);
    

    4. 检查任务中的代码逻辑

    • 你提到“只要解算 2 个及以下数据就能进中断,高于就不行”,说明 任务执行时间过长
    • 优化解算逻辑,避免长时间占用 CPU。
    • 可以考虑将解算过程 拆分到多个任务中,或使用 延时函数 让出 CPU:
    // 延迟一段时间,让出 CPU
    vTaskDelay(pdMS_TO_TICKS(1));
    

    5. 使用互斥量保护共享资源

    • 如果新代码中使用了全局变量或 CAN 寄存器,应在访问前加锁:
    xSemaphoreTake(mutex, portMAX_DELAY);
    // 修改共享资源
    xSemaphoreGive(mutex);
    

    6. 检查堆栈大小

    • 检查高优先级任务的堆栈大小是否足够,防止 堆栈溢出
    #define TASK_STACK_SIZE 512
    

    建议: 使用调试工具(如 ST-Link、J-Link)查看堆栈使用情况。

    7. 使用调试工具定位问题

    • 使用 逻辑分析仪示波器 查看 CAN2 的 RX 引脚是否有信号。
    • 使用 调试器 查看 中断是否被触发,以及 任务是否在运行

    三、推荐修改后的代码片段(示例)

    假设你有一个高优先级任务 Remote_Mode_Control(),你可以对其进行优化,避免长时间占用 CPU:

    void Remote_Mode_Control(void *pvParameters)
    {
        while (1)
        {
            // 解算 DBUS 数据
            int data_count = 0;
            while (data_count < MAX_DATA && /* 数据可用 */)
            {
                // 解算一个数据
                process_dbus_data(data_buffer[data_count]);
    
                data_count++;
    
                // 每处理一个数据,让出 CPU
                vTaskDelay(pdMS_TO_TICKS(1));
            }
    
            // 其他逻辑...
        }
    }
    

    重点: 每次处理完一个数据后调用 vTaskDelay(),避免长时间占用 CPU。


    四、总结

    | 问题原因 | 解决方案 | |----------|----------| | 任务优先级过高 | 调整任务优先级,确保不干扰中断 | | 中断优先级配置错误 | 检查并重新配置 CAN2 中断优先级 | | 任务执行时间过长 | 优化算法,使用 vTaskDelay() 让出 CPU | | 共享资源未加锁 | 使用 xSemaphoreTake/xSemaphoreGive 保护资源 | | 堆栈溢出 | 检查并增加任务堆栈大小 |


    如果你愿意提供具体的代码片段(如 CAN 初始化、任务函数、中断配置等),我可以进一步帮你分析和修复问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月26日