免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-03-07 21:30 |只看该作者 |正序浏览
本帖最后由 syukayo 于 2010-03-07 21:34 编辑

SD卡测试

   1. 首先要有一个测试环境,这里使用g-bios + linux kernel + lablin(rootfs)。 kernel中要选中对SD卡的相关驱动选项。
   2. 接着先测试kernel以及SD卡的驱动的正确性。 加载kernel, cmdline里选择NFS启动方式,挂载host端的rootfs。 进入字符界面后检查/dev下有没有SD卡的设备文件。
      确定kernel和SD卡,以及rootfs是否可用。
   3. 将可用的rootfs挂载到SD卡上, 然后让kernel挂载SD卡的rootfs启动,这里要正确修改kernel 的cmdline,让kernel挂上SD卡的rootfs。

论坛徽章:
0
12 [报告]
发表于 2010-03-18 23:12 |只看该作者
[Mar 18]
<1>. DONE:
        1. g-bios mmc sub system rewrite.添加了一些对象属性,增加了mmc bus operation.
子系统采用mmc_core.c, mmc_bus.c, s3c_mmc.c架构来实现对sd card的读写操作。
        2. 通过编写g-bios子系统,来理解kernel sd driver的底层函数实现。

<2>. TODO:
        1. 完善子系统,并进行测试。
        2. 这两天kernel sd driver没多少进展,继续kernel development.

论坛徽章:
0
11 [报告]
发表于 2010-03-17 21:55 |只看该作者
[Mar 17]
<1>. DONE:
        1. g-bios TH load BH 测试成功。之前一直调试不通,发现主要卡在了2个地方。首先是TH的printf
函数,没实现完整,有BUG,不能正确打印,观察不了寄存器的值。第二处则是GBT_START_MEM,发现
这个链接地址被设置在RAM地址最后靠前512KB处,BH_SIZE为512KB,TH从SD读取BH代码,往RAM写的时候,
读取了1024个块,多了一块,越界,因此程序一直挂掉,于是减去一个块的数据,成功load.
        2. 看了一下SD CARD的关于文件系统结构的资料,有了个概念,但没实现思路。

<2>. TODO:
        1. kernel sd driver 完善及测试。

论坛徽章:
0
10 [报告]
发表于 2010-03-16 23:24 |只看该作者
[Mar 16]
<1>. DONE:
        1. 编写kernel sd card driver code, 框架已经成形.
        2. 进行初步调试,卡在了发命令的地方,调用子系统的发命令函数,kernel panic

<2>. TODO:
        1. 明天继续kernel sd drive相关函数编程及测试。

论坛徽章:
0
9 [报告]
发表于 2010-03-15 22:21 |只看该作者
[Mar 15]
<1>. DONE:
        1. 修改了app/serial/下的ymodem函数,实现了将g-bios-bh.bin download to sd card.抽样比较
了几块数据,2者数据吻合.
        2. 在boot/下添加了2个mmc相关文件, 编写完成了GTH load GBH的函数. 但是测试未通过.期间printf函数
一直出错,导致显示不了调试值,待继续调试.
        3. kernel driver/mmc/host下添加mmc驱动文件,写了个基本框架.

<2>. TODO:
        1. 在kernel下完成mmc driver基本功能代码,并调试.
        2. 继续调试GTH load GBH代码.

论坛徽章:
0
8 [报告]
发表于 2010-03-14 23:23 |只看该作者
[Mar 14]
<1>. DONE
        1. 看了下kernel driver下mmc子系统里面的跟sdi相关的代码实现。core下面是核心子系统,card下是sd card块设备
的注册及一些实现,host下则是具体soc的sd/mmc host controller interface driver. 这里关注了下samsung的
s3cmci.c. 驱动框架都差不多,要操作的有mmc_host_ops里的几个函数,不过不太理解为什么要有那些实现。待自己写一遍后再
慢慢体会。
        2. 看了下g-bios下app里的ymodem,tftp的实现,打算将g-bios下半部load到sd card里并实现启动。

<2>. TODO
        1. 编写代码,实现ymodem下载g-bios-bh至sd card, 并测试到稳定。顺利的话在tftp里也增加sd card load功能.

论坛徽章:
0
7 [报告]
发表于 2010-03-13 20:31 |只看该作者
本帖最后由 syukayo 于 2010-03-13 20:32 编辑

[Mar 13]
<1>. DONE
        1. MMC子系统已出框架,提供了mmc_read, mmc_write, mmc_erase三个函数,在APP里写具体应用程序来
测试sd card的read,write,erase函数。经测试,对单独一块的读写擦操作都没问题,但是一旦执行多块操作后问题不断。
        首先对多块连读进行测试,发现每次都是第一次读能正确(重启后第一次),后面的读操作都读到错误数据。打印
