冷烟花
哎呀哎呀哎呀我的妈~蜗牛背着那重重的壳呀,一步一步地往上爬~
 
博客园    首页    博问    闪存    新随笔        管理
posts - 63,  comments - 10,  trackbacks - 0
NOR Flash擦写和原理分析

1. NOR FLASH 的简单介绍

NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直接在FLASH片内执行(这意味着存储在NOR FLASH上的程序不需要复制到RAM就可以直接运行).这点和NAND FLASH不一样.因此,在嵌入式系统中,NOR FLASH很适合作为启动程序的存储介质.NOR FLASH的读取和RAM很类似(只要能够提供数据的地址,数据总线就能够正确的给出数据),但不可以直接进行写操作.对NOR FLASH的写操作需要遵循特定的命令序列,最终由芯片内部的控制单元完成写操作.

从支持的最小访问单元来看,NOR FLASH一般分为 8 位的和16位的(当然,也有很多NOR FLASH芯片同时支持8位模式和是16 位模式,具体的工作模式通过特定的管脚进行选择).

对8位的 NOR FLASH芯片,或是工作在8-BIT模式的芯片来说,一个地址对应一个BYTE(8-BIT)的数据.例如一块8-BIT的NOR FLASH,假设容量为4个BYTE.那芯片应该有8个数据信号D7-D0 和2个地址信号,A1-A0.地址0x0对应第0个 BYTE,地址0x1对应于1BYTE,地址0x2对应于第2个BYTE,而地址0x3则对应于第3 个BYTE.对16位的 NOR FLASH芯片,或是工作在16-BIT模式的芯片来说,一个地址对应于一个HALF-WORD(16-BIT)的数据.例如,一块16-BIT的 NOR FLASH,假设其容量为4个BYTE.那芯片应该有16 个数据信号线D15-D0 和1个地址信号A0.地址 0x0对应于芯片内部的第0个HALF-WORD,地址0x1对应于芯片内部的第1个 HALF-WORD

FLASH一般都分为很多个SECTOR,每个SECTOR包括一定数量的存储单元.对有些大容量的FLASH,还分为不同的BANK,每个BANK包括一定数目的SECTOR.FLASH的擦除操作一般都是以SECTOR,BANK或是整片FLASH为单位的.

在对FLASH进行写操作的时候,每个BIT可以通过编程由1变为0,但不可以有0修改为1.为了保证写操作的正确性,在执行写操作前,都要执行擦除操作.擦除操作会把FLASH的一个SECTOR,一个BANK或是整片FLASH的值全修改为0xFF.这样,写操作就可以正确完成了.

由于NOR FLASH没有本地坏区管理,所以一旦存储区块发生毁损,软件或驱动程序必须接手这个问题,否则可能会导致设备发生异常. 在解锁、抹除或写入NOR FLASH区块时,特殊的指令会先写入已绘测的记忆区的第一页(Page).接着快闪记忆芯片会提供可用的指令清单给实体驱动程序,而这些指令是由一般性闪存接口(CommON FLASH memory Interface, CFI)所界定的. 与用于随机存取的ROM不同,NOR FLASH也可以用在存储设备上;不过与NAND FLASH相比,NOR FLASH的写入速度一般来说会慢很多.

2. NOR Flash的烧写方式

以下内容,如无特别说明,处理器指的是 ARM 处理器,FLASH 指的都是 NOR FLASH.另外,BYTE指的是8-BIT的数据单元,HALF-WORD代表的是16-BIT的数据单元,而WORD 则代表了32-BIT的数据单元.

2.1 处理器寻址

ARM 可以说是目前最流行的32位嵌进式处理器.在这里只提一下ARM处理器的寻址,为后面做个展垫.从处理器的角度来看,系统中每个地址对应的是一个BYTE的数据单元.这和很多别的处理器都是一样的.

2.2 处理器和NOR FLASH的硬件连接

从前面的先容,我们知道从处理器的角度来看,每个地址对应的是一个 BYTE 的数据单元.而,NOR FLASH 的每个地址有可能对应的是一个BYTE的数据单元,也有可能对应的是一个HALF-WORD的数据单元.所以在硬件设计中,连接ARM处理器和 NOR FLASH时,必须根据实际情况对地址信号做特别的处理.

