我正在使用 FreeRTOS 10.0.1,遇到一个非常棘手的问题,花了几天时间试图解决它,让我的代码在 CC1310 (Arm Cortex M3) 上运行。 我使用TI SDK从I2C设备读取数据,第一次成功,第二次卡在vListInsert中,pxIterator->pxNext指向自身,因此for循环是无限的。
驱动程序正在等待 SemaphoreP_pend(),如果我设置断点,我可以看到帖子被调用,但内核只是卡住了。
我已将 SysTick 和 PendSV isr prio 设置为 7(最低)。
i2c 中断优先级为 6。
configMAX_SYSCALL_INTERRUPT_PRIORITY 设置为 1。
据我所知,没有堆栈溢出。
请帮忙,我该如何调试这个问题?
最诚挚的问候 雅各布
这几乎肯定是中断优先级和列表损坏的问题。在您的情况下,中断优先级存储在前 3 位(因为有 3 个优先级位)。所以 7 存储为 7 << 5 (11100000b) (you can pad the lower bits with 1 if you like so priority 7 == 255). This is handled by FreeRTOS.
我怀疑发生的是你的优先级 6 的 I2C 中断,而不是 << 5 so you have 00000110b which gives a priority of 0 (highest, as its the top 3 bits)
我解决了这个问题,在获得@realtime-rik的帮助后,我决定再次检查所有中断优先级。他们都还好,但在这个过程中我发现了两件事。
当我不小心禁用中断并尝试再次禁用中断时,我遇到了 FreeRTOS 卡在 vListInsert() 中的问题。确保您没有调用taskENTER_CRITICAL(),然后调用portDISABLE_INTERRUPTS()。
至少有 5 个原因导致您的代码可能陷入
for
文件中 vListInsert()
函数的无限 list.c
循环中。
在这里,我增强了原因 4:
/* *** NOTE ***********************************************************
* If you find your application is crashing here then likely causes are
* listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for
* more tips, and ensure configASSERT() is defined!
* https://www.FreeRTOS.org/a00110.html#configASSERT
*
* 1) Stack overflow -
* see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
* 2) Incorrect interrupt priority assignment, especially on Cortex-M
* parts where numerically high priority values denote low actual
* interrupt priorities, which can seem counter intuitive. See
* https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
* of configMAX_SYSCALL_INTERRUPT_PRIORITY on
* https://www.FreeRTOS.org/a00110.html
* 3) Calling an API function from within a critical section or when
* the scheduler is suspended, or calling an API function that does
* not end in "FromISR" from an interrupt.
* 4) Using a queue or semaphore before it has been initialised or
* before the scheduler has been started (are interrupts firing
* before vTaskStartScheduler() has been called?).
* - This includes initializing binary semaphores before taking them. If
* you create one with `xSemaphoreCreateBinary()` or
* `xSemaphoreCreateBinaryStatic()`, you must call `xSemaphoreGive()`
* before calling `xSemaphoreTake(). See:
* https://freertos.org/xSemaphoreCreateBinaryStatic.html:
* > The semaphore is created in the 'empty' state, meaning the
* > semaphore must first be given using the xSemaphoreGive() API
* > function before it can subsequently be taken (obtained) using the
* > xSemaphoreTake() function.
* 5) If the FreeRTOS port supports interrupt nesting then ensure that
* the priority of the tick interrupt is at or below
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
来源(我的拉取请求):https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/1051/files