历史上的今天
返回首页

历史上的今天

今天是:2025年03月05日(星期三)

正在发生

2020年03月05日 | 【ARM裸板】Nor Flash基础知识与编程示例

2020-03-05 来源:eefocus

1.NOR与NAND的区别

Flash NOR NAND

接口 RAM-Like,引脚多 引脚少,复用(地址数据共用)

容量 小(1-32M) 大(128M+)

读 简单 复杂

写 发出特定命令(慢) 发出特定命令(快)

价格 贵 较便宜

缺点 无位反转、坏块 位反转、坏块

一般存放 bootloader(关键程序) 大文件、视频

xip 可以 不可以

xip(eXecute In Place),即芯片内执行,指应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。flash内执行是指nor flash 不需要初始化,可以直接在flash内执行代码。但往往只执行部分代码,比如初始化RAM.


2.命令表

在这里插入图片描述

在这里插入图片描述

UBOOT下读写数据


2.1 读数据

md.b为读命令

mw.w为写命令

md.b 0


2.2 读ID

Nor手册

往(555H)写入AAH

往(2AAH)写入55H

往(555H)写入90H

读(0)得到厂家(Manifacture)ID:C2H

读(1)得到设备(Device)ID:22C4/2249

在这里插入图片描述

但是由于地址是错开1位的(具体原因可查看第15章),则往CPU写的地址需要addr<<1,即(地址*2)因此:


UBOOT下

往(AAAH)写入AAH

往(554H)写入55H (这两步为解锁命令)

往(AAAH)写入90H(90H为命令)

读(0H)得到厂家(Manifacture)ID:C2H

读(2H)得到设备(Device)ID:22C4/2249

退出读ID状态(即复位)

mw.w aaa aa

mw.w 554 55

mw.w aaa 90

md.w 0 1   #读0地址1次

md.w 2 1   

mw.w 0 F0


2.3 CFI模式

CFI(Common Flash Interface)


Nor手册

往(55H)写入98H(进入CFI模式)

读(27H)得到容量2^n的n

退出CFI模式(复位)

UBOOT下

往(AAH)写入98H(进入CFI模式)

读(4EH)得到容量2^n的n

往(0H)写入F0H


3.基本函数

3.1 写函数

Nor Flash 地址线21:即可访问2M内存,0x1FFFFF,其范围地址为 0~0x1FFFFF

#define NOR_FLASH_BASE 0 /* Nor Flash基地址 nor-->cs0,base_addr = 0 */


/* Nor Flash写入一个字

 * 基地址:base,偏移地址:offset,写入的值:value

 * eg: 55 98

 * 往(0 + (0x55)<<1 )写入0x98

*/

void nor_write_word(unsigned int base,unsigned int offset,unsigned short value)

{

volatile unsigned short *p = (volatile unsigned short *) (base + offset<<1);

*p = value;

}


进行封装

void nor_cmd(unsigned int offset,unsigned short cmd)

{

nor_write_word(NOR_FLASH_BASE, offset, cmd);

}


3.2 读函数

/* Nor Flash读取一个字

 * 基地址:base,偏移地址:offset

 * eg: 55 98

 * 往(0 + (0x55)<<1 )写入0x98

*/

unsigned int nor_read_word(unsigned int base,unsigned int offset)

{

volatile unsigned short *p = (volatile unsigned short *) (base + offset<<1);

return *p;

}


进行封装

unsigned int nor_dat(unsigned int offset)

{

return nor_read_word(NOR_FLASH_BASE, offset);

}


4.识别NOR

4.1 读取ID号

往(555H)写入AAH

往(2AAH)写入55H

往(555H)写入90H

读(0)得到厂家(Manifacture)ID:C2H

读(1)得到设备(Device)ID:22C4/2249

/* 1.打印 Manifacture ID、Device ID */

nor_unlock();       //解锁

nor_cmd(0x555,0x90);//读命令

manifa_id = nor_dat(0x00); //读厂家ID

device_id = nor_dat(0x01); //读设备ID

nor_reset_mode(); //复位

在这里插入图片描述

4.2 进入CFI Mode

往(55H)写98H

CFI(Common Flash Interface)

/* 1.进入CFI Mode */

nor_cmd(0x55,0x98); 

在这里插入图片描述

4.3 读取容量

读(27H)得到容量bytes

/* 2.打印容量 */

size = 1<<(nor_dat(0x27));

printf("nor size = 0x%x, %dMrn",size,size>>20);

在这里插入图片描述

4.4 读取各个扇区

4.4.1 获得region数量

regions = nor_dat(0x2C);

1

4.4.2 region详细信息

erase block region :里面含有1个或多个block,它们大小都一样,一个nor含有1个或多个region,一个region含有1个或多个block(扇区)


Erase block region information:

前2字节+1:表示该region有多少个block

后2字节*256:表示该block的大小(bytes)

在这里插入图片描述

参考CFI标准:

在这里插入图片描述

regions的基址从0x2D开始

region_info_base = 0x2D;

block_addr = 0;

