跳至主要內容

RT-Thread 各版本问题整理

马龙伟...大约 1 分钟笔记RT-Thread

RT-Thread 4.1.0

SD 驱动框架

SD 初始化失败移除 blk_dev 时存在双向链表 nextprev 都为 NULL 的情况,造成死循环。

修改 rt_mmcsd_blk_remove:

void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
{
    rt_list_t *l, *n;
    struct mmcsd_blk_device *blk_dev;

+     if(card == RT_NULL)
+     {
+         LOG_E("card is null!");
+         return;
+     }
+
+     if(rt_list_isempty(&card->blk_devices))
+     {
+         LOG_E("card blk_devices is empty!");
+         return;
+     }
+
+     if ((&card->blk_devices)->next == RT_NULL)
+     {
+         LOG_E("card blk_devices is null!");
+         return;
+     }

    for (l = (&card->blk_devices)->next, n = l->next; l != &card->blk_devices; l = n, n=n->next)
    {
        blk_dev = (struct mmcsd_blk_device *)rt_list_entry(l, struct mmcsd_blk_device, list);
        if (blk_dev->card == card)
        {
            /* unmount file system */
            const char * mounted_path = dfs_filesystem_get_mounted_path(&(blk_dev->dev));
            if (mounted_path)
            {
                  dfs_unmount(mounted_path);
                  LOG_D("unmount file system %s for device %s.\r\n", mounted_path, blk_dev->dev.parent.name);
            }
            rt_sem_delete(blk_dev->part.lock);
            rt_device_unregister(&blk_dev->dev);
            rt_list_remove(&blk_dev->list);
            rt_free(blk_dev);
        }
    }
}

F4 SD 写入时偶尔长时间等待

rthw_sdio_send_command 的实现方式为 while 死等结束或者超时,会造成低优先级的任务在这段时间内不运行。

修改 drv_sdio.c:

- #define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS    (100000)
+ #define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS    (10000) //经测试为1.3ms

static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
{
    ...
    if (data != RT_NULL)
    {
        volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
+       volatile rt_uint32_t loop_cnt = 800;  // count为10000时一个loop约为1.3ms,800个loop约为1.04s

-        while (count && (hw_sdio->sta & (HW_SDIO_IT_TXACT | HW_SDIO_IT_RXACT)))
-        {
-            count--;
-        }

+        while (count && (hw_sdio->sta & (HW_SDIO_IT_TXACT | HW_SDIO_IT_RXACT)))
+        {
+            count--;
+            if ((count == 0) && (loop_cnt > 0)) {
+                rt_thread_mdelay(1);
+                count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
+                loop_cnt--;
+            }
+        }

        if ((count == 0) || (hw_sdio->sta & HW_SDIO_ERRORS))
        {
            cmd->err = -RT_ERROR;
        }
    }
    ...
}
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.5