加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

添加Redboot的NAND Flash驱动

发布时间:2020-12-15 17:42:40 所属栏目:百科 来源:网络整理
导读:现在我的Redboot已经实现了从NAND启动,并加载了cs8900网卡的驱动,但是仍然无法对NAND Flash进行操作,如fconfig命令、fis命令还是无法完成的。于是,需要给Redboot加载NAND Flash的驱动。 eCos的源代码中并没有提供对NAND器件的支持,只是提供了一个flash
现在我的Redboot已经实现了从NAND启动,并加载了cs8900网卡的驱动,但是仍然无法对NAND Flash进行操作,如fconfig命令、fis命令还是无法完成的。于是,需要给Redboot加载NAND Flash的驱动。
eCos的源代码中并没有提供对NAND器件的支持,只是提供了一个flash抽象设备的接口,如fis和fconfig命令都是针对于flash抽象设备接口实现的。flash抽象设备接口驱动是置于io设备驱动下的。而具体的flash器件的驱动则放在devs目录下,在flash器件驱动中大多是实用于NOR Flash器件,只有Toshiba的TC58xxx是NAND Flash器件。而Flash驱动中与平台相关的部分则放在devsflash下的各平台目录下。
在网上转了一圈,想找找现成的NAND Flash驱动,发现了有一些对NAND驱动结构的意见。其主要有两种意见,一种是按照linux的结构来实现;一种则直接采用flash抽象设备接口的结构,而只是实现NAND器件的驱动。按照linux结构实现较为复杂,但是能够做到与linux兼容,对于用Redboot引导linux的系统来说比较合适。按后一种方式则实现较为简单,对eCos的目录结构的调整也不大,如Toshiba的TC58xxx那样,则对于fis、fconfig命令而言是透明的,无需修改。由于是初学,也没有必要做得太复杂,至于与linux的兼容性也就先丢到一边吧,呵呵。况且,在网上还找到Alexey Shusharin写的NAND Flash的patch( url:http://www.nabble.com/NAND-Flash-device-driver-td14252516.html),据他称已经在SAMSUNG的K9F5608U0D上测试通过。而我的开发板上的NAND Flash是SAMSUNG的K9F1208U0B,应该正好可以拿来用,呵呵。
Alexey的驱动主要由两个部分组成,一个是NAND器件的驱动,位于devsflashnand目录下,包括nand_flash.c,nand_flash_parts.inl,nand_flash.h文件,在nand_flash.cdl中实现了NAND Flash驱动的配置脚本文件,定义了CYGPKG_DEVS_FLASH_NAND包,以及相关的一些配置选项。另外一部分是与平台相关的,放在了devsflasharmleo2410目录下了,包括flash_nand_leo2410.cdl和devs_flash_arm_leo2410.inl两个文件。
在nand_flash.c文件中实现了flash.c函数中所有相关的接口函数,如flash_query()、flash_hwr_init()、...等函数,这样fis、fconfig命令就可以通过这些函数访问到NAND Flash,当然这样的实现只能适合于只有NAND Flash的情况。nand_flash_parts.inl中定义了NAND器件的型号和参数;flash_nand_leo2410.cdl中对平台相关的包含文件devs_flash_arm_leo2410.inl做了连接,并定义了相关的宏以便能够使用NAND Flash驱动。而devs_flash_arm_leo2410.inl中则是平台对NAND控制器的实现。
在Alexey的这个patch中,实现了NAND Flash的驱动部分,平台相关部分给出了函数的空实现,以便于按照平台要求添加相应的代码。根据s3c2410的NAND控制器的访问方法,对这段代码进行了添加,如下所示:
?

#include?<cyg/hal/s3c2410x.h>?
?
define?__REGb(x)?(*volatile?unsigned?char?))
define?__REGiint?)

//-----------------------------------------------------------------
// Platform specific access to control-lines?
//-----------------------------------------------------------------
define?CYGHWR_FLASH_NAND_PLF_RESET nand_plf_reset
define?CYGHWR_FLASH_NAND_PLF_INIT nand_plf_init?
define?CYGHWR_FLASH_NAND_PLF_CE nand_plf_ce?
define?CYGHWR_FLASH_NAND_PLF_WP nand_plf_wp?
define?CYGHWR_FLASH_NAND_PLF_CMD nand_plf_cmd?
define?CYGHWR_FLASH_NAND_PLF_ADDR nand_plf_addr?
define?CYGHWR_FLASH_NAND_PLF_WAIT nand_plf_wait?
?
//----------------------------------------------------------------
// Global variables?
// The device-specific data?

static?cyg_nand_dev nand_device?=?
{?
????.flash_base?=?void(0x80000000,?
????.addr_r?)?NFDATA ????.addr_w? ?????
????.delay_cmd?=?1.delay_rst?=?500};?