假如ARM处理器外部扩展的是8-BIT的NOR FLASH, 数据线和地址线的连接应该如图1所示. 从图中我们可以看到,处理器的数据信号D0-D7和 FLASH的数据信号D0-D7是逐一对应连接的,处理器的地址信号A0-An和NOR FLASH的地址信号A0-An 也是逐一对应连接的.

假如ARM处理器外部扩展的是16-BIT的NOR FLASH, 地址线必须要错位连接. 图2给了一个ARM处理器和16-BIT NOR  FLASH的连接示意图.如图2所示,ARM处理器的数据信号D0-D15和FLASH 的数据信号D0-D15是逐一对应的.而ARM处理器的地址信号和NOR FLASH 的地址信号是错位连接的,ARM的A0悬空,ARM 的A1 连接FLASH 的A0,ARM 的A2连接FLASH的A1,依次类推.需要错位连接的原因是:ARM处理器的每个地址对应的是一个BYTE 的数据单元,而 16-BIT 的 FLASH 的每个地址对应的是一个HALF-WORD(16-BIT)的数据单元.为了保持匹配,所以必须错位连接.这样,从ARM处理器发送出来的地址信号的最低位A0对16-BIT FLASH来说就被屏蔽掉了.

补充说明:

  • 一般来说,ARM处理器内部要设置相应的寄存器,告诉处理器外部扩展的FLASH的位宽(8-BIT/16-BIT/32-BIT) .这样,处理器才知道在访问的时候如何从FLASH正确的读取数据;
  • 有些ARM处理器内部可以设置地址的错位.对于支持软件选择地址错位的处理器,在连接16-BIT FLASH的时候,硬件上可以不需要把地址线错位.读者设计的时候,请参考MCU的数据手册,以手册为准,以免造成不必要的麻烦;
  • 假如处理器支持内部设置地址错位,在实际访问的时候,送出的地址实际上是在MCU内部做了错位处理,其作用是等效于硬件连接上的错位的.

上面的描述可能比较抽象,下面让我们来看2个ARM处理器访问16-BIT FLASH的例子:

例子 1:ARM处理器需要从地址0x0读取一个BYTE

  1. ARM处理器在地址线An-A0上送出信号0x0;
  2. 16-BIT FLASH在自己的地址信号An-A0上看到的地址是0x0,然后将地址0x0对应的16-BIT数据单元输出到D15-D0上;
  3. ARM处理器知道访问的是16-BIT的FLASH,从D7-D0上读取所需要的一个BYTE的数据.

例子 2:ARM处理器需要从地址0x1读取一个BYTE

  1. ARM处理器在地址线An-A0上送出信号0x1;
  2. 16-BIT FLASH在自己的地址信号An-A0上看到的地址依然是0x0, 然后将地址0x0对应的16-BIT数据单元输出到D15-D0上;
  3. ARM处理器知道访问的是16-BIT的FLASH,从D15-D8 上读取所需要的一个BYTE 的数据.

2.3 从软件角度来看 ARM 处理器和 NOR FLASH 的连接

从软件的角度来理解ARM处理器和 FLASH的连接.对于8-BIT的FLASH的连接,很好理解,由于ARM处理器和8-BIT FLASH的每个地址对应的都是一个 BYTE 的数据单元.所以地址连接毫无疑问是逐一对应的.假如 ARM 处理器连接的是 16-BIT 的处理器,由于 ARM 处理器的每个地址对应的是一个 BYTE 的数据单元,而 16-BIT FLASH 的每个地址对应的是一个 HALF-WORD 的16-BIT的数据单元.所以,也毫无疑问,ARM处理器访问16-BIT处理器的时候,地址肯定是要错开一位的.在写FLASH驱动的时候,我们不需要知道地址错位是由硬件实现的,还是是通过设置ARM处理器内部的寄存器来实现的,只需要记住2点:

  1. ARM处理器访问8-BIT FLASH的时候,地址是逐一对应的;
  2. ARM处理器访问16-BIT FLASH的时候,地址肯定是错位的.

