玩转BeagleBoard xM——解决TF卡文件系统"readonly"错误

用TF卡作为bb的文件系统载体,在使用过程中,偶尔会遇到文件系统只能读取不能写入的错误,该问题轻则导致当前运行的程序出错,重则直接导致操作系统崩溃。通过执行dmesg命令,打印系统错误日志,发现以下错误信息:

    mmcblk0: error -110 transferring data, sector 4126233, nr 8, card status 0xc00 

error -110为mmc访问超时错误。上网google一下,发现OMAP系统有点挑TF卡,价格便宜、低端一些的卡比较容易出这个错。我用的Kingmax Class 10的卡很容易出这个问题,但换成Kinston Class 10的卡,就基本上没有出过错。当然,TI给出了官方的解决方法,可以通过修改mmc驱动,将延迟参数修改为最大值,来避免该错误。

 

具体解决办法:

STEP 1:修改Linux内核的mmc驱动

该驱动在Linux内核源码的drivers/mmc/host/omap_hsmmc.c文件中,以下为替换的代码部分:

drivers/mmc/host/omap_hsmmc.c |   30 +++++-------------------------

 1 files changed, 5 insertions(+), 25 deletions(-)

 

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c

index fd0c661..afd7292 100644

--- a/drivers/mmc/host/omap_hsmmc.c

+++ b/drivers/mmc/host/omap_hsmmc.c

@@ -1481,11 +1481,8 @@ static int omap_hsmmc_start_dma_transfer(struct 

omap_hsmmc_host *host,

        return 0;

 }

 

-static void set_data_timeout(struct omap_hsmmc_host *host,

-                            unsigned int timeout_ns,

-                            unsigned int timeout_clks)

+static void set_data_timeout(struct omap_hsmmc_host *host)

 {

-       unsigned int timeout, cycle_ns;

        uint32_t reg, clkd, dto = 0;

 

        reg = OMAP_HSMMC_READ(host->base, SYSCTL);

@@ -1493,25 +1490,8 @@ static void set_data_timeout(struct omap_hsmmc_host 

*host,

        if (clkd == 0)

                clkd = 1;

 

-       cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd);

-       timeout = timeout_ns / cycle_ns;

-       timeout += timeout_clks;

-       if (timeout) {

-               while ((timeout & 0x80000000) == 0) {

-                       dto += 1;

-                       timeout <<= 1;

-               }

-               dto = 31 - dto;

-               timeout <<= 1;

-               if (timeout && dto)

-                       dto += 1;

-               if (dto >= 13)

-                       dto -= 13;

-               else

-                       dto = 0;

-               if (dto > 14)

-                       dto = 14;

-       }

+    /* Use the maximum timeout value allowed in the standard of 14 or 0xE */

+       dto = 14;

 

        reg &= ~DTO_MASK;

        reg |= dto << DTO_SHIFT;

@@ -1534,13 +1514,13 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, 

struct mmc_request *req)

                 * busy signal.

                 */

                if (req->cmd->flags & MMC_RSP_BUSY)

-                       set_data_timeout(host, 100000000U, 0);

+                       set_data_timeout(host);

                return 0;

        }

 

        OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz)

                                        | (req->data->blocks << 16));

-       set_data_timeout(host, req->data->timeout_ns, req->data->timeout_clks);

+       set_data_timeout(host);

 

        if (host->use_dma) {

                ret = omap_hsmmc_start_dma_transfer(host, req);

 

注:-号表示删除该行;+号表示添加该行

 

STEP 2:重新编译替换uImage

完成修改后,重新编译内核,生成uImage文件,替换掉老的uImage。然后,重启,进行了若干天的压力测试,基本上就没有再出错了。

 

 

你可能感兴趣的:(c,测试,Google,linux内核)