免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3249 | 回复: 11
打印 上一主题 下一主题

[MID project] Daily Report from cavan [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-07 20:42 |只看该作者 |倒序浏览
1、搭建嵌入式linux(lablin)并测试
2、编译linux内核,添加SD卡支持
3、进入系统并mount SD卡,看是否能正常读写
4、在SD卡上制作rootfs
5、从SD卡mount rootfs,启动linux

论坛徽章:
0
2 [报告]
发表于 2010-03-08 12:42 |只看该作者
本帖最后由 CaoFuAng 于 2010-03-08 22:37 编辑

1、成功从sdcard mount rootfs 进入lablin
(1)开发板:MW2440
(2)sdcard类型:microSD卡(手机TF卡)
(3)Kernel command line: root=/dev/mmcblk0p1 rw rootfstype=ext3 mtdparts=s3c24x0_nand:0x20000@0x0(g-bios),0x80000@0x20000(g-bios),0x20000@0xA0000(sysconfig),0x200000@0xC0000(linux),0x200000@0x2C0000(ramdisk),0x3000000@0x4C0000(rootfs),0xCB40000@0x34C0000(data) ip=192.168.2.22:192.168.2.88:192.168.2.88:255.255.255.0:maxwit.googlecode.com:eth0ff console=ttySAC0,115200

2、sdcard读写速度与U盘、nand的对比
(1)编译内核,添加U盘驱动
(2)从你nfs mount rootfs 进入lablin
遇到问题:
(1)没有U盘的设备节点

论坛徽章:
0
3 [报告]
发表于 2010-03-09 20:04 |只看该作者
1、nandflash与microsdcard读写速度的对比

mount /dev/mtdblock5 /mnt/nand/
mount /dev/mmcblk0p1 /mnt/sdcard/

读写文件的大小:30082376 Byte = 29377.3203125 KB = 28.688789368 MB

nandflash读的速度
执行的命令:# i=5; while let i > 0; do let i--; time cp /mnt/nand/target /dev/null; done

第1次读用时:5.647s
第2次读用时:5.757s
第3次读用时:5.846s
第4次读用时:5.854s
第5次读用时:5.861s
平均用时:5.793s
平均速度:5071.1756 kb/s

microsdcard读的速度
执行的命令:# i=5; while let i > 0; do let i--; time cp /mnt/sdcard/target /dev/null; done

第1次读用时:7.560s
第2次读用时:7.510s
第3次读用时:7.713s
第4次读用时:7.495s
第5次读用时:8.096s
平均用时:7.6748s
平均速度:3827.763630648 kb/s

// =====================================================================

nandflash写的速度
执行的命令:# i=5; while let i > 0; do let i--; rm -rf /mnt/nand/target; time cp /tmp/target /mnt/nand; done

第1次写用时:30.023s
第2次写用时:39.826s
第3次写用时:31.868s
第4次写用时:34.542s
第5次写用时:34.330s
平均用时:34.1178s
平均速度:861.055528566 kb/s

microsdcard写的速度
执行的命令:# i=5; while let i > 0; do let i--; rm -rf /mnt/sdcard/target; time cp /tmp/target /mnt/sdcard; done                           

第1次写用时:26.569s
第2次写用时:26.878s
第3次写用时:25.654s
第4次写用时:27.578s
第5次写用时:25.696s
平均用时:26.475s
平均速度:1109.624940982 kb/s

打算在PC机上测试sdcard、usb HD、SATA的速度,然后以sdcard为中介,与nand对比,但是,同样是sdcard,在板子上的读写速度比PC慢很多,暂时没法对比,未免影响进度,先调寄存器。

2、成功读取sdcardID

论坛徽章:
0
4 [报告]
发表于 2010-03-10 23:57 |只看该作者
1、昨晚回到宿舍后一直读不出ID,经过长时间的调试后仍没有结果,后来无意中关了一下电,再次读ID竟然成功了,又多试了几次,发现只要有一次出错,就要重新开一下电源才能恢复正常,我推测可能是出错后sdcard进入inactive状态,只有断一下电才能恢复。后来很快就调稳了。
2、开始进行单块读操作。遇到问题,读命令发出后,fifo status寄存器一直为0。

论坛徽章:
0
5 [报告]
发表于 2010-03-11 14:42 |只看该作者
本帖最后由 CaoFuAng 于 2010-03-11 18:48 编辑

1、成功完成单块读操作。昨天一直收不到数据是因为:
(1)要在读之前设置SDIBSize寄存器的值,并且要4字节对其,否则收数据时会FIFO会出错。
(2)出现错误后要记得清一下状态。
(3)发命令的顺序不对。一定要先填写寄存器SDIDatCon,再发CMD17。单块读时SDIDatCon的正确值应为:0x9B6000 | 1,BlkNum表示要读写的块数,而不是字节数,若设的值大于1,则读完1块后,SD卡还将继续发送数据,一直处于RxDatOn状态。成功读取cardID以后编程的正确流程应为:
设置SDIBSize的值 ->设置SDIDTimer的值 -> 发送CMD3->[发送CMD9] ->发送ACMD6 ->发送CMD16->设置SDIDatCon的值->发送CMD17->读数据直到FIFO状态寄存器的RFDET位为0.
(4)总线宽度设置不对,我作了几次测试,结果如下:
     ACMD6设置的宽度    SDIDatCon设置的宽度    测试结果
      4                             1                                  成功
      4                             4                                  成功
      1                             1                                  成功
      1                             4                                  失败
可见只要ACMD6设置的总线宽度小于 SDIDatCon设置的宽度,就收不到数据。
在编程过程中,遇到的一些问题:
(1)似乎CMD16没有什么效果,无论CMD16设置BlockSize多大,实际读取的块大小始终与SDIBSize寄存器设的值一样。
(2)不清楚FIFO count (FFCNT),SDIDatCnt,Busy finish(BusyFin),之间的关系,于是作了下面的测试,主要使用三个函数:
static void sdi_show_command_status(u32 status)
{
        printf("SDICmdSta = 0x%08x\n", status);
       
        if (status & SDICmdSta_RspCrc)
                printf("*_* Error: Response CRC Fail(RspCrc) !!!!\n");
       
        if (status & SDICmdSta_CmdSent)
        printf("^_^ Command Sent(CmdSent)\n");
       
        if (status & SDICmdSta_CmdTout)
                printf("*_* Error: Command Time Out(CmdTout) !!!!\n");
       
        if (status & SDICmdSta_RspFin)
                printf("^_^ Response Receive End (RspFin)\n");
       
        if (status & SDICmdSta_CmdOn)
                printf("^_^ CMD line progress On (CmdOn)\n");
       
        printf("^_^ RspIndex = %d\n", status & SDICmdSta_RspIndex);
}

static void sdi_show_fifo_status(u32 status)
{
        printf("SDIFSTA = 0x%08x\n", status);

        if (status & SDIFSTA_FFfail)
                printf("*_* Error: FIFO fail error (FFfail) !!!!\n");
       
        if (status & SDIFSTA_TFDET)
                printf("^_^ FIFO available detect for Tx (TFDET)\n");
       
        if (status & SDIFSTA_RFDET)
                printf("^_^ FIFO available detect for Rx (RFDET)\n");
       
        if (status & SDIFSTA_TFHalf)
                printf("^_^ Tx FIFO half full (TFHalf)\n");
       
        if (status & SDIFSTA_TFEmpty)
                printf("^_^ Tx FIFO empty (TFEmpty)\n");
       
        if (status & SDIFSTA_RFLast)
                printf("^_^ Rx FIFO last data ready (RFLast)\n");
               
        if (status & SDIFSTA_RFFull)
                printf("^_^ Rx FIFO full (RFFull)\n");
               
        if (status & SDIFSTA_RFHalf)
                printf("^_^ Rx FIFO half full (RFHalf)\n");

        printf("^_^ FIFO count (FFCNT) = %d\n", status & SDIFSTA_FFCNT);
}

static void sdi_show_data_status(u32 status)
{
        printf("SDIDatSta = 0x%08x\n", status);

        if (status & SDIDatSta_NoBusy)
                printf("^_^ No busy (NoBusy)\n");
       
        if (status & SDIDatSta_RWaitReq)
                printf("^_^ Read wait request occur (RWaitReq)\n");
       
        if (status & SDIDatSta_IOIntDet)
                printf("^_^ SDIO interrupt detect (IOIntDet)\n");
       
        if (status & SDIDatSta_CrcSta)
                printf("*_* Error: CRC status fail (CrcSta) !!!!\n");
       
        if (status & SDIDatSta_DatCrc)
                printf("*_* Error: Data receive CRC fail (DatCrc) !!!!\n");
       
        if (status & SDIDatSta_DatTout)
                printf("*_* Error: Data time out (DatTout) !!!!\n");
       
        if (status & SDIDatSta_DatFin)
                printf("^_^ Data transfer finish (DatFin)\n");
       
        if (status & SDIDatSta_BusyFin)
                printf("^_^ Busy finish (BusyFin)\n");
       
        if (status & SDIDatSta_TxDatOn)
                printf("^_^ Tx data progress on (TxDatOn)\n");
       
        if (status & SDIDatSta_RxDatOn)
                printf("^_^ Rx data progress on (RxDatOn)\n");
}
在每次读取4个字节后,利用上面三个函数打印出各种状态。
测试结果见附件 test_result.tar.bz2 (919 Bytes, 下载次数: 38)
测试结果表明:FIFO的大小为64byte,收到命令的响应后,FIFO被填满,但数据还没有读完,所以BusyFin没有被置1,SDIDatCnt的值就是还没有从SD卡读到FIFO的字节数,此后每读取4个字节FIFO就有4个字节的空闲区域,但是FIFO仍然是满的,只有SDIDatCnt的值减了4,因为马上又有4个字节从SD卡读出并放入FIFO;当SD上最后一个字节被读出后,FIFO状态寄存器的RFLast位被置1,SDIDatCnt的值变成0,SDIDatSta寄存器的DatFin位也被置1,表明数据已全部从SD卡读出,此后每读一次FIFO的长度就减4,直到减为0,RFDET被置1,单块读取完成.

2、今天下午完成了单块写的函数。遇到了一个问题:总是发生CRC错误,猜想可能是没有发送CMD16设置BLOCK_LEN的缘故,查看代码,果然是没有发CMD16,最后通过发送CMD16把BLOCK_LEN设置成跟SDIBSize寄存器设的值一样,就能成功写了。于是猜测CMD16发送的BLOCK_LEN用于控制SD卡的与FIFO之间的通讯,而SDIBSize的BLOCK_LEN用于控制FIFO与Host的通讯,两者必须保持一致。

论坛徽章:
0
6 [报告]
发表于 2010-03-12 21:36 |只看该作者
本帖最后由 CaoFuAng 于 2010-03-12 21:38 编辑

回复 1# CaoFuAng


1、今天做多块读写和擦除。本来可以很快完成的,但是,我昨天晚上对代码作了很大的改动,把大部分的调试信息都去掉了,今天来的时候跑不了了,调了一个上午还是一无所获,无赖之下,下午吃完饭后又重新添加了很多的调信息,最终找到了出错的原因,详述如下:
(1)在修改代码的时候,把发命令的函数改坏了,把SDIDatCon寄存器的6~7位填成了3,本来应该是1的,导致发送命令总是超时。
(2)单块读的函数本身有误,在读之前没有检测sdcard的状态,如果刚写完一块马上有写下一块,此时sdcard还处于prg状态,如果这时发送CMD24,命令可以发送成功但sdcard不会接收数据,此时再往FIFO里写数一下子FIFO就满了,而且FIFO一直保持这种状态,程序就死在这里了。

2、下午成功完成多块擦除操作。遇到了一个问题:在擦除块时,把附近的块也擦除了。为了解决此问题,我在g-bios里添加了几个命令,单块读、单块写和多块擦除,读、写、擦除的地址及写大内容通过参数传入。经过多次测试后发现,只要地址落在某个块,哪个块就会被擦除掉,例如:起始地址是11,结束地址是22,则第0块将被擦除,当地址范围落在一个块内时,结束地址大于起始地址也可以。

3、多块读操作顺利完成。在单块读的基础上做多块读操作很简单,只要到填写SDIDatCon寄存器的时候,把BlkNum设为将要读的块数,在读完了指定的块数发送CMD12即可。在编程是还发现,SDIDatCon寄存器的BlkNum位数与SDIDatCnt寄存器的BlkNumCnt位数相同,估计SDIDatCnt寄存器跟sdcard没有通讯,反应的是主机端的状态,以便于编程。

4、多块写也已完成,只是发送CMD12的时机没有掌握好,还需要进一步的调试。

论坛徽章:
0
7 [报告]
发表于 2010-03-14 00:02 |只看该作者
本帖最后由 CaoFuAng 于 2010-03-14 00:03 编辑

回复 1# CaoFuAng

    今天开始写子系统。上午写子系统时又对代码作了大幅度的调整。下午进行调试,在去掉了所有的打印语句后有时不能正常读写,估计应该是延时的问题,但是在相应的地方加了延时后,还是没有任何改善,于是又在g-bios里增加了一条命令用于用于输出各个寄存器的状态,当读取失败后,执行该命令,发现寄存器ADIDatCnt的值不是0。原来是前一次读卡没有读完,sdcard一直处在data状态,导致发读写命令总是失败。至此,sdcard的读写及擦除函数都已跑稳了。接下来将用sdcard load g-bios下半部分,以便进行进一步的测试,为把代码移植到kernel作准备。

2010年03月13日的日志

论坛徽章:
0
8 [报告]
发表于 2010-03-14 22:51 |只看该作者
本帖最后由 CaoFuAng 于 2010-03-14 22:53 编辑

1、今天改写g-bios的tftp代码,增加sdcard load功能。直接用tftp把g-bios下半部分下载到sdcard,并从sdcard load g-bios下半部分,为了达到此目的,进一步完善了子系统,给sdcard添加catche,在读写是只需给定buffer和大小即可。每个mmc controler上可以挂多个sdcard,每个sdcard有自己独立的catche,要写入的数据首先与catche进行合并,如果合并后的大小大于一个block的大小则写入到sdcard中,否则就直接退出。首先用单块写操作把catche中的数据写入到sdcard中,接着用多块写操作,把数据写到sdcard中,最后可能还有剩余,所以要把剩余部分保存到catche中,以便与下一次要写的数据合并。考虑到最后一次写完后很可能还会有还有剩余,于是又添加一个函数,把catche中的所有数据写到一个块中。

2、在写的过程中遇到了问题: 刚写了一块数据马上有发送写的命令,总是发送失败,发现前一次还没写完sdcard还处在programme状态,此时是不允许写的,必须等到sdcard回到tran状态才能继续发写命令,需要进行等待。到底是在写前等待了,还是应该在写后等待?于是分别作了测试,发现写后等待效率要高一些,因为在等待的时候要靠发命令CMD13来读状态,在开始读的时候可能sdcard不是在program状态,而我们又必须发CMD13才能知道sdcard的状态,这就浪费了时间。而在写完后在等待时,我们确切的知道sdcard肯定处在program状态,虽然也要发CMD13才能知道sdcard的状态,但是,这并没有浪费时间,因为发CMD 13的过程就是等待的过程。

论坛徽章:
0
9 [报告]
发表于 2010-03-15 22:33 |只看该作者
DONE:
完成了子系统的设计
TODO:
(1)对子系统进行测试;
(2)分析kernel源码的sdcard子系统;
(3)把sdcard驱动移植到kernel;

论坛徽章:
0
10 [报告]
发表于 2010-03-16 22:10 |只看该作者
DONE:
(1)子系统调试成功;
(2)成功从sdcard loader g-bios下半部分。
TODO:
(1)分析g-bios的分区表;
(2)分析kernel源码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP