最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

编写uboot下Nor Flash驱动的注意事项

工作和技术 crifan 2348浏览 0评论

编写ubootNor Flash驱动的注意事项

Version: 0.9

Date:20090826

Authorcrifan

Mail:green-waste(At)163.com

.

Nor Flash中的一些术语】

1.       Bottom/Top Boot Sect(底部/顶部 启动块)

所谓的boot sect,是指的是Nor FlashNand Flash不太一样。Nand Flash从开始到最后,都是由同样大小的page所组成的。

Nor Flash,一般都是有个boot sect,好像是由于历史原因,常将Nor Flash用于作为存储启动代码的设备,也就是从Nor Flash启动,所以,这个boot sect块,专门设计出来,用于存放启动代码。如果详细解释,按照datasheet中的描述就是,第一个或最后一个,此处是bottom sect,所以是最后一个64KB大小的块,被分为4个独立的块。第一个16KB,用于少量的系统初始化代码。而28KB的块用于存储参数,余下的32KB的块叫做Main Block,用于存储应用程序的代码。

2.       Sector(扇区)

此处的sector(扇区)也就是flash里面的最小的擦除单位:块(block)。

所以sector count,也就是有多少个block

3.       Sector Count (扇区数)Sector List

此处的Nor FlashM29W320DB,一共有正常的6364KBblock,加上上面提到的原先是正常的164KB分成的4个小块,所以是63+4=67个。

而所谓的驱动中的sector list,也就是block list,代码注释写的也很清楚了:

       ulong      start[CFG_MAX_FLASH_SECT];   /* physical sector start addresses */

用于存储每一个块的起始地址的。也是需要你驱动初始化的。对于这里的M29W320DB,也很简单了,从开始顺序加上块大小64K,直到最后3个,计算一下对应地址,填进去就可以了。

4.       Protect(写保护)

Nor Flash从软件的寄存器配置和硬件上,都提供了对应的保护机制,目的是,防止有意或无意间,把那些不希望被改动/删除的数据破坏了。比如有些机制把Flash的一些系统启动参数存储Nor Flash,或者是其他某种原因,只允许你使用部分Nor Flash的空间,所以,把这类需要保护的部分,在ubootflash_info_t的结构体中,把对应的位设置成1

       uchar      protect[CFG_MAX_FLASH_SECT]; /* sector protection status */

这样,之后程序就可以避免有意无意的擦除有用的数据了。

【写Nor Flash驱动时的一些注意事项】

1.       位宽(bitwidthX8/X16/X32

Nor Flash控制器,此处我这里用的是,ARMPromeCell PL172MPMCMultiPort Memory Controller),可以接多种不同的存储设备,比如SRAMStatic Memory),Nor Flash,而其中又可以分别设置是否支持Page ModeExtended wait和写保护(启用写保护,就可以看出是ROM了)等。

在硬件上MPMCNor Flash连接好了之后。在使用Nor Flash之前,要初始化MPMC

这里说的,要注意位宽,是因为我开始就没注意到,所以,在开始初始化MPMC的时候,设置MPMCStaticConfig寄存器的时候,设置成了X1616位),但是,后来去uboot中找到别人的Nor Flash的驱动(参考的是boardoxcflash.c),发出的命令去读ID,也都是X88位)的:

    addr[0x0AAA] = 0xAA;

    addr[0x0555] = 0x55;

    addr[0x0AAA] = 0x90;

所以,导致读取Manufacture ID Device ID,都无法读正确,读的都是0xFF。后来重新去确认,在配置MPMCStaticConfig的时候,是配置的X16模式,然后再发命令,也对应的是按照X16模式发命令,可以参考:boardmvs1flash.c中的代码,读取ID时是:

       addr[0x0555] = 0x00AA;

       addr[0x02AA]= 0x0055;

       addr[0x0555] = 0x0090;

才能正确读取到期望出的ID

       value = addr[0];                   /* manufacturer ID */

读出来的是0x20h

       value = addr[1];                   /* device ID           */

读出来的是0x22CB

datasheet中的匹配:

Manufacturer Code: 0020h

Bottom Device Code M29W320DB: 22CBh

2.       不同位宽对应不同的时序

此处说的时序,也就是上面提到的,X8X16发的地址,是不一样的,而且顺序也不同。

而且还有一小点要注意的是,记得转换地址成对应的类型:

X8vu_char *

X16 vu_short *

这样再写入对应的地址和数值,就可以了。

3.       reset命令

看了uboot中的代码,好像是其他设备,多数的reset命令,都是0xFF

而这里用到的是STM(STMicroelectronics,后来好像改成IntelST合资的恒忆(Numonyx)了。。。) Nor FlashM29W320DB (32 M, bottom boot sect)      ,比较特殊些,是0xF0

4.       boot sector的位置

刚刚看了下datasheet,很汗的是,本以为bottom sect是底部的sect,是地址最大的那个,结果datasheet中的是倒叙计算开始处的,也就是地址最大的那个块,是第一个块,所以,此处的boot sector 是块0-3

#   Size (KByte/KWord) Address Range(x8)/ Address Range (x16)

66 64/32 3F0000h-3FFFFFh   1F8000h-1FFFFFh

。。。。。

。。。。。

3 32/16 008000h-00FFFFh   004000h-007FFFh

2 8/4   006000h-007FFFh   003000h-003FFFh

1 8/4   004000h-005FFFh   002000h-002FFFh

0 16/8 000000h-003FFFh   000000h-001FFFh

5.block的起始地址
之所以会说这个问题,是因为在调试flash代码的时候,
发现虽然前面的erase bank 1都成功了,应该也就是整个flash都擦除了。
但是,实际写入的值,却是每次都到0x6000位置就出错了,说是没有erase。
觉得很是奇怪,最后,我重新去做
erase bank 1
然后debug时候,手动把要擦除的块地址设置成0x6000,结果发现可以把
0x6000到0x7FFF位置都擦除了。
由于我此处是设置成X16模式,16位的,所以,初始化的时候设置的block首址的时候,都是按照X16模式设置的。
但是现在发现,好像这个block的首地址,实际还是应该按照X8格式的地址,而不是datasheet中写的X16模式的地址。
这样,在擦除的时候,才能够找到对应块的首地址,才能正确擦除。。。

所以,就要在开始的时候,即 flash_get_size中的flash_get_offsets,去初始化每个block的起始地址的时候,
就要按照datasheet中X8模式的地址:
…….
3 32/16 008000h-00FFFFh
2 8/4 006000h-007FFFh
1 8/4 004000h-005FFFh
0 16/8 000000h-003FFFh

而不是按照X16模式的地址:
….
3 32/16 004000h-007FFFh
2 8/4 003000h-003FFFh
1 8/4 002000h-002FFFh
0 16/8 000000h-001FFFh

最后,想要说的是,还是不能完全确定到底是我之前初始化或者哪里操作错了,
所以要在16位模式的时候,还是发8位地址才能擦除对应的块,还是本身datasheet没有说明白。。。

转载请注明:在路上 » 编写uboot下Nor Flash驱动的注意事项

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (1)

  1. 所以要在16位模式的时候,还是发8位地址才能擦除对应的块,还是本身datasheet没有说明白。
    prettybxp13年前 (2011-02-05)回复
82 queries in 0.177 seconds, using 22.15MB memory