for(i = 0;i < regions; i++){

/* 获取block的数量和大小 */

blocks = 1 + nor_dat(region_info_base) + (nor_dat(region_info_base+1)<<8);//低2字节,获取block数量

block_size = 256 * (nor_dat(region_info_base+2) + (nor_dat(region_info_base+3)<<8));//高2字节,获取block大小

region_info_base += 4;//region读取的基址+4


/* 打印每个block的起始地址 */

for(j = 0;j < blocks; j++){

printf("0x%08x ",block_addr);

block_addr += block_size;

if( ((++cnt) % 5) == 0){ //每打印5个换行

printf("rn");

}

}

}


4.5 退出CFI Mode

nor_cmd(0x00,0xF0);//复位

在这里插入图片描述

5.写数据

5.1 写入

需要注意一个点,写入的数据是16位的,也就是两个字节,需要一次性写入一个字节,所以在写入之前需要对数据进行整合。


while(str[i] && str[i+1]){//两个字符都不为0时

data = str[i] + (str[i+1]<<8);

nor_unlock();//解锁

nor_cmd(0x555,0xA0); //写命令

nor_cmd(addr>>1,data);


/* 等待烧写完成:读数据Q6,无变化时表示完成*/

wait_ready(addr);

i += 2;

addr += 2;

}

在这里插入图片描述

5.2 判断数据写入完成

等待烧写完成:读数据Q6,无变化时表示完成

两次读取的结果不一致,说明数据还在变化,继续等待

//等待读取或擦除完毕

void wait_ready(unsigned int addr)

{

unsigned int pre_val;//上一次的值

unsigned int cur_val;


pre_val = nor_dat(addr>>1);

cur_val = nor_dat(addr>>1);


/* 两次读取的结果不一致,说明数据还在变化,继续等待 */

while((cur_val & (1<<6) != (pre_val &(1<<6)))){//当前的Q6不等于上一次的Q6则等待

pre_val = cur_val;//更新上一次的值

val = nor_dat(addr>>1);//重新获取

}

}

在这里插入图片描述
在这里插入图片描述

6.测试

6.1 读取

在这里插入图片描述

6.2 写入

在这里插入图片描述

6.3 擦除

在这里插入图片描述

7.问题

7.1 系统异常卡死

执行多次的菜单选择,导致系统卡死

该为定时器造成的异常错误,关闭定时器,则不会卡死

 因为当测试nor进入CFI模式时,如果发生了中断,CPU必定读NOR,那么读不到正确的指令,导致程序异常崩溃

7.2 nor数据错误

读取设备ID时,读到的是0x002f,0xea00,改为反汇编中text的[0]上的数据


 编译程序加上选项:指定ARM版本指令集-march=armv4 或者指定芯片类型 -mcpu=arm9tdmi

否则像如下的写入操作会被分成两个strb步骤(我们需要的是strh,一次性写入两个字节),最后导致读取设备ID和厂家ID的时候出错。


     volatile unsigned short *p =value;    

    *p = value;


没加编译指定选项(分两次存2个字节)

在这里插入图片描述

加了编译指定芯片类型 -mcpu=arm9tdmi(一次性存2个字节)

在这里插入图片描述

8.擦除扇区

void erase_nor_flash(void)

{

unsigned int addr;

/* 获得地址*/

printf("Enter the address of sector to erase:");

addr = get_uint();

printf("Erase...rn");


nor_unlock();

nor_cmd(0x555,0x80); //擦除扇区命令


nor_unlock(); 

nor_cmd(addr>>1,0x30); //发出扇区地址

wait_ready(addr);

}

推荐阅读

史海拾趣

HellermannTyton公司的发展小趣事

进入21世纪后,Heimann Optoelectronics Gmbh意识到全球化合作的重要性。公司积极寻求与国际知名企业的合作机会,与美国一家领先的半导体制造商共同研发了新一代的光电集成芯片。这一合作不仅提升了产品的技术水平和市场竞争力,还借助合作伙伴的全球销售网络,将Heimann的产品迅速推向国际市场。同时,公司也在亚洲设立了研发中心和生产基地,进一步提升了生产效率和供应链管理能力。

Actel公司的发展小趣事

在20世纪90年代初,Heimann Optoelectronics Gmbh作为一家初创企业,在光电传感器领域崭露头角。公司创始人汉斯·海曼(Hans Heimann,虚构人物)敏锐地洞察到市场对高精度、低功耗光电传感器的迫切需求。他带领团队历经数年研发,成功推出了首款基于先进光电转换技术的红外传感器,该产品在工业自动化、医疗设备等领域迅速获得认可,为公司赢得了第一批重要客户,奠定了市场地位。

ELM [ELM Electronics]公司的发展小趣事

在追求经济效益的同时,ELM也注重环保和可持续发展。公司积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。同时,ELM还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅体现了ELM的社会责任感,也为公司的长期发展奠定了坚实的基础。

DIOO公司的发展小趣事

