小标
2018-06-11
来源 :
阅读 2432
评论 0
摘要:本文主要向大家介绍了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频道!
喜欢 | 0
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号