Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Debug
I2C_IIC
进行i2c驱动移植的经验总结
发布于 2024-12-09 19:43:59 浏览:379
订阅该版
esp32c3的硬件i2c驱动有很大问题(无论是驱动代码本身还是freertos兼容层对esp的支持还是esp32的库代码本身),我不是说学了驱动后看谁都像个钉子,但是从我下面的血泪教训可窥知一二了 我的目标是能够正常读取mpu6050的数据,并且有了硬件i2c驱动实现**应该**会简单些(尽管rtt编写应用层代码有时必须参考驱动层的实现,但现造的轮子他不香么😊)。之后执行应用层代码时出现了死机的问题(相关bug的图片我没记录)。内核打印的信息是在中断中获取mutex,最后花了两天时间把问题定位到freertos的兼容层里,具体原因是rtt使用i2c时会先加锁,虽然在rtt眼中这毫无问题甚至很安全,但是使用esp32c3的代码和兼容层代码后一切都不一样了:现在的传输流程是rtt获取mutex->调用esp32c3的i2c代码->当使用到freertos的代码时转到freertos兼容层->再次回到esp32c3的i2c代码直至完成传输。这一过程一旦在获取rt_mutex后执行freertos的非中断版本的api时就会触发异常,该异常被rt_check捕获并显示在屏幕上。因此我们需要做的就是将esp32i2c内部的与传输相关的函数改成中断版本 重新实验……还是不行,这次是逻辑分仪收不到信息,之前由于排除了esp32代码和兼容层的问题,这次就没在这个方面下精力。这里卡了我一个星期,最后当我回看freetos兼容层代码时才发现坑爹的地方:i2c的关键函数没有实现。使用i2c时,esp32内部会使用队列,但这个队列函数并不是直接使用的freertos的,这个api被他们改造了,而freertos兼容层内并没有专门对esp32的函数进行适配。因此我们需要自己实现这个函数 原函数定义如下 ```c BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken) { ESP_LOGE(TAG, "xQueueOverwriteFromISR unimplemented"); configASSERT(0); return pdFAIL; } ``` 而后我实现为: ```c BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken) { //ESP_LOGE(TAG, "xQueueOverwriteFromISR unimplemented"); // configASSERT(0); // return pdFAIL; rt_kprintf("In function %s, line %d, file: %s\n", __FUNCTION__, __LINE__, __FILE__); return xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ); } #endif ``` 这样就可以正常传输了 但是在后续的传输过程中发现只能传7个bit 发现硬件i2c很坑之后就打算手搓一个软件i2c,虽然rtt内部有gpio模拟i2c的功能但是不是很灵活 手搓过程还是比较简单,具体可以参考spi那期。同时我们还需要实现`rt_hw_us_delay`这个函数,比较可惜的是如果使用网上流传的直接调用esp32api`usleep(1000);`或`ets_delay_us(1000);`会造成无限重启的bug。受限于技术能力,找不到bug。之前曾使用过`RVbacktrace`来排除bug,但不幸的是使用`RVbacktrace`本身就会带来bug,同样是无限重启(当同时使用`RVbacktrace`和`hwtimer`驱动时稳定触发),最后看堆栈勉勉强强发现是内核中调度器相关的问题,但是我们好奇为什么这两个功能会触发调度器的问题。最终这成了压死骆驼的最后一棵稻草,我只能使用软件i2c的方案: 常用的两个api不能使用,那就换种思路:使用esp的定时器(好在定时器是54位的,分辨率足够微秒级别)搓一个延时函数,代码如下: ```c static gptimer_handle_t gptimer_hw_us = NULL; static int delay_us_init(void) { gptimer_config_t timer_config = { .clk_src = GPTIMER_CLK_SRC_DEFAULT, .direction = GPTIMER_COUNT_UP, .resolution_hz = 1 * 1000 * 1000, // 1MHz, 1 tick = 1us }; ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer_hw_us)); ESP_ERROR_CHECK(gptimer_enable(gptimer_hw_us)); return RT_EOK; } INIT_DEVICE_EXPORT(delay_us_init); void rt_hw_us_delay(rt_uint32_t us) { uint64_t count = 0; ESP_ERROR_CHECK(gptimer_start(gptimer_hw_us)); ESP_ERROR_CHECK(gptimer_set_raw_count(gptimer_hw_us, 0)); // Retrieve the timestamp at anytime while(count < (uint64_t)us) { ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer_hw_us, &count)); } ESP_ERROR_CHECK(gptimer_stop(gptimer_hw_us)); } ``` 代码有两个缺点: * 不能异步处理其他程序,网上的api会在delay时将线程sleep,但是这里只能硬等 * 多占用一个定时器硬件资源 前者可以通过esp定时器的alert功能解决,后者就无能为力了 总之,目前已经将软件i2c代码完成了,剩下的可以之后优化
6
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
qq1078249029
这家伙很懒,什么也没写!
文章
4
回答
8
被采纳
0
关注TA
发私信
相关文章
1
NXP的I2C应该比ST的好用吧
2
Use of I2C device driver
3
关于I2C 驱动问题请教
4
我如何知道这个iic的io配置和我电路设计的是一致的?
5
I2C模拟读操作失败,不知道问什么进不去读函数
6
RTT的I2C有官方文档资料没有
7
求 STM32F103 IIC 自定义IO初始化 代码
8
报一个LPC4008代码中I2C的bug
9
RTOS IIC总线使用
10
关于在RTT中使用STM32 I2C的疑问
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
7
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
6
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部