在测试SD卡反复热插拔时出现SD卡无法顺利初始化的情况,初始化程序挂起并进入idle,输出日志如下:
\ | /
- RT - Thread Operating System
/ | \ 4.1.0 build May 13 2022 00:40:03
2006 - 2022 Copyright by RT-Thread team
I/I2C main: I2C bus [i2c1] registered
ADC1_3 init success!
msh />I/SDIO mmcsd_detect: SD card capacity 3872256 KB.
I/SDIO mmcsd_detect: switching card to high speed failed!
found part[0], begin: 4194304, size: 3.705GB
dfs mount sd0 success
SD card eject!
SD card insert!
SD card eject!
I/SDIO mmcsd_detect: SD card capacity 3872256 KB.
SD card insert!
SD card eject!
通过在RT1061上debug不断查找问题,发现在sd.c文件中mmcsd_send_app_op_cond函数卡死,通过将mmcsd_send_app_cmd命令尝试次数改为1000可以解决热插拔卡时可能由于电源不稳定造成的初始化失败,修改后的代码为:
rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host,
rt_uint32_t ocr,
rt_uint32_t *rocr)
{
struct rt_mmcsd_cmd cmd;
rt_uint32_t i;
rt_err_t err = RT_EOK;
rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
cmd.cmd_code = SD_APP_OP_COND;
if (controller_is_spi(host))
cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
else
cmd.arg = ocr;
cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR;
for (i = 1000; i; i--) //改为1000,防止重新插卡时失败
{
err = mmcsd_send_app_cmd(host, RT_NULL, &cmd, 3);
if (err)
break;
/* if we're just probing, do a single pass */
if (ocr == 0)
break;
/* otherwise wait until reset completes */
if (controller_is_spi(host))
{
if (!(cmd.resp[0] & R1_SPI_IDLE))
break;
}
else
{
if (cmd.resp[0] & CARD_BUSY)
break;
}
err = -RT_ETIMEOUT;
mmcsd_delay_ms(10); //delay 10ms
}
if (rocr && !controller_is_spi(host))
*rocr = cmd.resp[0];
return err;
}
里面的i由初始值100改为1000,修改后的输出:
\ | /
- RT - Thread Operating System
/ | \ 4.1.0 build May 13 2022 00:40:03
2006 - 2022 Copyright by RT-Thread team
I/I2C main: I2C bus [i2c1] registered
ADC1_3 init success!
msh />I/SDIO mmcsd_detect: SD card capacity 3872256 KB.
I/SDIO mmcsd_detect: switching card to high speed failed!
found part[0], begin: 4194304, size: 3.705GB
dfs mount sd0 success
SD card eject!
SD card insert!
I/SDIO mmcsd_detect: SD card capacity 3872256 KB.
I/SDIO mmcsd_detect: switching card to high speed failed!
found part[0], begin: 4194304, size: 3.705GB
SD card eject!
SD card insert!
I/SDIO mmcsd_detect: SD card capacity 3872256 KB.
I/SDIO mmcsd_detect: switching card to high speed failed!
found part[0], begin: 4194304, size: 3.705GB
SD card eject!
经反复测试,SD卡初始化不再出现失败情况
I used to try to add a 500ms delay in the detect thread but it's useless. Debug step by step, every command was processed successfully but responded error in the mmcsd_send_app_op_cond function. Even useless to add the delay time of the mmcsd_delay_ms(10) at the end of for loop. I can't explain specifically why, but it seems working on my demo board when I try to hot-plugin the SD card.