【ESP32】ESP-IDF开发 | I2C从机接收i2c_slave_receive函数的BUG导致程序崩溃解决(idf-v5.3.1版本)

1. 问题

在调试I2C外设的demo时,按照官方文档的描述调用相关API,烧录程序后发现程序会不断崩溃,系统log如下。

初步分析log,原因是访问到了不存在的地址。一开始我以为是自己的代码问题,反反复复改了几次都会出现同样的问题。

后面使用backtrace追踪出现问题的代码位置,代码在执行到i2c_slave.c的77行的时候崩溃了。

这是I2C中断服务函数内调用的,仔细观察发现,这个函数的处理就有问题。i2c_ll_read_rxfifo函数中传入的这个t->rcv_fifo_cnt参数是我们在上层调用i2c_slave_receive函数时传进去的buffer_size,这个参数的官方描述如下。

cpp 复制代码
/**
 * @brief Read bytes from I2C internal buffer. Start a job to receive I2C data.
 *
 * @note This function is non-blocking, it initiates a new receive job and then returns.
 *       User should check the received data from the `on_recv_done` callback that registered by `i2c_slave_register_event_callbacks()`.
 *
 * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
 * @param[out] data Buffer to store data from I2C fifo. Should be valid until `on_recv_done` is triggered.
 * @param[in] buffer_size Buffer size of data that provided by users.
 * @return
 *      - ESP_OK: I2C slave receive success.
 *      - ESP_ERR_INVALID_ARG: I2C slave receive parameter invalid.
 *      - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured
 */
esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, size_t buffer_size);

它指的是用户数据接收buffer的大小,然而在中断处理函数中,程序竟然直接把这个值作为读FIFO寄存器的长度,然而I2C的FIFO只有32字节,77行的memcpy必然会导致数组越界。

2. 解决

具体的修改是上面红框,把所有要传入接收长度的参数改成rx_fifo_cnt,这个值是通过上面i2c_ll_get_rxfifo_cnt函数获取的,它是当前FIFO可读的长度。

3. 后续

本来想着到Github上issue一下这个问题,没想到国外有大神已经抢先一步了。这是他的issue链接:https://github.com/espressif/esp-idf/issues/14803

相关推荐
Ching·16 分钟前
物联网 STM32【源代码形式-使用以太网】连接OneNet IOT从云产品开发到底层MQTT实现,APP控制 【保姆级零基础搭建】
stm32·嵌入式硬件·物联网
嘻嘻哈哈的zl34 分钟前
初级数据结构:栈和队列
c语言·开发语言·数据结构
weixin_537590451 小时前
《C程序设计》第六章练习答案
c语言·c++·算法
charlie1145141913 小时前
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(OLED设备层封装)
c语言·stm32·单片机·教程·oled·嵌入式软件
小林up4 小时前
【C语言设计模式学习笔记1】面向接口编程/简单工厂模式/多态
c语言·设计模式
云山工作室6 小时前
基于fpga技术的脉冲信号源设计(论文+源码)
stm32·嵌入式硬件·fpga开发·毕业设计·毕设
涛ing7 小时前
32. C 语言 安全函数( _s 尾缀)
linux·c语言·c++·vscode·算法·安全·vim
2401_843785239 小时前
STM32 AD多通道
stm32·单片机·嵌入式硬件
厂太_STAB_丝针9 小时前
【自学嵌入式(8)天气时钟:天气模块开发、主函数编写】
c语言·单片机·嵌入式硬件
charlie11451419111 小时前
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(协议层封装)
c语言·驱动开发·单片机·学习·教程·oled