历史上的今天
返回首页

历史上的今天

今天是:2025年04月15日(星期二)

正在发生

2018年04月15日 | S3C6410使用---7uboot中SD初始化及读写分析

2018-04-15 来源:eefocus

一、uboot中SD卡的初始化
二、读取扇区
三、 写变量到SD卡中
四、

一、uboot中SD卡的初始化
1.1 硬件连线

  1. MMC0_CDN     -->     GPG6       --> SD卡检测引脚 

  2. MMC0_WPN     -->     GPGL13     --> SD卡写保护引脚

  3. MMC0_DATA[0-3] -->   GPG[2-5]   -->

  4. MMC0_CMD     -->     GPG1       --> SD命令线

  5. MMC0_CLK     -->     GPG0       --> SDIO/SD卡时钟线

1.2 uboot中初始化过程
uboot lib_arm/board.c中

  1. void start_armboot (void)

  2. {

  3. #if defined(CONFIG_BOOT_MOVINAND)

  4.     puts ("SD/MMC: ");

  5.     if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {

  6.         printf("Boot up for burningn");

  7.     } else {

  8.         movi_set_capacity();

  9.         movi_set_ofs(MOVI_TOTAL_BLKCNT);

  10.         movi_init();

  11.     }

  12. #endif

  13. }

 a. 设置为sector mode   

  1. movi_set_capacity();

  2. {

  3.     if (MOVI_HIGH_CAPACITY & 0x1) //in sector mode, this value will be set

  4.         movi_hc = 1; //全局变量movi_hc=1

  5. }

 b.以扇区为单位,设置BL1,ENV,BL2,kernel,rootfs的位置    

  1. movi_set_ofs(MOVI_TOTAL_BLKCNT);

  2. {

  3.     if (ofsinfo.last != last) {

  4.         ofsinfo.last = last - (eFUSE_SIZE / MOVI_BLKSIZE);

  5.         ofsinfo.bl1 = ofsinfo.last - MOVI_BL1_BLKCNT;

  6.         ofsinfo.env = ofsinfo.bl1 - MOVI_ENV_BLKCNT;

  7.         ofsinfo.bl2 = ofsinfo.bl1 - (MOVI_BL2_BLKCNT + MOVI_ENV_BLKCNT);

  8.         ofsinfo.kernel = ofsinfo.bl2 - MOVI_ZIMAGE_BLKCNT;

  9.         ofsinfo.rootfs = ofsinfo.kernel - MOVI_ROOTFS_BLKCNT;

  10.         changed = 1;

  11.     }

  12. }

 c. SD控制器初始化   

  1. movi_init();

  2. {

  3.     hsmmc_set_gpio();

  4.     {

  5.         reg = readl(GPGCON) & 0xf0000000;

  6.         writel(reg | 0x02222222, GPGCON); //设置 GPG为MMC模式

  7.         reg = readl(GPGPUD) & 0xfffff000;

  8.         writel(reg, GPGPUD); //上拉电阻disable

  9.     }

  10.     hsmmc_reset();

  11.     {

  12.         s3c_hsmmc_writeb(0x3, HM_SWRST);   //data_line && cmd_line reset        

  13.     }

  14.     if (hsmmc_init()) {

  15.         printf("nCard Initialization failed.n");

  16.         return -1;

  17.     }

  18.     return 1;

  19. }

cpu/s3c64xx/hs_mmc.c

  1. int hsmmc_init (void)

  2. {

  3.     hsmmc_clock_onoff(0); //关闭SDCLK

  4.     {

  5.         a. CLKCON0[2]:0 //SD Clock diaable

  6.     }

  7.     

  8.     a. SCLK_GATE-->0x7E00_F038[27]:

  9.     SCLK_MMC0_48 [27] Gating special clock for MMC0 (0: mask, 1: pass)

  10.     

  11.     b.

  12.     set_clock(SD_EPLL, 0x80);

  13.     {

  14.         //CONTROL2_0 0x7C200080 R/W Control register 2 (Channel 0)

  15.         //[5:4]: Base Clock Source Select--> EPLL

  16.         //[14]:1 Feedback Clock Enable for Rx Data/Command Clock

  17.         //[30]:1 Command Conflict Mask Enable

  18.         //[31]:1 Write Status Clear Async Mode Enable 

  19.         s3c_hsmmc_writel(0xC0004100 | (clksrc << 4), HM_CONTROL2);

  20.         

  21.         s3c_hsmmc_writel(0x00008080, HM_CONTROL3);

  22.         s3c_hsmmc_writel(0x3 << 16, HM_CONTROL4);

  23.         //下3条: SDCLK Frequency Select

  24.         //div=80h base clock divided by 256

  25.         //

  26.         //最后的for The SD Host Driver shall wait to set SD Clock Enable until this bit is set to 1.

  27.         s3c_hsmmc_writew(s3c_hsmmc_readw(HM_CLKCON) & ~(0xff << 8), HM_CLKCON);

  28.         s3c_hsmmc_writew(((div<<8) | 0x1), HM_CLKCON);

  29.         for(i=0; i<0x10000; i++) ; //wait stable

  30.         

  31.         hsmmc_clock_onoff(1);

  32.     }

  33.     c. s3c_hsmmc_writeb(0xe, HM_TIMEOUTCON);

  34.         TIME_OUT_CNT=1110b TMCLK x 2的27

  35. }

