当前位置: 首页 > news >正文

岳阳网站开发培训网站建设公司简介

岳阳网站开发培训,网站建设公司简介,罗马柱 东莞网站建设,亲 怎么给一个网站做备份S3C2410处理器集成了8位NandFlash控制器。目前市场上常见的8位NandFlash有三星公司的k9f1208、k9f1g08、k9f2g08等。k9f1208、k9f1g08、k9f2g08的数据页大小分别为512Byte、2kByte、2kByte。它们在寻址方式上有一定差异,所以程序代码并不通用。本文以S3C2410处理器和…

S3C2410处理器集成了8位NandFlash控制器。目前市场上常见的8位NandFlash有三星公司的k9f1208、k9f1g08、k9f2g08等。k9f1208、k9f1g08、k9f2g08的数据页大小分别为512Byte、2kByte、2kByte。它们在寻址方式上有一定差异,所以程序代码并不通用。本文以S3C2410处理器和k9f1208系统为例,讲述NandFlash的读写方法。

NandFlash的数据是以bit 的方式保存在memory cell里的,一般来说,一个cell 中只能存储一个bit,这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的位宽。这些Line 组成Page, page 再组织形成一个Block。k9f1208的相关数据如下:

1block=32page;1page=528byte=512byte(Main Area)+16byte(Spare Area)。

总容量为=4096(block数量)*32(page/block)*512(byte/page)=64Mbyte

NandFlash以页为单位读写数据,而以块为单位擦除数据。按照k9f1208的组织方式可以分四类地址: Column Address、halfpage pointer、Page Address 、Block Address。A[0:25]表示数据在64M空间中的地址。

Column Address表示数据在半页中的地址,大小范围0~255,用A[0:7]表示;

halfpage pointer表示半页在整页中的位置,即在0~255空间还是在256~511空间,用A[8]表示;

Page Address表示页在块中的地址,大小范围0~31,用A[13:9]表示;

Block Address表示块在flash中的位置,大小范围0~4095,A[25:14] 表示;

把nand_flash想象成一本书,每一页纸就是一页数据(每一页书的宽就是flash的位宽,长就是flash的列地址),没几十页组成一个块,所有的块又组成一本书,就这样直观多了。

而页寄存器用来缓存一页数据。

flashdatarecoveryn001

 

 

#include <linux/tmd/nand.h>

#define __REGb(x) (*(volatile unsigned char  *)(x))
#define __REGw(x) (*(volatile unsigned short *)(x))
#define __REGi(x) (*(volatile unsigned int   *)(x))
#define NF_BASE  0x4e000000

#if defined(CONFIG_S3C2440)
#define NFCONF         __REGi(NF_BASE + 0x0)
#define NFCONT        __REGi(NF_BASE + 0x4)
#define NFCMD       __REGb(NF_BASE + 0x8)
#define NFADDR        __REGb(NF_BASE + 0xc)
#define NFDATA        __REGb(NF_BASE + 0x10)
#define NFDATA16     __REGw(NF_BASE + 0x10)
#define NFSTAT        __REGb(NF_BASE + 0x20)
#define NFSTAT_BUSY    1
#define nand_select()    (NFCONT &= ~(1 << 1))  //cs低电平选中
#define nand_deselect()    (NFCONT |=  (1 << 1))
#define nand_clear_RnB() (NFSTAT |= (1 << 2))
#endif

static inline void nand_wait(void)
{
int i;

while(!(NFSTAT & NFSTAT_BUSY))
for(i=0; i<10; i++);
}

struct boot_nand_t {
int page_size;
int block_size;
int bad_block_offset;
};

static int is_bad_block(struct boot_nand_t *nand, unsigned long i)
{
unsigned char data;
unsigned long page_num;

nand_clear_RnB();
if(nand->page_size == 512)
{
NFCMD = NAND_CMD_READOOB;
NFADDR = nand->bad_block_offset & 0xf;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
}else if(nand->page_size == 2048)
{
page_num = i >> 11;  /* addr / 2048 */
NFCMD = NAND_CMD_READ0;
NFADDR = (nand->bad_block_offset ) & 0xff;     // Check "FFh" at the column address 2048
NFADDR = (nand->bad_block_offset >> 8) & 0xff; // of the 1st and 2nd page in the block
NFADDR = (page_num ) & 0xff;                   // address of block
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD  = NAND_CMD_READSTART;
}else
{
return -1;
}
nand_wait();
data = (NFDATA & 0xff);
if(data != 0xff)
return 1;

return 0;
}