2.4 8-BIT FLASH 烧写驱动实例 - HY29F040

HY29F040是现代公司的一款8-BIT的NOR FLASH.在这个小节里,我们以这个芯片为例子,讲述如何对8-BIT NOR FLASH进行操作.

HY29F040的容量为512K-BYTE,总共包括8 个SECTOR,每个SECTOR 的容量是64K-BYTE.该芯片支持SECTOR擦除,整片擦除和以BYTE 为基本单位的写操纵.HY29F040的命令定义如表-1所示.

下面,我们来看看如何实现基本的擦除和编程操作.在本节后面的描述中,我们使用了下面的2 个定义:

U32 sysbase;          //该变量用来表示 FLASH 的起始地址
#define SysAddr8(sysbase, offset)    ((volatile U8*)(sysbase)+(offset))   //用来方便对指定的 FALSH 地址进行操作

宏SysAddr8定义了一个 BYTE(8-BIT)指针,其地址为(sysbase + offset).假设FLASH的起始地址为0x10000000,假如要将0xAB写到FLASH的第一个BYTE中往,可以用下面的代码:

*SysAddr8(0x10000000, 0x1) = 0xAB;

注意:

在本节后面的描述中,sysbase代表的是FLASH的起始地址,而SysAddr8中的offset则代表了相对于FLASH起始地址的BYTE偏移量.offset也是8-BIT FLASH在自己的地址信号An-A0上看到的地址.

a. 整片擦除操作

整片擦除操纵共需要6个周期的总线写操作:

  1. 将 0xAA写到 FLASH 地址 0x5555;
  2. 将 0x55 写到 FLASH 地址 0x2AAA;
  3. 将 0x80 写到 FLASH 地址 0x5555;
  4. 将 0xAA写到 FLASH 地址 0x5555;
  5. 将 0x55 写到 FLASH 地址 0x2AAA;
  6. 将 0x10 写到 FLASH 地址 0x5555.

对应的代码:

*SysAddr8(sysbase, 0x5555) = 0xAA;    //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55;    //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0x80;    //将值 0x80 写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x5555) = 0xAA;    //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55;    //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0x10;    //将值 0x10 写到 FLASH 地址 0x5555

b. SECTOR擦除操作

SECTOR的擦除操纵共需要6个周期的总线写操作:

  1. 将 0xAA写到 FLASH 地址 0x5555;
  2. 将 0x55 写到 FLASH 地址 0x2AAA;
  3. 将 0x80 写到 FLASH 地址 0x5555;
  4. 将 0xAA写到 FLASH 地址 0x5555;
  5. 将 0x55 写到 FLASH 地址 0x2AAA;
  6. 将 0x30 写到要擦除的 SECTOR 对应的地址.

对应的代码:

*SysAddr8(sysbase, 0x5555) = 0xAA;    //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55;    //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0x80;    //将值 0x80 写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x5555) = 0xAA;    //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55;    //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, addr) = 0x30;     //将值 0x30 写到要擦除的 SECTOR 对应的地址

c. BYTE擦除操作

写一个BYTE 的数据到FLASH中往,需要 4个周期的总线写操作:

  1. 将 0xAA写到 FLASH 地址 0x5555;
  2. 将 0x55 写到 FLASH 地址 0x2AAA;
  3. 将 0xA0 写到 FLASH 地址 0x5555;
  4. 将编程数据(BYTE)写到对应的编程地址上.

对应的代码:

*SysAddr8(sysbase, 0x5555) = 0xAA;    //将值 0xAA写到 FLASH 地址 0x5555
*SysAddr8(sysbase, 0x2AAA) = 0x55;    //将值 0x55 写到 FLASH 地址 0x2AAA
*SysAddr8(sysbase, 0x5555) = 0xA0;    //将值 0xA0 写到 FLASH 地址 0x5555
*SysAddr8(sysbase, addr) = data;      //将一个 BYTE的数据写到期看的地址

2.5 16-BIT FLASH 烧写驱动实例 - SST39VF160

