乐鑫技术交流
直播中

剪刀脚

8年用户 841经验值
私信 关注
[问答]

vfs_uart中的代码导致串口中断异常怎么解决?

IDF: esp-idf v4.2.2
HW: ESP32D0WD-V3
OS: Windows 10


如果开启了CONFIG_VFS_SUPPORT_SELECT特性就会“在ISR内调用flash代码”的错误。

分析过程如下:
【1】在vfs组件里,vfs_uart.c文件中定义了select_notif_callback_isr()函数,它是定位在flash中的代码片段。
static void select_notif_callback_isr(uart_port_t uart_num, uart_select_notif_t uart_select_notif, BaseType_t *task_woken);
【2】而uart_start_select()被select接口调用时,执行如下代码把select_notif_callback_isr函数配置为uart驱动的select通知回调函数:
uart_set_select_notif_callback(i, select_notif_callback_isr);
【3】uart.c文件中的uart_set_select_notif_callback函数定义如下:
void uart_set_select_notif_callback(uart_port_t uart_num, uart_select_notif_callback_t uart_select_notif_callback){  if (uart_num < UART_NUM_MAX && p_uart_obj[uart_num]) {    p_uart_obj[uart_num]->uart_select_notif_callback = (uart_select_notif_callback_t) uart_select_notif_callback;  }}
【4】当uart进入ISR后,多处执行了如下代码,这实际上是调用了flash中的select_notif_callback_isr函数。
if (p_uart->uart_select_notif_callback) {  p_uart->uart_select_notif_callback(...);}
【5】如果此时cache禁用(例如在OTA升级),flash代码不可执行,就会导致异常!
总结:ESP32由于flash用于XIP的设计,同时又用于读写用户数据和OTA。这虽然成本降低了,但引入非常多与此相关的BUG。
                       

回帖(1)

h1654155275.5669

2024-6-21 17:01:53
以下是一些建议来解决这个问题:

1. **检查代码和配置**:首先,请确保您的代码和配置是正确的。检查 vfs_uart.c 文件中的 select_notif_callback_isr 函数是否正确实现,并确保 UART 驱动的 select 通知回调函数配置正确。

2. **更新 ESP-IDF**:您当前使用的是 ESP-IDF v4.2.2 版本。尝试更新到最新的稳定版本(例如 v4.4),因为新版本可能已经修复了这个问题。

3. **禁用 CONFIG_VFS_SUPPORT_SELECT**:如果问题仍然存在,您可以尝试禁用 CONFIG_VFS_SUPPORT_SELECT 特性,以避免使用 select 功能。这可能会影响您的应用程序的某些功能,但可以作为临时解决方案。

4. **修改 select_notif_callback_isr 函数**:如果问题仍然存在,您可以尝试将 select_notif_callback_isr 函数从 flash 中移动到 IRAM 中。这可以通过在函数声明前添加 `__attribute__((section(".iram.text")))` 属性来实现。例如:

   ```c
   __attribute__((section(".iram.text")))
   static void select_notif_callback_isr(uart_port_t uart_num, uart_select_notif_t uart_select_notif, BaseType_t *task_woken);
   ```

5. **检查中断优先级**:确保 UART 接收中断的优先级设置正确。如果优先级设置过高,可能会导致其他中断无法正常工作。您可以在 ESP-IDF 的配置文件中调整 UART 接收中断的优先级。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分