发完连读命令CMD18后的resp数据,第一次是0x00000900,相关意思是sd card现在处在transfer state并且ready_for_data,
就是说可以对卡进行读操作,读出来后数据正确。第二次则是0x00000B00,表示card处在data state,说明它还停留在上次发数据
阶段,data可读,但读出的数据错误。之后又出现0x80400B00, 0x00400B00等错误response,分别为OUT_OF_RANGE,
ILLEGAL_COMMAND. 区别第一次与第二次的不同在于它们所处的state不同,正常情况card应该在tran态才能进行数据读写操作,
data态说明数据还在发送,看了datasheet的state diagram之后,发现读完后要发CMD12停止命令才能让card转入transfer
state.在read函数结束前我加了个CMD12命令后,multi block read正常。多次验证,没发生错误。
        接着就是对多块连写的测试了。连写过程要特别关注state diagram,host端发数据给sd card,发过来很快,
card端接收后,会有一个programming state,也就是要写入sd card,这个过程需要时间缓冲,sd card会产生阻塞,
不接收host的数据,于是会导致host的FIFO变为full状态,这个时候如果host端继续往SDIDAT寄存器里写的话就会出错,所以
这里必须要有个阻塞等待的过程。数据写完,然后再判断下FIFO里的数据是否为空,看下是不是都发过去了。完了之后再发送
CMD12命令告诉SD操作完毕可以切换状态。之后SD卡还可能会在programming state,保险起见发个CMD13过去看下resp里的
card status是否转入transfer state后再退出函数。
        还有就是发现erase过程也会进入programming state,所以也需要等待,发CMD13看response,直到卡转入transfer
state为止。这样read,write,erase功能基本成形,并经过多次测试,都无问题。
        2. 利用read函数,找到了windows下烧g-bios的TH部到SD card的地址。发现在卡的底部靠前562个block开始处,一共
10个block大小左右,这里block为512bytes.

<2>. TODO
        1.试下在g-bios th起来后,用ymodem协议将g-bios下半部烧入sd card并启动.以及看下tftp传输状况,使得g-bios
下半部可以选择从tftp下载bh到sd card.
        2.ready to write kernel sd driver.

论坛徽章:
0
6 [报告]
发表于 2010-03-12 21:48 |只看该作者
[Mar 12]
<1>. DONE
        1. 确定sd card分区表所在block. 首先在PC机上建立分区,然后用dd命令读取第一块数据(512Bytes).
dd if=/dev/sdb of=sdblk.bin bs=512 count=1 该命令可以直接读取块设备里的数据.if后面是设备文件,
of是数据读取后存放的文件,bs为block size,count为读取的block数.这样sdblk.bin里就有了从sd card读出来
的数据了.用vi打开发现是乱码,这里可以用vi命令 :%!xxd 可以把2进制码转换成hex码,并保存.
然后把卡插入开发板,覆盖或erase第一块内容后, 再放入PC机上读取该卡,发现之前的partition table没了.
接下来把先前保存的第一块内容数据重新写入第一块内,再读取,发现分区复原了.由此可以确定第一块保存了分区里的信息.
        2. 完成了block erase功能, erase后读出的数据全为0xFF. erase操作比较简单,设置擦除起始块addr,由
CMD32命令发出,再设置结束块addr,CMD33发出,最后一个erase命令CMD38,将擦除之前所设地址间的块.命令发完后
需要发CMD13来判断下card status的bit8,来确认erase操作是否结束.否则读写操作很可能出现问题.
        3. 编完了read multiblock函数, block数少的时候可以读成功,但是块数一大就有问题出现.明天继续调试.
        4. 将代码整理到一个子系统上,基本框架已出来,在APP上测试读函数成功.

<2>. TODO
        1. 完善并测试multiblock read, write and erase function. 并完善子系统.
        2. 研究下kernel中mmc子系统. 打算着手写kernel sd驱动

论坛徽章:
0
5 [报告]
发表于 2010-03-11 20:33 |只看该作者
[Mar 11]
1. 经过昨晚的调式,read一个block已经测试成功。
  首先熟悉下初始化读CID过程:
        (1) 配置SDI的GPIO,主要用到了6个引脚DAT0~3,CMD,CLK
        (2) 配置SDIPRE,初始工作时钟SDCLK,可以让card在200~400kHz下工作。
        (3) 设置了CLK,就可以使能该CLK,[SDICON]
        (4) 设置(SDIDTIMER,SDIBSIZE,SDIFSTA),读写数据时用,可以先不设置。
        (5) 先延时1s左右,让sd card电压升到稳定状态.接下来就是发送CMD了.
        CMD0 --> CMD8 ---> CMD55 --> CDM41 -- OCR.bit31 is set or not --> CMD2
                                   ^------------------------^
                发送CMD2之后, 如果之前都配置正确的话, CMD2的RESP里就有CID信息了.
  初始化完之后,就可以尝试read a block, 先配置好(4)的几个寄存器, DTimer可以设大一点,否则容易发生
