摘要:本文主要向大家介绍了Flash基础入门的Nor Flash工作原理,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。
本文主要向大家介绍了Flash基础入门的Nor Flash工作原理,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。
Nor Flash 具有像内存一样的接口,它可以像内存一样读,却不可以像内存一样写,Nor Flash 的写、擦除都需要发出特定的命令。谈到 Nor Flash 通常就会涉及到 CFI ([Common Flash Interface) 接口,一般 Nor Flash 都支持发命令来读取厂家 ID 和 设备 ID 等基本信息,但并不是所有的 Nor Flash 都支持发命令来获取和芯片本身容量大小、扇区数、擦除块大小等信息。为了让将来的 Nor Flash 兼容性更好,引进了 CFI 接口,将芯片有关的信息都写入芯片内部,通过 CFI 命令就可以获取这些信息。
Linux 内核中对各种型号的 Nor Flash 都有很好的支持 ,但是其组织复杂,不利于分析。这里选用 u-boot 里面的 Nor Flash 代码来分析。代码位于:u-boot-2010.06/board/samsung/smdk2410/flash.c 。
通常内核里面要识别一个 Nor Flash 有两种方法:一种是 jedec 探测,就是在内核里面事先定义一个数组,该数组里面放有不同厂家各个芯片的一些参数,探测的时候将 flash 的 ID 和数组里面的 ID 一一比较,如果发现相同的,就使用该数组的参数。另一种是 cfi 探测,就是直接发各种命令来读取芯片的信息,比如 ID、容量等。jedec 探测的优点就是简单,缺点是如果内核要支持的 flash 种类很多,这个数组就会很庞大。../samsung/smdk2410/flash.c 文件采用的是第一种方法,但是还是有些区别的,内核里面用 jedec 探测一个芯片时,是先通过发命令来获取 flash 的 ID,然后和数组比较,但是 flash.c 中连 ID 都是自己通过宏配置的。
unsigned long flash_init (void) { for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { ulong flashbase = 0; //设置 flash_id ,这个标志保存厂家 ID 和 设备 ID flash_info[i].flash_id = #if defined(CONFIG_AMD_LV400) (AMD_MANUFACT & FLASH_VENDMASK) | (AMD_ID_LV400B & FLASH_TYPEMASK); #elif defined(CONFIG_AMD_LV800) (AMD_MANUFACT & FLASH_VENDMASK) | (AMD_ID_LV800B & FLASH_TYPEMASK); #else #error "Unknown flash configured" #endif //设置 flash 大小和扇区数 flash_info[i].size = FLASH_BANK_SIZE; flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT; //对于 flash 的每个扇区,都需要保存扇区的首地址 for (j = 0; j < flash_info[i].sector_count; j++) { ...... flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE; } size += flash_info[i].size; //片外所有flash 的总大小 } //对代码区的扇区设置写保护,这里只是软件的一种设定 flash_protect (FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]); //如果环境变量保存在 nor 里面,还需对这些扇区设置写保护 flash_protect (FLAG_PROTECT_SET, CONFIG_ENV_ADDR, CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]); return size; //返回 flash 大小 }
flash_init() 函数主要是做一些 flash 的初始化,比如设置 flash 的 ID、大小、扇区数等来构造 flash_info_t 结构体,但是从上面的代码可以看出,在该初始化函数中并没有做任何与硬件有关的初始化,所有的值都是通过外部赋值,也就是说我们可以给这些成员变量赋任何我们想要的值,哪怕这些值并不是 flash 真正的参数,虽然这些值并不影响本函数的调用,但是和下面这些函数就有密切关系。
int flash_erase (flash_info_t * info, int s_first, int s_last) { //参看是否有写保护扇区,有直接返回错误 prot = 0; for (sect = s_first; sect <= s_last; ++sect) { if (info->protect[sect]) prot++; } if (prot) return ERR_PROTECTED; //关闭中断等,防止擦除过程被中断 cflag = icache_status (); icache_disable (); iflag = disable_interrupts (); /* Start erase on unprotected sectors */ for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { printf ("Erasing sector %2d ... ", sect); /* arm simple, non interrupt dependent timer */ reset_timer_masked (); if (info->protect[sect] == 0) //此处的判断有点多余 { /* not protected */ //取扇区的首地址 vu_short *addr = (vu_short *) (info->start[sect]); //发解锁和擦除扇区命令 MEM_FLASH_ADDR1 = CMD_UNLOCK1; //往地址 0x555<<1 写入 0xAA MEM_FLASH_ADDR2 = CMD_UNLOCK2; //往地址 0x2AA<<1 写入 0x55 MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;//往地址 0x555<<1 写入 0x80 MEM_FLASH_ADDR1 = CMD_UNLOCK1; MEM_FLASH_ADDR2 = CMD_UNLOCK2; *addr = CMD_ERASE_CONFIRM; //往地址 0x555<<1 写入 0x30 /* wait until flash is ready */ chip = 0; do { result = *addr; //读取该扇区首地址里面的值 /* check timeout */ if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) { MEM_FLASH_ADDR1 = CMD_READ_ARRAY; chip = TMO; break; } //BIT_ERASE_DONE = 0x80,即判断 DQ7 是否为 1 if (!chip && (result & 0xFFFF) & BIT_ERASE_DONE) chip = READY; //BIT_PROGRAM_ERROR = 0x20,即判断 DQ5 是否为 1 if (!chip && (result & 0xFFFF) & BIT_PROGRAM_ERROR) chip = ERR; } while (!chip); MEM_FLASH_ADDR1 = CMD_READ_ARRAY; //往地址 0x555<<1 写入 0xF0 ...... printf ("ok.\n"); } else { /* it was protected */ printf ("protected!\n"); } } ...... /* allow flash to settle - wait 10 ms */ udelay_masked (10000); return rc; }
对于擦除工作,不可能瞬间完成,如何检测芯片是否已经完成擦除工作是我们所关心的,当然你可以用一个很长的延时来确保芯片肯定已经完成擦除,但是一款芯片一定会提供相应的状态供我们检测,利用这些状态位可以减少程序中不必要的等待。下面这些描述是摘自芯片手册。
以上就介绍了Flash的相关知识,希望对Flash有兴趣的朋友有所帮助。了解更多内容,请关注职坐标常用软件Flash频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号