为了区别SD卡是2.0还是1.0,或是MMC卡,这里根据协议向上兼容的原理,首先发送只有SD2.0才有的命令CMD8,如果CMD8返回无错误,则初步判断为2.0卡,进一步发送命令循环发送CMD55+ACMD41,直到返回0x00,确定SD2.0卡初始化成功,进入Ready状态,再发送CMD58命令来判断是HCSD还是SCSD,到此SD2.0卡初始化成功。如果CMD8返回错误则进一步判断为1.0卡还是MMC卡,循环发送CMD55+ACMD41,返回无错误,则为SD1.0卡,到此SD1.0卡初始成功,如果在一定的循环次数下,返回为错误,则进一步发送CMD1进行初始化,如果返回无错误,则确定为MMC卡,如果在一定的次数下,返回为错误,则不能识别该卡,初始结束。


二、读取扇区
SDMK6410> fatload mmc 0:1 50008000 zImage
以读取MBR为例
do_fat_fsload 
    --> fat_register_device(dev_desc,part);
        --> dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)buffer);
1. 初始化时
hsmmc_init() //初始化mmc_dev的函数指针
{
    mmc_dev.if_type = IF_TYPE_MMC;
    mmc_dev.part_type = PART_TYPE_DOS;
    mmc_dev.dev = 0;
    mmc_dev.blksz = MMC_BLOCK_SIZE;
    mmc_dev.block_read = mmc_bread;
}    
2. 正式进入读取部分
cpu/s3c64xx/hs_mmc.c L1337
/*
    dev_num: 第几个mmc设备
    blknr:   开始的扇区
    blkcnt:  要读取的扇区数
    dst:     数据保存到的dst_buffer 
*/
static ulong mmc_bread (int dev_num, ulong blknr, ulong blkcnt, ulong* dst)
{
    if (dst >= 0xc0000000)
        dst = virt_to_phys(dst); //取物理地址
    if (blkcnt != 0)        //连dev_num都不要了,看来只能支持1个SD设备
        movi_read((uint) dst, (uint) blknr, (uint) blkcnt);
    return blkcnt;
}

void movi_read (uint addr, uint start_blk, uint blknum)
{
}

三、写入扇区
SMDK6410> saveenv


推荐阅读

史海拾趣

Analog Microwave Design公司的发展小趣事

随着公司规模的不断扩大,Analog Microwave Design公司开始将目光投向国际市场。为了更好地拓展海外业务,公司制定了一套完善的国际化战略。首先,公司加强了与国际知名企业的合作,通过技术交流和合作研发,提升了公司的技术水平和国际影响力。其次,公司积极参加国际展览和会议,展示公司的最新产品和技术成果,吸引了众多海外客户的关注。通过这些努力,公司的海外业务得到了快速发展,成为公司新的增长点。

Austek Microsystems公司的发展小趣事

随着产品线的不断丰富和技术实力的不断提升,Austek Microsystems开始积极拓展市场。公司不仅在国内市场取得了良好的销售业绩,还积极开拓海外市场,与多个国家和地区的客户建立了稳定的合作关系。同时,Austek Microsystems还注重品牌建设,通过参加行业展会、举办技术研讨会等方式,提升品牌知名度和影响力。

百佳(BAIJIA)公司的发展小趣事

百佳公司的创始人蔡永权,在改革开放初期,凭借敏锐的商业洞察力和对技术的执着追求,创立了中山市古镇百佳电子电器厂。初创时期,公司面临着资金短缺、设备简陋、市场竞争激烈等多重困难。然而,蔡永权带领团队坚持不懈,以质量为核心,通过不断改进生产工艺和提升产品质量,逐渐赢得了客户的信任和市场的认可。