// Reset platform nand?
static?inline?void?nand_plf_reset{
????int?i;
????????
????__REGi(NFCONF&~(1<<11;
????__REGi(NFCMD=?0xFF;???????????????/* reset command */????????
????for(i?=?0;?i?<?10;?i+;????????????/* tWB = 100ns. */
????while?!(__REGi(NFSTAT&?<0;?/* wait 200~500us; */
????__REGi|;
}
?
// Init platform nand?
void?nand_plf_init)?
{?
????// Init NAND Flash platform stuff?

#if?1
????define?TACLS 0
????define?TWRPH0 1
????define?TWRPH1 0
else
????define?TWRPH0 4
????define?TWRPH1 2

endif

????__REGi<15(0<14<13<12(TACLS<8(TWRPH0<4(TWRPH1;
????/* 1 1 1 1,1 xxx,r xxx,r xxx */
????/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */

????nand_plf_reset}?
// Enable/disable nand chip?
void?nand_plf_ceint?stateif(state)?
????{?
????????// Enable CE line?
????????__REGi;
????}?
????else?
????// Disable CE line?
????????__REGi}?
}?
?
// Enable/disable write protect?
void?nand_plf_wpint?nowrite(nowrite// Enable WP?
????// Disable WP?
????//-----------------------------------------------------------------

// Write nand command?
void?nand_plf_cmdint?cmd// Enable CLE line?
????// Write command?
????// Disable CLE line?
????__REGi=?cmd//-----------------------------------------------------------------

// Write nand address?
//-----------------------------------------------------------------

void?nand_plf_addrint?addr// Enable ALE line?
????// Write address?
????// Disable ALE line?
????__REGi(NFADDR)????=?addr// Wait device ready pin?
void?nand_plf_wait// Wait while device is not ready?
????}?

其中nand_plf_wp没有实现,是因为我的开发板上写保护线是直接接的高电平,故无需控制。而nand_plf_cmd和nand_plf_addr的实现没有考虑CLE和ALE的控制是由于s3c2410的控制器是由硬件直接控制的,无需由软件控制。

这样,在eCos.db的leo2410 target中加入下面几行:

CYGPKG_IO_FLASH
CYGPKG_DEVS_FLASH_NAND
CYGPKG_DEVS_FLASH_ARM_LEO2410_NAND

就可以用configureTool进行配置、编译了。下载之后启动,Redboot发现了NAND Flash器件,但是fconfig初始化错误,NAND驱动中的bbm也无法初始化。使用fconfig命令、fis命令发现完全没有作用。于是将nand_flash.c文件中的NAND_DEBUG_LEVEL设置为3,以打印出调试信息。重新编译,下载,发现打印出的调试信息都是success,这就奇怪了,为什么无法执行操作却返回成功呢?

左思右想没有结果,怎么办呢,只有借鉴成功经验了。一开始想在vivi中找,却发现vivi对NAND器件的驱动不是很清晰,看起来比较费劲。又分析了一下,发现erase、write甚至read命令都无法正常工作,因此猜想应该是底层命令的原因,第一个怀疑的就是command命令了。这时候,突然想到用来刷NAND Flash的SJF2410也有源代码,于是打开将command的实现进行了一下比较,才发现Alexey代码中少了一段page地址的设置,s3c2410的控制方法不一致,如下列代码中红色部分所示。

// Write page address if needed?
(page_addr?>{?
???CYGHWR_FLASH_NAND_PLF_ADDR&?0xFF;?
???CYGHWR_FLASH_NAND_PLF_ADDR>?8;?
???CYGHWR_FLASH_NAND_PLF_ADDR>?16;?
}

page地址没有写对,那么当然无法正常工作,但是并没有影响到NAND控制器的状态改变,所以总是返回成功了。重新编译、下载,启动,终于没有报初始化不成功的错误了,试验了一下fconfig命令,也可以正确的设置了,这样修改ip地址等变得很方便了。

+NAND FLASH Device probed: Samsung K9F1208U0B,size 64MB

... Read from 0x03ffc000-0x04000000 at 0x83f7c000:

.

... Read from 0x03ffb000-0x03ffc000 at 0x83f7f000:

.

CS8900A[0x19000300] - type: 0x630e,rev: 0x0a00

CS8900 - status: 0x0ad6 (EEPROM present)

Got hardcoded ESA

ESA 00:21:85:92:d5:0e

Ethernet eth0: MAC address 00:21:85:92:d5:0e

IP: 192.168.0.4/255.255.255.0,Gateway: 192.168.0.1

Default server: 192.168.1.21

?

RedBoot(tm) bootstrap and debug environment [NAND]

Non-certified release,version UNKNOWN - built 11:48:11,Jan 14 2009

?

Platform: LEO2410 system (ARM9)

Copyright (C) 2000,2001,2002,2003,2004 Red Hat,Inc.

Copyright (C) 2003,2004,2005,2006 eCosCentric Limited

?

RAM: 0x00000000-0x04000000,[0x0002d568-0x03ff5000] available

FLASH: 0x80000000 - 0x83f80000,4064 blocks of 0x00004000 bytes each.

RedBoot>

其中NAND器件的信号是自己在nand_flash_parts.inl的结构中添加的,并在nand_flash.c的flash_hwr_init()函数添加了以下代码而实现的打印NAND Flash器件的信息:

flash_info.pf("NAND FLASH Device probed: %s,size %dMBn" ????????????name ????????????flash_info.block_size?*?dev->blocks_count?/?0x100000;

fis命令也能工作了,用fis list命令看了一下,发现有三个image,如下:

RedBoot> fis list

... Read from 0x03ffc000-0x03fff000 at 0x83f7c000:

.

Name????????????? FLASH addr? Mem addr??? Length????? Entry point

RedBoot?????????? 0x80000000? 0x80000000? 0x00020000? 0x00000000

FIS directory???? 0x83F7C000? 0x83F7C000? 0x00003000? 0x00000000

RedBoot config 0x83F7F000? 0x83F7F000? 0x00001000? 0x00000000

这样,我的Redboot就可以使用NAND驱动了,通过配置可以直接用load命令将映像文件下载到NAND Flash中去,采用tftp速度飞快,再也不需要在SJF2410下载时经历那样漫长的等待了,呵呵!

原文见:http://blog.chinaunix.net/uid-20802172-id-458568.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
    站长推荐
    热点阅读