SST39VF160是SST公司的一款16-BIT的NOR FLASH. 在这个小节里, 我们以SST39VF160为例子, 讲述如何对16-BIT NOR FLASH进行操作.对8-BIT FLASH的操作很好理解,但对16-BIT FLASH的操作理解起来要晦涩很多.我尽力描述得清楚些.

SST39VF160的容量为2M-BYTE , 总共包括512个SECTOR, 每个SECTOR 的容量是4K-BYTE. 该芯片支持SECTOR擦除,整片擦除和以 HALF-WORD 为基本单位的写操纵.SST39VF160 的命令定义如表-2 所示.在表 2 中,由于所有命令都是从FLASH的角度来定义的. 所以,   所有的地址都是HALF-WORD地址, 指的是16-BIT FLASH在自己的地址信号An-A0上看到的地址.

在本节后面的描述中,我们使用了下面的2个定义:

U32 sysbase;          //该变量用来表示 FLASH 的起始地址
#define SysAddr16(sysbase, offset)  ((volatile U16*)(sysbase)+(offset))  //用来方便对指定的 FALSH 地址进行操作

SysAddr16(sysbase,  offset)首先定义了一个16-BIT HALF-WORD的指针,指针的地址为sysbase,然后根据offset做个偏移操纵. 由于HALF-WORD指针的地址是2个BYTE对齐的, 所以每个偏移操纵会使得地址加2.  终极, SysAddr16 (sysbase, offset)相当于定义了一个HALF-WORD的指针,其终极地址为(sysbase  +  2offset) .在使用SysAddr16的时候,将sysbase设置成 FLASH 的起始地址,offset 则可以理解为相对于 FLASH 起始地址的HALF-WORD 偏移量或是偏移地址.假设FLASH 的起始地址为 0x10000000,SysAddr16(0x10000000, 0)指向 16-BIT FLASH 的第 0 个HALF-WORD, SysAddr16(0x10000000, 1指向16-BIT FLASH的第1个HALF-WORD.依次类推.假如要将0xABCD分别写到FLASH 的第0个和第 1个HALF-WORD 中往,可以用下面的代码:

*SysAddr16(0x10000000, 0x0) = 0xABCD;
*SysAddr16(0x10000000, 0x1) = 0xABCD;

接下来,我们分别从ARM处理器的角度和FLASH的角度来具体分析一下.

从 ARM 的角度来看:

  假设 FLASH 的起始地址为 0x10000000,由于 ARM 处理器知道 FLASH 的地址空间为 0x10000000 ~ (0x10000000 +FLASH容量 –  1),所以在对这个地址空间进行访问的时候,会设置好FLASH的片选信号,并将低位的地址输出到 地址信号上.以*SysAddr16(0x10000000, 0x1) = 0xABCD 为例.从ARM 处理器的角度来看,该操纵是把0xABCD写到地址0x10000002上往.所以ARM处理器终极会在它的地址信号An-A0输出地址0x2,同时会在D15-D0 上输出0xABCD.

从 FLASH 的角度来看:

  还是以  *SysAddr16(0x10000000, 0x1) = 0xABCD 为例,FLASH看到的地址是多少呢?接着分析.ARM 处理器在执行操纵的时候,会设置好相应的FLASH片选使能信号,并在ARM的地址信号An-A0上输出 0x2.由于 ARM和 16-BIT FLASH的地址信号的连接是错开一位的, 所以, FLASH终极在自己的地址An-A0上看到的信号是0x1, 相当于将ARM处理器输出的地址往右做了一个移位操纵,恰好对应的是FLASH的第1 个HALF-WORD.同时,FLASH会在自己的D15-D0上看到数据0xABCD.

通过上面的分析,我们知道 SysAddr16 中指定的 offset 的值就是 16-BIT FLASH 在自己的地址 An-A0 上看到的值.所以,我们可以很方便的通过 SysAddr16(sysbase, offset) 对 FLASH 进行操纵,其中 sysbase 代表 FLASH 起始地址,offset 则代表了FLASH 的第几个HALF-WORD(HALF-WORD偏移量或偏移地址)

注意:

  1. 在本节后面的描述中,SysAddr16中的 SYSBASE代表的是FLASH的起始地址,而SysAddr16中的 OFFSET则代表了相对于FLASH起始地址的 HALF-WORD 偏移量或偏移地址.OFFSET 的值也是16-BIT FLASH在自己的地址信号An-A0上看到的值;
  2. 在SST39VF160的命令定义中,所有的地址都是针对FLASH的HALF-WORD地址,指的是在FLASH自己的地址信号An-A0上看到的地址.

整片擦除操作

整片擦除操纵共需要6个周期的总线写操作:

  1. 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555;
  2. 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA;
  3. 将 0x0080 写到 FLASH HALF-WORD地址 0x5555;
  4. 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555;
  5. 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA;
  6. 将 0x0010 写到 FLASH HALF-WORD地址 0x5555.

对应的代码:

*SysAddr16(sysbase, 0x5555) = 0x00AA;    //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055;    //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x0080;    //将值 0x0080 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x5555) = 0x00AA;    //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055;    //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x0010;    //将值 0x0010 写到 FLASH HALF-WORD地址 0x5555

SECTOR擦除操作

SECTOR的擦除操纵共需要6个周期的总线写操作:

  1. 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555;
  2. 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA;
  3. 将 0x0080 写到 FLASH HALF-WORD地址 0x5555;
  4. 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555;
  5. 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA;
  6. 将 0x0030 写到要擦除的 SECTOR 对应的 HALF-WORD地址.

对应的代码:

*SysAddr16(sysbase, 0x5555) = 0x00AA;    //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055;    //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x0080;    //将值 0x0080 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x5555) = 0x00AA;    //将值 0x00AA 写到 FLASH HALF-WORD地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055;    //将值 0x0055 写到 FLASH HALF-WORD地址 0x2AAA
*SysAddr16(sysbase, addr >> 1) = 0x0030;    //将值 0x0030 写到要擦除的 SECTOR 对应的HALF-WORD地址

注意:

上面的代码中第6个操纵周期中的ADDR 是从ARM处理器的角度来看的BYTE地址,由于在擦除的时候,用户希看指定的是从 ARM 的角度看到的地址,这样更方便和更直观.而在 SysAddr16 的宏定义中,OFFSET 表示的是相对于FLASH起始地址的 HALF-WORD 偏移量,或是FLASH在自己的地址信号An-A0上看到的地址.所以需要执行一个右移操作,把ADDR转换成 HALF-WORD 地址.

举例说明,SST39VF160 每个 SECTOR 的大小是 4K-BYTE.从 ARM 处器的角度和用户的角度来看,SECTOR-0 相对于FLASH起始地址的BYTE地址是0x0;从FLASH来看SECTOR-0 的HALF-WORD地址是0x0.从ARM处理器的角度和用户的角度来看, FLASH SECTOR-1相对于FLASH起始地址的BYTE地址0x1000; 从FLASH来看, SECTOR-1的HALF-WORD地址应该是(0x1000 >> 1) = 0x800.

假如要擦除SECTOR-0,上面代码的第6条指令应该是:

*SysAddr16(sysbase, 0x0 >> 1) = 0x0030;

假如要擦除SECTOR-1,上面代码的第6条指令应该是:

*SysAddr16(sysbase, 0x1000 >> 1) = 0x0030;

HALF-WORD 编程操作

写一个HALF-WORD的数据到FLASH中往,需要4个周期的总线写操作:

  1. 将 0x00AA写到 FLASH HALF-WORD 地址 0x5555;
  2. 将 0x0055 写到 FLASH HALF-WORD地址 0x2AAA;
  3. 将 0x00A0 写到 FLASH HALF-WORD 地址 0x5555;
  4. 将编程数据(HALF-WORD)写到对应的 HALF-WORD地址.

对应的代码:

*SysAddr16(sysbase, 0x5555) = 0x00AA;      //将值 0x00AA 写到 FLASH 地址 0x5555
*SysAddr16(sysbase, 0x2AAA) = 0x0055;      //将值 0x0055 写到 FLASH 地址 0x2AAA
*SysAddr16(sysbase, 0x5555) = 0x00A0;      //将值 0x00A0 写到 FLASH 地址 0x5555
*SysAddr16(sysbase, addr >> 1) = data;      //将数据写到对应的 HALF-WORD 地址

注意:

上面的代码中第4个操作周期中的ADDR是从ARM处理器的角度来看的BYTE地址, 由于在执行写操作的时候,用户希看指定的是从 ARM 的角度看到的地址,这样会更方便和更直观.而在 SysAddr16 的宏定义中,OFFSET表示的是相对于FLASH起始地址的HALF-WORD偏移量. 所以需要执行一个右移操纵, 把它转换成HALF-WORD地址.

例如要将数据 0x0123 写到地址 0x0处,对应的是 FLASH 的第 0 个 HAFL-WORD,对应的 HALF-WORD 地址应该是0x0,上面代码的第4条指令应该是:

*SysAddr16(sysbase, 0x0 >> 1) = 0x0123;

又如要将数据0x4567写到地址0x2处, 对应的是FLASH的第1个 HALF-WORD, 对应的HALF-WORD地址应该是0x1, 上面代码的第4条指令应该是:

*SysAddr16(sysbase, 0x2 >> 1) = 0x4567;

再如要将数据0x89AB写到地址0x4处, 对应的是FLASH的第2个HALF-WORD, 对应的HALF-WORD地址应该是0x2,上面代码的第4条指令应该是:

*SysAddr16(sysbase, 0x4 >> 1) = 0x89AB;

还如要将数据0xCDEF 写到地址 0x6处,对应的是 FLASH 的第 3 个 HALF-WORD,对应的 HALF-WORD 地址应该是0x3,上面代码的第4条指令应该是:

*SysAddr16(sysbase, 0x6 >> 1) = 0xCDEF;

2.6 结束语

以上简单介绍了NOR FLASH原理,以及如何对NOR FLASH进行操作, 但没有包括状态查询, 保护等其他操纵. 对于更复杂的多片FLASH并联的情况也没有讨论,如有需要者,可自行分析.

本文转自:http://wiki.dzsc.com/info/5353.html#top

分类: flash
标签: 烧写, nor flash, 原理, 擦除
好文要顶 关注我 收藏该文  

冷烟花
关注 - 0
粉丝 - 60

+加关注

0
0

« 上一篇:arm linux kernel 从入口到start_kernel 的代码分析
» 下一篇:NAND/NOR FLASH和一些嵌入式存储概念

posted on 2013-03-13 14:16 冷烟花 阅读(12284) 评论(3) 编辑 收藏


FeedBack:

#1楼
2013-05-21 14:50 | lanxiaoha

你好 , 请问下面两句应该怎么理解?
#define SysAddr8(sysbase, offset) ((volatile U8*)(sysbase)+(offset))

*SysAddr16(0x10000000, 0x0) = 0xABCD;

我的理解是替换后:
*((volatile U8*)(sysbase)+(offset)) = 0xABCD;

但是我不明个(sysbase)+(offset)这个算是变量还是什么?

支持(0)反对(0)

#2楼[楼主]
2013-05-22 09:18 | 冷烟花

@ lanxiaoha
这两个宏不是一个概念!你看差了~
首先
#define SysAddr8(sysbase, offset) ((volatile U8*)(sysbase)+(offset))
这个宏是为了方便对一个字节操作而定义的.sysbase很明显是基址,offset是偏移
比如有 *SysAddr8(0x10000, 0x4) = 0xAB; 就是将0xAB这样一个字节的内容写如到地址0x10004上去


#define SysAddr16(sysbase, offset) ((volatile U16*)(sysbase)+(offset))这个宏 这是对两个字节(16bits)的操作

支持(0)反对(0)

#3楼
2016-08-30 13:47 | yanlutian

很详细 稍微领会下就懂了好多 感谢博主
支持(0)反对(0)

刷新评论刷新页面返回顶部
注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。
【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
【推荐】带SSD固态硬盘和电池的随身看片路由器开卖了
【推荐】移动直播百强八成都在用融云即时通讯云
【推荐】报表开发有捷径:快速设计轻松集成,数据可视化和交互
【推荐】网易云信-一天开发一个微信,独创1对1技术顾问让开发加速
最新IT新闻:
· 关于要不要对苹果补缴税 欧盟和爱尔兰争了起来
· 看不懂Google Analytics后台数据背后的意义?现在有机器人来帮你
· 苹果“太空船”园区屋顶安装太阳能电池板 礼堂接近完工
· 软件架构入门
· App Store新政变动:若用户长期续订、开发者可享85/15分成
» 更多新闻...
最新知识库文章:

· 程序猿媳妇儿注意事项
· 可是姑娘,你为什么要编程呢?
· 知其所以然(以算法学习为例)
· 如何给变量取个简短且无歧义的名字
· 编程的智慧

» 更多知识库文章...

一个喜欢Linux和驱动的小蜗牛

昵称:冷烟花
园龄:4年3个月
粉丝:60
关注:0

+加关注

我的标签

  • linux(26)
  • 串口(18)
  • 驱动(9)
  • SPI(8)
  • 内核(8)
  • ALSA(8)
  • 声卡(7)
  • TI(6)
  • 内存(5)
  • codec(5)
  • 更多

随笔分类(82)

  • algorithm(5)
  • alsa(8)
  • bootloader(2)
  • c programming languge(3)
  • filesystem(1)
  • flash(2)
  • i like(7)
  • iic(3)
  • input(3)
  • linux(28)
  • mac(3)
  • operating system(8)
  • serial(1)
  • spi(8)

最新评论

  • 1. Re:NOR Flash擦写和原理分析
  • 很详细 稍微领会下就懂了好多 感谢博主
  • --yanlutian
  • 2. Re:网口扫盲三:以太网芯片MAC和PHY的关系
  • 写的很好,不过有一点,WOL是wake on LAN,不是wake on line。“Wake on LAN (WOL) is a standard that allows you to turn o......
  • --wwjlisa
  • 3. Re:网口扫盲二:Mac与Phy组成原理的简单分析
  • 简单明白
  • --m8684589
  • 4. Re:VS2008项目移植到Linux
  • 您好,我的按您的一路做来为什么会出现 未将对象引用设置到对象的实例的错误
  • --zhiming257
  • 5. Re:Linux ALSA框架之三:PCM设备的创建
  • LZ写的ALSA帮助挺大,上面框图有个疑问,调用snd_pcm_open()打开/dev/snd/pcmC0D0p这个设备,我能查到我arm上存在录音设备,但我把这个参数(我的是/dev/snd/pc......
  • --xiaoxiao2015

阅读排行榜

  • 1. 网口扫盲三:以太网芯片MAC和PHY的关系(41067)
  • 2. NOR Flash擦写和原理分析(12284)
  • 3. Linux下串口编程入门(7810)
  • 4. 网口扫盲二:Mac与Phy组成原理的简单分析(6641)
  • 5. Linux ALSA框架之五:移动设备中的ALSA(ASoC)(4984)

评论排行榜

  • 1. NOR Flash擦写和原理分析(3)
  • 2. 网口扫盲二:Mac与Phy组成原理的简单分析(2)
  • 3. 网口扫盲三:以太网芯片MAC和PHY的关系(2)
  • 4. Linux ALSA框架之三:PCM设备的创建(1)
  • 5. VS2008项目移植到Linux(1)

推荐排行榜

  • 1. VS2008项目移植到Linux(2)
  • 2. 网口扫盲一:网卡初步认识(1)
  • 3. 网口扫盲二:Mac与Phy组成原理的简单分析(1)
  • 4. 网口扫盲三:以太网芯片MAC和PHY的关系(1)
  • 5. Linux下串口编程入门(1)

Copyright ©2016 冷烟花 Powered By博客园 模板提供:沪江博客

NOR FLASH工作原理相关推荐

  1. Optane ,内存,flash 工作原理对比

    1. 内存工作原理 2. Flash工作原理 3. Optane工作原理 4. 对比 5. 总结 http://www.cnblogs.com/QQParadise/articles/2430204. ...

  2. NAND FLASH 和NOR FLASH工作原理

    存储数据的原理 两种闪存都是用三端器件作为存储单元,分别为源极.漏极和栅极,与场效应管的工作原理相同,主要是利用电场的效应来控制源极与漏极之间的通断,栅极的电流消耗极小,不同的是场效应管为单栅极结构, ...

  3. 计算机原理eprom,eprom eeprom和flash储存器的工作原理及区别

    先介绍板答题存储器:据写入特性,可粗略地将半导体存储器划分为随机存取存储器(RAM,Random-Access Memory)和只读存储器(ROM,Read-Only Memory)两类.更进一步则可 ...

  4. linux下nand flash驱动工作原理,1.3.4. Nand flash驱动工作原理

    1.3.4. Nand flash驱动工作原理 在介绍具体如何写Nand Flash驱动之前,我们先要了解,大概的整个系统,和Nand Flash相关的部分的驱动工作流程,这样,对于后面的驱动实现,才 ...

  5. cpu工作原理flash动画_cpu的基本结构及其工作原理

    中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机指令以 ...

  6. cpu工作原理flash动画_17张PLC工作原理动画,每一个都是经典

    小编今天给大家带来17张PLC工作原理控制动画,每一个都是经典. 1.PLC顺序控制 顺序控制的基本思路,即要将设备的动作细分为单个动作步,每个步执行一个操作.且步与步之间通过对应的转换条件连接,及步 ...

  7. SPI FLASH(W25Q128BV) 包含SPI工作原理

    目录 一.SPI简介 1.全双工与半双工 2.同步与异步 3.SPI通信方式 二.SPI工作模式 三.W25Q128BV 1.读ID Read Manufacturer/Device ID(90h) ...

  8. JavaScript 工作原理之五-深入理解 WebSockets 和带有 SSE 机制的HTTP/2 以及正确的使用姿势(译)...

    原文请查阅这里,略有改动,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第五章. 现在 ...

  9. 阿里P7工作总结:Spring MVC的工作原理,看完受益匪浅

    这篇文章将深入探讨Spring框架的一部分--Spring Web MVC的强大功能及其内部工作原理. 项目安装 在本文中,我们将使用最新.最好的Spring Framework 5.我们将重点介绍S ...

最新文章

  1. 同一份数据,Redis为什么要存两次?
  2. $cfg_dbtype = mysql_Druid连接池二(学习笔记)
  3. PTA L2-001 紧急救援 (点带权最短路)
  4. Nginx学习之六:Nginx配置操作导航
  5. Atomic Integer 原理分析-其他方法
  6. Linux中find命令详解
  7. 简书UI易用性缺陷:投稿按钮太小
  8. Cesium加载GeoServer发布的SHP和GeoTIFF文件
  9. linux服务器系统时间和bios时间,Linux系统时间, 硬件BIOS时间的校准与同步
  10. eclipse windows 窗口背景颜色 保护视力
  11. matlab用我爱你绘制立体桃心,用MATLAB画心形图案
  12. 最炫表白网站html5源码_七夕程序员的十款表白源码_html+css+js
  13. [irisctf 2023] rev
  14. 计算总成绩和平均成绩
  15. 深度神经网络(DNN)Deep Neural Networks 介绍
  16. java 英文单词命名缩写_java程序员英文单词缩写和解释
  17. 【编程之美】一摞烙饼的排序
  18. 大数据入门教程,小白快速掌握Hadoop集成Kerberos安全技术
  19. com.android.camera.action.CROP照片剪辑的问题
  20. 常见传统算法实现DOA估计总结CBF、Capon、MUSIC、ESPRIT、OMP

热门文章

  1. 安装Django4.0最详细教程 pip总是报错怎么办
  2. 工资4500,副业22000,淘宝赚钱的路子到底有多野????
  3. MySQL攻略 - JDBC程序SQL注入,PreparedStatement接口详解与案例练习,JDBC相关API小结
  4. 主成分分析(PCA)是目前应用很广泛的一种代数特征提取方法
  5. 列王的纷争显示服务器过载高,列王的纷争新手迁城令攻略 怎么更换服务器
  6. 天降大任与斯人也,成功是有原因的
  7. eps文件转pdf不留白 不安装软件
  8. 创新链接未来,安全赋能发展——区块链技术网络安全应用创新大赛即将召开
  9. SIM71004G模块使用Linux C语言实现打电话发短信
  10. Axure绘制密码输入框