面对数字化时代的挑战和机遇,DIOO公司决定加快数字化转型步伐。通过引入云计算、大数据、人工智能等先进技术,DIOO公司实现了产品设计、生产、销售等各个环节的数字化管理。同时,DIOO公司还积极探索新的商业模式和市场机会,与互联网企业、电信运营商等合作伙伴共同打造智能生态圈。未来,DIOO公司将继续秉承创新、卓越、服务的理念,致力于成为全球领先的电子产品制造商和服务提供商。

Dialog Semiconductor(戴乐格半导体)公司的发展小趣事

随着物联网市场的快速发展,Dialog Semiconductor积极布局物联网领域。公司推出了一系列物联网相关的产品和解决方案,包括蓝牙和Wi-Fi芯片、传感器等。这些产品和解决方案能够满足物联网设备对低功耗、高可靠性通信的需求,为物联网市场的发展提供了有力支持。Dialog Semiconductor的前瞻性布局使其在物联网市场中占据了重要位置。

ATC [American Technical Ceramics]公司的发展小趣事

在电子行业的发展历程中,技术突破一直是推动公司成长和市场扩张的关键因素。假设ATC在某一时期成功研发出了一种新型的陶瓷材料,这种材料在耐高温、抗腐蚀等方面具有显著优势,因此被广泛应用于半导体制造和电子设备领域。这一技术突破使得ATC的产品在市场上获得了极高的认可,公司也因此实现了快速的收入增长和市场占有率的提升。

问答坊 | AI 解惑

【瑞萨 CPK-RA2L1 开发板】测评 - 1:安装 BSP

本帖最后由 MianQi 于 2022-11-12 20:34 编辑 从用户的角度来说,E2 Studio 中最重要的组成部分是两个: 1、 Flexible Software Package (FSP) ,下载地址:https://github.com/renesas/fsp;这个类似于Android 的 SDK - 软件开发包,它有版 ...…

查看全部问答>

[RTT&瑞萨超低功耗MCU RA2L1开发板]测评之基于MDK+RT-Thread的开发环境搭建

本帖最后由 qinyunti 于 2022-11-12 10:27 编辑 准备 前提已经安装MDK和JLINK我这里 MDK版本 V5.37 JLINK版本 V7.82(V7.5以上)   开发板资料参考 https://www2.renesas.cn/cn/zh/products/microcontrollers-microprocess ...…

查看全部问答>

[RTT&瑞萨超低功耗MCU RA2L1开发板]测评之SPI模块介绍驱动分析与测试

SPI模块介绍 参考<<Renesas RA2L1 Group User’s Manual: Hardware>>的章节<<28. Serial Peripheral Interface (SPI) >>   特征 2通道 支持全双工和仅发送模式,支持3线制和4线制 RSPCK极性反转,相位 ...…

查看全部问答>

e络盟限时福利|《e选》-------晒单

以前有一个树莓派: 但是。。。没有HDMI的小头的线。。。 这一次,又弄了线,又弄了盒子,甚至于还有天线,也许可以好好的玩玩树莓派了。。。 感谢电子工程世界(eeworld),感谢e络盟(element14)   …

查看全部问答>

【行空板 Python编程学习主控板】开箱报告

【行空板 Python编程学习主控板】开箱报告 首先真诚感谢eeword、DFRobot给了我这次参与《DFRobot行空板Python编程学习板》评测的机会。11月7日收到快递通知,因最近一直出差在外,周五回来后拿到快递,立即开箱,首先映入眼帘的是印有行空板及lo ...…

查看全部问答>

【行空板 Python编程学习主控板】评测二、硬件系统熟悉

    一周工作终于结束,每天加班到很晚,都没有什么时间来学习行空板,赶紧趁着周末把玩一下。     所谓工欲善其事必先利其器,我玩任何开发板都有个习惯,那就是上手前先要熟悉一下该板子的硬件设计, ...…

查看全部问答>

【MPS商城钜惠体验季】开箱

        借助活动买了几款升压芯片测试下, 顺便买了官方的电感。 活动好评!   …

查看全部问答>

【行空板 Python编程学习主控板】评测三、开发板初探之连接方式介绍

        在上篇测评二中,对行空板的硬件系统进行了初步的了解,这篇文章对行空板的几种连接方式进行介绍。         行空板支持四种连接方式与开发者的电脑进行连 ...…

查看全部问答>

[RTT&瑞萨超低功耗MCU RA2L1开发板]测评之DAC模块介绍与测试

[localvideo]9fb1cabad83ad0154eb76903f1caaa2f[/localvideo]   DAC模块介绍 参考<<Renesas RA2L1 Group User’s Manual: Hardware>>的章节<<31. 12-Bit D/A Converter (DAC12)>> 特征 12位带运放,1通道 ...…

查看全部问答>

【行空板 Python编程学习主控板】评测四、开发板初探之WEB服务器介绍

本帖最后由 天意无罪 于 2022-11-13 20:29 编辑        在上篇评测三中,对行空板的4种连接方式进行了简单介绍,这篇测评文章便介绍通过USB Type-C线连接到行空板自带的WEB服务器,并查看其WEB服务功能有哪 ...…

查看全部问答>