timeout, 接着发CMD3来获取一个RCA,可以连续发2个CMD3,来确定以下RCA值是否会变.有了RCA,之后凡是有用到
RCA作参数的都用该RCA值,CMD3之后card进入stand-by state.接下来可以发个CMD9, 来读取下CSD的信息
(如果有必要).然后发CMD7, 让sd card进入transfer state. 在该状态下可以配置sd card的blksize,
bus width等等.在transfer state下, 可以发送相应的read,write命令了.

   昨天的主要问题还是出在arg的配置上,CMD55的arg是[31:16]RCA,[15:0]stuff bits.
由于第一次在发ACMD41的时候,当时还没有RCA从card端传过来,故用的是0x0, 读完CID以后,
用CMD3获取了一个RCA,故之后的命令中有RCA作参数的就需要指定CMD3获取的RCA,而我在之后用到
CMD55的地方,RCA还用的是0,所以cmdsta一直timeout状态。注意到了以后,之后凡是用到RCA的
都用了正确的RCA值。另外,在填host端与card端的block size 与bus width时要注意一致。
在blksize上,我两端都直接设置为通用的512bytes/blk, bus采用4位来传输数据。发完读一块数据命令
CMD17后,就可以循环读取SDIDAT上的数据了.这里的数据都是来自FIFO的,故要检测是否读完,可以判断下
SDIFSTA的BIT12,当FIFO empty的时候就可以结束数据读取了. 还需要注意的是发送命令的参数
[31:0]data address 这个参数是表示要读取的是哪个块.这个data addr应该设为blksize的整数倍:
BLKN * BLKSIZE, BLKN就是block的index了.
        数据读是读了,但是不知道对不对.所以往里面写一块数据,然后再读出来验证以下.

2. 编写write函数。
        往一个block里写数据的命令是CMD24,写哪一块取决与arg,也就是data address.写之前与读一样都得
先配置SDIDATCON.
        write a block data成功, 但是写完立刻读,发现没数据读出来.fifo为空. 先读,后写同一块区域时,
可行, 数据是上一次写操作时的数据,此操作验证了write函数已经成功.
        于是测试先往连续10个block里写不同的数据,然后接着读取这10个block里的数据.结果发现第一块读取
数据失败,后9个block可正常读取,数据也正确.经多次测试及讨论,最后问题确定在SDIDATCON这个寄存器的
BlkNum这段位域上,这个位域表示的是block num(0~4095),我原以为可以随便填个数,后来才知道这个位域表示
一次要发的block数,所以发一个block时,该位域值设为1才正确.填完之后,收发一切正常.

3. 总结一下read,write时要注意的地方. 首先当然是要填对相关寄存器的值,以及各命令要用的参数. 设置都
正确了,接下来就是判断status register了.这里的几个registers的一些判断位比较容易混淆:
SDIDatSta 显示数据传输状态及正确性. 数据发送,接收完毕后,DatFin位都会置一.但是不表示数据发送,接收结束,
          因为FIFO里还留有数据.
SDIFSTA          这里的状态位域比较重要,因为数据都是先存放在FIFO里的,跟read,write的操作密切相关.
          write时检测TFDET位, set时可以发送数据.由于测试时是单块数据发送,FIFO里不会存留数据,
          写一次立即被发送,故可以直接将一块数据写入SDIDAT中.
          read时检测RFDET位,set时表示有数据过来,可以接收.还有一位RFLast需要注意,该位不是说数据接收
          结束,而是表示SD端数据发送完毕,FIFO里还留有数据,所以只要判断RFDET位即可,FIFO empty时即可
          结束接收.

论坛徽章:
0
4 [报告]
发表于 2010-03-10 22:42 |只看该作者
[Mar 10]

   今天首先在g-bios下测试了读cid代码,已经可以正确读取cid. 然后细读spec上用于读写的命令,以及2440上的几个register。
接着写了下read函数,想从sd card读取一个block的数据,未果。
   主要问题是一些command的arg参数没配置正确,有些参数也不清楚写什么值好,需要逐个试验。还有2个status register的几个位也比较容易混淆,
SDIFSTA与SDIDATSTA, 不清楚读数据时判断哪些位恰当。然后读写用的几个控制寄存器设置也存在些问题,准备一步步测试。 进度比较缓慢。
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP