|
EE_BeagleBone_Cape之NAND
[复制链接]
作者:chenzhufly QQ:36886052 ( 转载请注明出处)
1. 概述
这篇文档是关于EE_BeagleBone_Cape nand部分设计的一些心得和体会,和大家分型一下。欢迎大伙拍砖
2. NAND设计点滴
还是把原理图图贴上来吧,呵呵
1) 关于管脚电压,主要是34,39脚。这里做了一点兼容性设计,MT29F2G08这两个引脚需要接3.3V,而我使用的K9LBG08U0M和K9F2G08是不需要接的。
2) 由于需要通过FPGA连接,FPGA的代码是必不可少的。
3) 关于NAND和NOR的区别网络上很多,可以看看以下链接:
http://www.91tech.net/Article/SoftHardTech/EmbeddedSystem/200608/4147.html
或者看看这张图吧,我觉得还是比较清楚的。
4) 在选择NAND的容量的时候,还需要先了解下uboot和linux的支持情况,要不让是比较苦逼的。比如U-boot 2011.09是不支持K9LBG08U0M这样4GB的Nand的flash的,让我走了一些弯路,后面有介绍。
5) 能够识别了也不是就完事了,分区的格式化也是个问题,我在使用3.1内核的时候,搞死都不行;换成3.2内核就一切ok啦。非常的诡异,具体啥情况我还没细细研究,有兴趣的可以研究下哦:)
3. FPGA代码
1) 首先呢,是做好管脚分配,主要是把BeagleBone的控制引脚和NAND的引脚一一对应上.关于管脚分配前面已经写过了,就不重复啦
// for NAND
-
assign gpmc_we = TIMER6 ;
-
assign gpmc_adv_ale = TIMER4
- ;
-
assign gpmc_be0n_cle = TIMER5
- ;
-
assign gpmc_cs0 = GPIO1_29 ;
-
assign gpmc_oen_ren = TIMER7
- ;
-
assign UART4_RXD = gpmc_wait0 ;
-
-
assign gpmc_ad = ((GPIO1_29== 1'b0)
- && (TIMER6 == 1'b0)) ?
- {GPIO1_7,GPIO1_6,GPIO1_5,GPIO1_4,GPIO1_3,GPIO1_2,GPIO1_1,GPIO1_0} : 16'bz;
-
- assign
- {GPIO1_7,GPIO1_6,GPIO1_5,GPIO1_4,GPIO1_3,GPIO1_2,GPIO1_1,GPIO1_0} = ((GPIO1_29==
- 1'b0) && (TIMER7 == 1'b0)) ? gpmc_ad : 16'bz;
复制代码 4. U-Boot中的NAND支持
1) 首先看看drivers/mtd/nand/目录下的Nand_ids.c文件吧,这个文件列出了U-Boot支持的NAND列表,在U-boot 2011.09中,没有找到支持4GB的NAND类型,悲剧!怪不得U-Boot启动的时候没打印信息,我还以为是焊接问题,焊了又焊,深刻的教训! /* 8 Gigabit */ {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS}, {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS}, {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16}, {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16},
/* 16 Gigabit */ {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS}, {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS}, {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16}, {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16}, 下面没有了,呵呵 复制代码2) 在来看看include/configs下的Am335x_evm.h文件吧
第46行,说明已经支持NAND了,要不然也不会有打印呵呵#define CONFIG_MMC #define CONFIG_NAND #define CONFIG_SPI
复制代码 再看看第210行,这是和NAND配置相关的一些代码,还有SPL相关的配置/* NAND boot config */ #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_NAND_SUPPORT #define CONFIG_SYS_NAND_5_ADDR_CYCLE #define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ CONFIG_SYS_NAND_PAGE_SIZE) #define CONFIG_SYS_NAND_PAGE_SIZE 2048 #define CONFIG_SYS_NAND_OOBSIZE 64 #define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) #define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS #define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ 10, 11, 12, 13, 14, 15, 16, 17, \ 18, 19, 20, 21, 22, 23, 24, 25, \ 26, 27, 28, 29, 30, 31, 32, 33, \ 34, 35, 36, 37, 38, 39, 40, 41, \ 42, 43, 44, 45, 46, 47, 48, 49, \ 50, 51, 52, 53, 54, 55, 56, 57, }
#define CONFIG_SYS_NAND_ECCSIZE 512 #define CONFIG_SYS_NAND_ECCBYTES 14
#define CONFIG_SYS_NAND_ECCSTEPS 4 #define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \ CONFIG_SYS_NAND_ECCSTEPS)
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 复制代码第19行,说明可以在nand中存放环境变量#define CONFIG_SYS_NO_FLASH #define CONFIG_NAND_ENV
复制代码 3) 看看我换成K9F2G08的打印信息吧U-Boot 2011.09 (Nov 04 2011 - 21:39:19)
I2C: ready DRAM: 256 MiB WARNING: Caches not enabled No daughter card present NAND: HW ECC Hamming Code selected 256 MiB MMC: OMAP SD/MMC: 0 *** Warning - bad CRC, using default environment 复制代码5. Linux中的NAND支持
1) 同样的,我们先看看drivers/mtd/nand/目录下的Nand_ids.c文件,有心的人可以看出U-Boot的目录结构和文件和linux的一样的。但是支持的NAND的类型就大很多了哦,最大可以到64GB。 /* 16 Gigabit */ {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS}, {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS}, {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16}, {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16}, ........ ........ /* 512 Gigabit */ {"NAND 64GiB 1,8V 8-bit", 0x1E, 0, 65536, 0, LP_OPTIONS}, {"NAND 64GiB 3,3V 8-bit", 0x3E, 0, 65536, 0, LP_OPTIONS}, {"NAND 64GiB 1,8V 16-bit", 0x2E, 0, 65536, 0, LP_OPTIONS16}, {"NAND 64GiB 3,3V 16-bit", 0x4E, 0, 65536, 0, LP_OPTIONS16},
复制代码 看看\arch\arm\mach-omap2\Board-am335xevm.c中关于NAND支持吧
如果要让Beaglebone支持nand,需要在beaglebone_dev_cfg中增加nand的初始化函数,我是这样做的/* Beaglebone Rev A3 and after */ static struct evm_dev_cfg beaglebone_dev_cfg[] = { {mii1_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {usb0_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {usb1_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {mmc0_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {evm_nand_init, DEV_ON_BASEBOARD, PROFILE_NONE}, {NULL, 0, 0}, };
复制代码 看看NAND初始化部分都干了些啥子,主要设计nand_pin_mux和am335x_nand_partition这两个static void evm_nand_init(int evm_id, int profile) { setup_pin_mux(nand_pin_mux); board_nand_init(am335x_nand_partitions, ARRAY_SIZE(am335x_nand_partitions), 0, 0); }
复制代码 下面这个就是管脚的定义了/* Pin mux for nand flash module */ static struct pinmux_config nand_pin_mux[] = { {"gpmc_ad0.gpmc_ad0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad1.gpmc_ad1", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad2.gpmc_ad2", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad3.gpmc_ad3", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad4.gpmc_ad4", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad5.gpmc_ad5", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad6.gpmc_ad6", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_ad7.gpmc_ad7", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_wait0.gpmc_wait0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_wpn.gpmc_wpn", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP}, {"gpmc_csn0.gpmc_csn0", OMAP_MUX_MODE0 | AM33XX_PULL_DISA}, {"gpmc_advn_ale.gpmc_advn_ale", OMAP_MUX_MODE0 | AM33XX_PULL_DISA}, {"gpmc_oen_ren.gpmc_oen_ren", OMAP_MUX_MODE0 | AM33XX_PULL_DISA}, {"gpmc_wen.gpmc_wen", OMAP_MUX_MODE0 | AM33XX_PULL_DISA}, {"gpmc_ben0_cle.gpmc_ben0_cle", OMAP_MUX_MODE0 | AM33XX_PULL_DISA}, {NULL, 0}, };
复制代码 这是NAND的分区,可以看到和系统启动的时候打印是一致的/* NAND partition information */ static struct mtd_partition am335x_nand_partitions[] = { /* All the partition sizes are listed in terms of NAND block size */ { .name = "SPL", .offset = 0, /* Offset = 0x0 */ .size = SZ_128K, }, { .name = "SPL.backup1", .offset = MTDPART_OFS_APPEND, /* Offset = 0x20000 */ .size = SZ_128K, }, { .name = "SPL.backup2", .offset = MTDPART_OFS_APPEND, /* Offset = 0x40000 */ .size = SZ_128K, }, { .name = "SPL.backup3", .offset = MTDPART_OFS_APPEND, /* Offset = 0x60000 */ .size = SZ_128K, }, { .name = "U-Boot", .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ .size = 15 * SZ_128K, }, { .name = "U-Boot Env", .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ .size = 1 * SZ_128K, }, { .name = "Kernel", .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ .size = 40 * SZ_128K, }, { .name = "File System", .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */ .size = MTDPART_SIZ_FULL, }, };
复制代码 2) 这也为什么我的4GB NAND也是可以被linux检测到的原因
看看4GB的系统的打印信息吧
再看看256MB的系统的打印信息吧[ 0.885371] omap_hsmmc.0: alias fck already exists [ 0.894289] mtdoops: mtd device (mtddev=name/number) must be supplied [ 0.901336] omap2-nand driver initializing [ 0.906150] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit) [ 0.915251] Creating 8 MTD partitions on "omap2-nand.0": [ 0.920854] 0x000000000000-0x000000020000 : "SPL" [ 0.927785] 0x000000020000-0x000000040000 : "SPL.backup1" [ 0.935221] 0x000000040000-0x000000060000 : "SPL.backup2" [ 0.942519] 0x000000060000-0x000000080000 : "SPL.backup3" [ 0.950013] 0x000000080000-0x000000260000 : "U-Boot" [ 0.957714] 0x000000260000-0x000000280000 : "U-Boot Env" [ 0.965087] 0x000000280000-0x000000780000 : "Kernel" [ 0.974097] 0x000000780000-0x000010000000 : "File System"
复制代码 6. NAND Flash相关操作
U-Boot下的相关命令:具体的就不解释了,有兴趣的可以从网上查看U-Boot# nand nand - NAND sub-system
Usage: nand info - show available NAND devices nand device [dev] - show or set current device nand read - addr off|partition size nand write - addr off|partition size read/write 'size' bytes starting at offset 'off' to/from memory address 'addr', skipping bad blocks. nand erase[.spread] [clean] off size - erase 'size' bytes from offset 'off' With '.spread', erase enough for given file size, otherwise, 'size' includes skipped bad blocks. nand erase.part [clean] partition - erase entire mtd partition' nand erase.chip [clean] - erase entire chip' nand bad - show bad blocks nand dump[.oob] off - dump page nand scrub off size | scrub.part partition | scrub.chip really clean NAND erasing bad blocks (UNSAFE) nand markbad off [...] - mark bad block(s) at offset (UNSAFE) nand biterr off - make a bit error at offset (UNSAFE) 复制代码查看一下信息吧U-Boot# nand info Device 0: nand0, sector size 128 KiB U-Boot# nand device Device 0: nand0, sector size 128 KiB
复制代码 Linux下的相关操作
看看有几个分区root@am335x-evm:~# cat /proc/mtd dev: size erasesize name mtd0: 00020000 00020000 "SPL" mtd1: 00020000 00020000 "SPL.backup1" mtd2: 00020000 00020000 "SPL.backup2" mtd3: 00020000 00020000 "SPL.backup3" mtd4: 001e0000 00020000 "U-Boot" mtd5: 00020000 00020000 "U-Boot Env" mtd6: 00500000 00020000 "Kernel" mtd7: 0f880000 00020000 "File System"
复制代码root@am335x-evm:~# cat /proc/partitions major minor #blocks name
31 0 128 mtdblock0 31 1 128 mtdblock1 31 2 128 mtdblock2 31 3 128 mtdblock3 31 4 1920 mtdblock4 31 5 128 mtdblock5 31 6 5120 mtdblock6 31 7 254464 mtdblock7 179 0 3813376 mmcblk0 179 1 72261 mmcblk0p1 179 2 923737 mmcblk0p2 179 3 2795310 mmcblk0p3 复制代码使用flash_eraseall是有些问题,暂时问题不明,如果哪位大侠知道,麻烦告诉我一下,谢谢!root@am335x-evm:~# flash_eraseall -j /dev/mtd7 flash_eraseall has been replaced by `flash_erase 0 0`; please use it flash_erase: error!: /dev/mtd7: unable to get NAND oobinfo error 22 (Invalid argument)
复制代码 使用mkfs就没有问题root@am335x-evm:~# mkfs -t ext2 /dev/mtd7 mke2fs 1.41.14 (22-Dec-2010) /dev/mtd7 is not a block special device. Proceed anyway? (y,n) root@am335x-evm:~# mkfs -t ext2 /dev/mtdblock7 mke2fs 1.41.14 (22-Dec-2010) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 63744 inodes, 254464 blocks 12723 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67371008 32 block groups 8192 blocks per group, 8192 fragments per group 1992 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185
Writing inode tables: done Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 32 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. 复制代码挂载到/mnt/nand,创建一个hello_eeworld目录,然后重启root@am335x-evm:~# cd /mnt root@am335x-evm:/mnt# ls card cf nand net ram root@am335x-evm:/mnt# ls nand root@am335x-evm:/mnt# mount /dev/mtdblock7 nand/ root@am335x-evm:/mnt# ls nand/ lost+found root@am335x-evm:/mnt# mkdir nand/hello_eeworld root@am335x-evm:/mnt# ls nand/ hello_eeworld lost+found root@am335x-evm:/mnt# reboot
复制代码 重启后,hello_eeworld还在,说明是能够操作成功的。am335x-evm login: root root@am335x-evm:~# mount /dev/mtdblock7 /mnt/nand root@am335x-evm:~# ls /mnt/nand hello_eeworld lost+found root@am335x-evm:~#
复制代码 7. PDF下载
EE_BeagleBone_Cape之Nand.pdf
(783.48 KB, 下载次数: 177)
[ 本帖最后由 chenzhufly 于 2012-10-27 13:29 编辑 ]
|
|