General Electric Solid State公司的发展小趣事

在多年的发展过程中,百佳公司始终坚守品质至上的原则。他们严格把控产品质量,从原材料采购到生产制造的每一个环节都进行严格的监控和检测。同时,百佳公司还注重提升客户服务水平,为客户提供及时、专业的技术支持和售后服务。正是这种对品质的坚持和对客户的尊重,使得百佳公司赢得了广大客户的信赖和长期合作。

这五个故事只是百佳公司在电子行业发展中的一部分缩影。它们展示了百佳公司从初创时期的艰苦与坚持,到抓住市场机遇迅速崛起,再到技术创新引领发展、拓展国际市场实现全球化布局,以及坚持品质至上赢得客户信赖的完整历程。这些故事不仅见证了百佳公司的成长和成功,也展现了电子行业的蓬勃发展和无限可能。

GWP Group公司的发展小趣事

百佳公司的创始人蔡永权,在改革开放初期,凭借敏锐的商业洞察力和对技术的执着追求,创立了中山市古镇百佳电子电器厂。初创时期,公司面临着资金短缺、设备简陋、市场竞争激烈等多重困难。然而,蔡永权带领团队坚持不懈,以质量为核心,通过不断改进生产工艺和提升产品质量,逐渐赢得了客户的信任和市场的认可。

Good-Ark公司的发展小趣事
为整个电路提供所需的电能。

问答坊 | AI 解惑

Windows CE中的命令提示行的和PC机上的XP中的有啥区别?

网上说:     Windows CE和Windows XP Embedded存在诸多本质区别。首先,Windows CE是一款全32位、Unicode操作系统,它不支持MS-DOS或Windows 3.x应用。         这里说的MS-DOS不就是台式机上的命令提示行中DOS ...…

查看全部问答>

串口通讯中的DCB结构

串口通讯中的DCB结构 我看很多程序,它里面使用了BCD结构,但是BCD结果不是在winbase.h中定义的吗, 程序里面并没有#include \"winbase.h\",但是编译确实成功的,为什么? 我是学了VC现在学EVC,觉得有点困扰,EVC很多库函数都不一样了,怎么找 ...…

查看全部问答>

求关于嵌入式软件低功耗的论文

急求关于软件低功耗的文章!!! 搜到很多都是收费的,要不就是类似的,拜托各位高手帮帮忙!!! 谢谢了!!!…

查看全部问答>

bootloader中的一些问题

小弟关于bootloader中有几个问题不清楚,麻烦兄弟们帮忙解释下, 1,其中涉及到内存映射,它的作用是什么? 2,cpu又是如何区分flash和ram的地址呢,难到有控制flash和ram地址的寄存器吗? 3,如果flash的os要加载到ram中执行,又是如何实现拷贝的呢,如 ...…

查看全部问答>

急求Lcd 中“-”的编码?

急求Lcd 中“-”的编码? 顺便问下Lcd中是怎样进行汉字编码的!…

查看全部问答>

wince 6和VS2005 共存问题

   在安装了wince6以后发现vs2005的本地帮助文档不能用了,在修复了本地文档之后,原来的wince6项目又不能用了,在修复wince6,本地文档继续不能用。太郁闷了,大家有什么解决办法啊?…

查看全部问答>

EVC环境下为什么delete对象无法释放内存

我写了一个很简单的程序,窗口上就两个按钮,用于动态分配和释放内存.打开WinCE.net的SystemProperties的Memory选项卡查看内存情况,发现分配可以,但按了释放内存的按钮却不能释放内存,不知原因,望高手指点!…

查看全部问答>

求救,STM32F101VCT6下载出现问题,

请教各位一个问题,我们现在用STM32F101VCT6的MCU,用IAR J-LINK下载出现一个错误提示: “Could not write CPU register MSP:Written:0xFFFFFFFF,Read 0xFFFFFFFC” 是什么原因的呢??…

查看全部问答>

24L01的问题

本帖最后由 paulhyde 于 2014-9-15 09:01 编辑 我用NRF24L01传输温度,开始温度还随时能变化,变几下就不动了,用手捏也不动,需要复位才可能正常工作,有时候复位好多次才行,这是为什么?(用其他方法测试也都要复位,是nrf24L01出现什么问题了 ...…

查看全部问答>

vc33怎么用c语言实现扩展精度?

vc33中float是32位,十进制是8位有效位。如果8位有效位不够用,怎么用扩展精度使有效位更多?…

查看全部问答>