static int nand_read_page_ll(struct boot_nand_t *nand, unsigned char *buf, unsigned long addr)
{
unsigned short *ptr16 = (unsigned short *)buf;
unsigned int i, page_num;

nand_clear_RnB();

NFCMD = NAND_CMD_READ0;

if(nand->page_size == 512){
NFADDR = addr & 0xff;
NFADDR = (addr >> 9)&0xff;
NFADDR = (addr >> 17)&0xff;
NFADDR = (addr >> 25)&0xff;
}else if (nand->page_size == 2048){
page_num = addr >> 11;
NFADDR = 0;               //页内地址 ,为0时读取整页
NFADDR = 0;
NFADDR = page_num & 0Xff; //确定页地址
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD  = NAND_CMD_READSTART;
}else {
return -1;
}
nand_wait();                  //发送命令和地址后,flash ready    

#if defined(CONFIG_S3C2410)
for(i = 0; i < nand->page_size; i++){
*buf = (NFDATA & 0xff);
buf++;
}
#elif defined(CONFIG_S3C2440)    //循环读出数据
for(i = 0; i < (nand->page_size >> 1); i++){
*ptr16 = NFDATA16;
ptr16++;
}
#endif

return nand->page_size;        
}

static unsigned short nand_read_id()
{
unsigned short ret = 0;
NFCMD = NAND_CMD_READID;
NFADDR = 0;
res = NFDATA;
res = (res << 8) | NFDATA;

return res;
}

extern unsigned int dynpart_size[];

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
unsigned short nand_id;
struct boot_nand_t nand;

nand_select();
nand_clear_RnB();

for(i = 0; i < 10; i++)
;
nand_id = nand_read_id();


if(nand_id == 0xec76 || /* Samsung K91208 */
nand_id == 0xad76) { /*Hynix HY27US08121A*/
nand.page_size = 512;
nand.block_size = 16 * 1024;    
} else if(nand_id == 0xecf1 ||/* Samsung K9F1G08U0B */
nand_id == 0xecda ||/* Samsung K9F2G08U0B */
nand_id == 0xecd3 ){/* Samsung K9K8G08 */
nand.page_size = 2048;
nand.block_size = 128 * 1024;
nand.bad_block_offset = nand.page_size;        
}else{
return -1 ; //hang
}

if((start_addr & (nand.block_size - 1)) || (size & (nand.block_size - 1)))//检查块地址对齐,即地址的低17为只能为0。
return -1;

for(i = start_addr; i < (start_addr + size);){
#ifdef CONFIG_S3C2410_NAND_SKIP_BAD
if(i & (nand.block_size - 1) == 0){  //如果i时块地址对齐就执行,不是块地址对齐就不检查
if(is_bad_block(&nand, i) || is_bad_block(&nand, i+nand.page_size)){//the 1st and 2nd page in the block
i += nand.block_size;
size += nand.block_size;
continue;  //跳回去检测,下一个块是否为坏块
}
}
#endif
j = nand_read_page_ll(&nand, buf, i);
i += j;
buf += j;

}
nand_deselect();

return 0;
}

http://www.hkea.cn/news/288428/

相关文章:

  • 做收集信息的网站河源市企业网站seo价格
  • 有赞短链接生成汕头seo推广
  • 团队做网站分工搜索引擎案例分析结论
  • 企业网站的建设过程做整站优化
  • 最简单的cms网站怎么做惠州抖音seo
  • 做网站销售怎么开发客户自己做一个网站
  • wordpress发布文章空白整站优化 mail
  • vs怎么做网站的首页seo知识培训
  • 网站建设的一般步骤包括知乎关键词排名工具
  • 网页设计怎样做一个网页seo软件哪个好
  • 销售性网站建设需求seo案例
  • 企业怎样选择域名做网站电脑突然多了windows优化大师
  • 网站一元空间有哪些呀品牌策划方案范文
  • 最便宜的网站建设企点
  • 网站代码加密深圳新闻今日最新
  • 不要钱做网站软件网站seo优化效果
  • 公司做网站提供产品加盟费互联网销售怎么做
  • 视频网站开发架构百度app最新版本
  • 网站上内容列表怎么做的网站模板中心
  • 上海利恩建设集团有限公司网站国内好用的搜索引擎
  • 网站模板论坛今日重大军事新闻
  • 昆山自适应网站建设电商平台的营销方式
  • 盘龙区网站建设外包高级搜索引擎技巧
  • 什么做的网站吗58百度搜索引擎
  • wordpress 企业站开发口碑营销的概念
  • 广州免费核酸检测点东莞seo项目优化方法
  • 学风建设网站版块设计个人网站
  • 网站底部连接怎么做福州seo推广
  • 生猪价格今日猪价行情关键词优化是什么工作
  • 网站建设公司下载搜索引擎查询