0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SPI flash是什么,关于SPI FLASH的读写问题

ss 作者:工程师谭军 2018-09-18 14:38 次阅读

本文主要是关于SPI flash的相关介绍,并着重对SPI flash的原理及其读写进行了相近的阐述。

SPI flash

SPI一种通信接口。那么严格的来说SPI Flash是一种使用SPI通信的Flash,即,可能指NOR也可能是NAND。但现在大部分情况默认下人们说的SPI Flash指的是SPI NorFlash。早期Norflash的接口是parallel的形式,即把数据线和地址线并排与IC的管脚连接。但是后来发现不同容量的Norflash不能硬件上兼容(数据线和地址线的数量不一样),并且封装比较大,占用了较大的PCB板位置,所以后来逐渐被SPI(串行接口)Norflash所取代。同时不同容量的SPI Norflash管脚也兼容封装也更小。,至于现在很多人说起NOR flash直接都以SPI flash来代称。

SPI flash是什么,关于SPI FLASH的读写问题

NorFlash根据数据传输的位数可以分为并行(Parallel,即地址线和数据线直接和处理器相连)NorFlash和串行(SPI,即通过SPI接口和处理器相连)NorFlash;区别主要就是:1、SPI NorFlash每次传输一bit位的数据,parallel连接的NorFlash每次传输多个bit位的数据(有x8和x16bit两种); 2、SPI NorFlash比parallel便宜,接口简单点,但速度慢。

NandFlash是地址数据线复用的方式,接口标准统一(x8bit和x16bit),所以不同容量再兼容性上基本没什么问题。但是目前对产品的需求越来越小型化以及成本要求也越来越高,所以SPI NandFlash渐渐成为主流,并且采用SPI NANDFlash方案,主控也可以不需要传统NAND控制器,只需要有SPI接口接口操作访问,从而降低成本。另外SPI NandFlash封装比传统的封装也小很多,故节省了PCB板的空间。

今天主要说下SPI NorFlash。

二、有毛用啊

节省成本,减小封装,存储数据。

三、怎么用啊

怎么用说白了对于Flash就是读写擦,也就是实现flash的驱动。先简单了解下spi flash的物理连接。

之前介绍SPI的时候说过,SPI接口目前的使用是多种方式(具体指的是物理连线有几种方式),Dual SPI、Qual SPI和标准的SPI接口(这种方式肯定不会出现在连接外设是SPI Flash上,这玩意没必要全双工),对于SPI Flash来说,主要就是Dual和Qual这两种方式。具体项目具体看了,理论上在CLK一定的情况下, 线数越多访问速度也越快。我们项目采用的Dual SPI方式,即两线。

当前涉及到具体的SPI flash芯片类型了,所以必须也得参考flash的datasheet手册了。我们以W25Q64JVSSIQ为例。

这是基本信息的介绍,然后看下具体IO的定义

这个是WSON封装的管脚定义,其他详细信息参考datasheet。

硬件驱动的话也是和芯片强相关的,因为读写擦都是和硬件时序相关的,所以必须得参考硬件datasheet手册。

上面的datasheet都详细说明了每个操作的时序周期发送的命令。上图中,第一列是指令名称,第二列是指令编码,第三列及以后的指令功能与对应的指令有关。带括号的字节内容为flash向主机返回的字节数据,不带括号则是主机向flash发送字节数据。

A0~A23:flash内部存储器地址;MID0~MID7:制造商ID;ID0~ID15:flash芯片ID;D0~D7:flash内部存储的数据;dummy:指任意数据。

比如获取deviceID:

表示该命令由这四个字节组成,其中dummy意为任意编码,即这三个字节必须得发数据,但这些数据是任意的,上图命令列表中带括号的字节数据表示由FLASH返回给主机的响应,可以看到deviceID命令的第5个字节为从机返回的响应,(ID7~ID0),即返回设备的ID号。

代码如下:

uint32_t Get_Flash_DeviceID(void)

{

uint8_t deviceID= 0x00;

spiflashReset();

spi_write( 0xAB);

spi_write( Dummy);

spi_write( Dummy);

spi_write( Dummy);

deviceID = spi_write( Dummy);

spi_write( Dummy);

spiflashSet() ;

return deviceID;

}

SPI Flash的擦写注意事项

SPI flash一般支持3种擦写方式:按sector擦写,按block擦写,整片chip擦写。

以KH25L3255E为例,

• Serial Peripheral Interface compatible -- Mode 0 and Mode 3

• 33,554,432 x 1 bit structure or 16,777,216 x 2 bits (two I/O mode) structure or 8,388,608 x 4 bits (four I/O

mode) structure

• 1024 Equal Sectors with 4K bytes each

- Any Sector can be erased individually

• 128 Equal Blocks with 32K bytes each

- Any Block can be erased individually

• 64 Equal Blocks with 64K bytes each

- Any Block can be erased individually

• Power Supply Operation

- 2.7 to 3.6 volt for read, erase, and program operations

• Latch-up protected to 100mA from -1V to Vcc +1V

由此可以看出,KH25L3255E的sector大小是4K,block大小是32K/64K.因此,可以一次性擦除4K/32K/64K.

三种擦写方式的性能比较:

- Fast erase time: 30ms (typ.)/sector (4K-byte per sector) ; 0.25s(typ.) /block (64K-byte per block); 10s(typ.) /

chip

从上述数据看,擦除同样大小的情况下,执行时间 sector》block》chip

按sector擦写,擦完64K需要0.48s,而按block一次性擦写64K只需要0.25s;按block擦写,擦完整片chip需要16s,而按chip擦写只需要10s;按sector擦写完整片chip需要30s。

linux/drivers/mtd/devices/m25p80.c看,m25p_probe函数在选择擦写单位时,是倾向于选择小单位的,会优先选择4K,如下:

/* prefer “small sector” erase if possible */

if (info-》flags & SECT_4K) {

flash-》erase_opcode = OPCODE_BE_4K;

flash-》mtd.erasesize = 4096;

} else {

flash-》erase_opcode = OPCODE_SE;

flash-》mtd.erasesize = info-》sector_size;

}

这在在用户空间体现在,使用mtd工具或者ioctl读取erasesize时读到的是sector(4K),如下:

# mtd_debug info /dev/mtd0

mtd.type = MTD_NORFLASH

mtd.flags = MTD_CAP_NORFLASH

mtd.size = 2883584 (2M)

mtd.erasesize = 4096 (4K)

mtd.writesize = 1

mtd.oobsize = 0

regions = 0

# mtdinfo /dev/mtd0

mtd0

Name: flash0.bolt

Type: nor

Eraseblock size: 4096 bytes, 4.0 KiB

Amount of eraseblocks: 704 (2883584 bytes, 2.8 MiB)

Minimum input/output unit size: 1 byte

Sub-page size: 1 byte

Character device major/minor: 90:0

Bad blocks are allowed: false

Device is writable: true

若想要将erasesize改成block大小,需要修改驱动,例如,将上述m25p80.c中的配置成SECT_4K的相关地方改成0,驱动就会使用block大小。

另外,需要注意的是,m25p80.c中“sector”和“block”的概念搞反了,里面的“block”才是规格书中的sector,一般是4K,请见OPCODE_BE_4K和OPCODE_SE两个宏定义处。

mtd.erasesize的大小会对应用上有一些影响,比较重要的一点是在制作某些嵌入式文件系统的镜像文件时,需要设置擦除单位,如果设置的擦除单位和驱动中的不符,会导致文件系统无法正常工作。

另外,porting层设置spi的擦写单位时,也需要注意当前实际的erasesize。

案例(解决方法就是修改驱动将spi-mtd的erasesize改成block大小,使其和jffs2的擦写单位一致):

http://bbs.csdn.net/topics/390299487/

《制作JFFS2时的erase_block与SPI FLASH中的erase_sector的关系?》

如题, 在制作JFFS2时 需要用到-e 参数(。/mkfs.jffs2 -b --pad=524288 -s 256 -e 65536 -d userfs/ -o usrjffs2.img)help命令中,对其的解释为: -e, --eraseblock=SIZE Use erase block size SIZE (default: 64KiB)。

在SPI FLASH(winbond 8M)的datasheet中写到:其erase_sector只能为4KB,erase_block可为32/64kB,

目前在SPI的驱动中,设置block_size为 64KB, erase_sector为 4KB。

问题来了!

将制作好的512K FLASH挂载到系统上后,会报如下错误:

jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00022034: 0x5771 instead

Further such events for this erase block will not be printed

Node at 0x00022f60 with length 0x000000f6 would run over the end of the erase block

Perhaps the file system was created with the wrong erase size?

jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00023000: 0x69c2 instead

进入系统后,发现jffs2中的文件有缺失。

根据报错提示以及网上资料, 原因应该为: 制作JFFS2时的erase_block 与系统的不符~。

但系统这块的block_size(这个应该也就是erase_block的大小吧?)已经是设置成64KB的了。

更改SPI驱动中,erase_sector的大小为64KB,则JFFS2报错问题解决, 但由于该SPI FLASH的

erase_sector是固定死的4K,贸然使用64KB(32KB同样)会造成再擦写FLASH时,极大概率出现某

一erase_secotr大小的块中数据为空的情况,即系统不能启动。

另,在制作JFFS2时,将-e参数设置为4096,以配合FLASH的erase_sector, 但悲催的是mkfs.jffs2

所支持-e 最小为8KB。

请问现在这个报错问题应该如何解决???

一点细节: 尝试添加了 -s 参数,其大小为FLASH page的大小256B,但问题依旧。

当JFFS2中文件较少时,不知为何就不会出现上方的报错。

关于SPI FLASH的读写问题

spi flash W25Q128会偶尔出现写入错误的情况,会发现读出的值和写入的值不一致,需加入2次读出比较判断。

21W25QXX_Read(&temp_date_count,0x000000,1);

//W25QXX_Write((u8*)&temp_date,0x400000,135);

//W25QXX_Read((u8*)&temp_data_test,0x400000,135);

W25QXX_Write((u8*)&temp_date,(temp_date_count*135+1),135);

W25QXX_Read((u8*)&temp_data_test,(temp_date_count*135+1),135);

if(memcmp(&temp_date,&temp_data_test,135)!=0)

{

W25QXX_Write((u8*)&temp_date,(temp_date_count*135+1),135);

W25QXX_Read((u8*)&temp_data_test,(temp_date_count*135+1),135);

if(memcmp(&temp_date,&temp_data_test,135)!=0)

{

W25QXX_Write((u8*)&temp_date,(temp_date_count*135+1),135);

}

}

temp_date_count=temp_date_count+1;//Each time a structure is written

if(temp_date_count==60)

{

temp_date_count=0;

}

W25QXX_Write(&temp_date_count,0,1);

结语

关于SPI flash的相关介绍就到这了,如有不足之处欢迎指正。

相关阅读推荐:揭开Zynq Z-7000从SPI接口挂载的flash启动的神秘面纱

相关阅读推荐:基于FPGA 的SPI Flash 控制器设计及验证

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FlaSh
    +关注

    关注

    10

    文章

    1547

    浏览量

    146629
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1610

    浏览量

    89539
收藏 人收藏

    评论

    相关推荐

    基于FPGA的SPI Flash控制器的设计方案

    传统的Flash读写是通过CPU软件编程实现,其读写速度较慢,且占用CPU资源,另外由于Flash芯片本身功能指令较多,使得对芯片进行直接操作变得非常困难。本文提出一个基于FPGA的
    发表于 09-24 09:12 5565次阅读
    基于FPGA的<b class='flag-5'>SPI</b> <b class='flag-5'>Flash</b>控制器的设计方案

    SPI方式FPGA配置和SPI flash编程

    SPI方式FPGA配置和SPI flash编程
    发表于 05-16 18:01 164次下载
    <b class='flag-5'>SPI</b>方式FPGA配置和<b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>编程

    基于红牛开发板的spi flash读写图片

    你的MCU上有外部总线接口,SPI flash就是通过SPI口对flash进行读写。速度上,总线flas
    发表于 09-01 17:16 16次下载
    基于红牛开发板的<b class='flag-5'>spi</b> <b class='flag-5'>flash</b><b class='flag-5'>读写</b>图片

    SPI flash如何运行程序,SPI flash有哪些应用

    SPI一种通信接口。那么严格的来说SPI Flash是一种使用SPI通信的Flash,即,可能指NOR也可能是NAND。
    的头像 发表于 09-19 10:54 1.8w次阅读
    <b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>如何运行程序,<b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>有哪些应用

    浅析spi flash驱动及其程序

    怎么用说白了对于Flash就是读写擦,也就是实现flash的驱动。先简单了解下spi flash的物理连接。
    的头像 发表于 10-07 11:26 1.8w次阅读
    浅析<b class='flag-5'>spi</b> <b class='flag-5'>flash</b>驱动及其程序

    浅析FLASH读写----SPI原理及应用

    SPI一种通信接口。那么严格的来说SPI Flash是一种使用SPI通信的Flash,即,可能指NOR也可能是NAND。
    的头像 发表于 10-07 11:32 2.2w次阅读
    浅析<b class='flag-5'>FLASH</b><b class='flag-5'>读写</b>----<b class='flag-5'>SPI</b>原理及应用

    STM32F0xx_SPI读写(Flash) 配置详细过程

    STM32F0xx_SPI读写(Flash)配置详细过程
    的头像 发表于 04-07 11:40 4604次阅读
    STM32F0xx_<b class='flag-5'>SPI</b><b class='flag-5'>读写</b>(<b class='flag-5'>Flash</b>) 配置详细过程

    STM32_ SPI读写Flash

    STM32_SPI读写Flash
    的头像 发表于 04-08 10:26 4905次阅读
    STM32_ <b class='flag-5'>SPI</b><b class='flag-5'>读写</b><b class='flag-5'>Flash</b>

    实现简单的SPI读写FLASH

    实现简单的SPI读写FLASH一、前言继上篇文章SPI的相关知识,本章主要介绍使用SPI协议实现简单的
    发表于 11-26 19:21 22次下载
    实现简单的<b class='flag-5'>SPI</b><b class='flag-5'>读写</b><b class='flag-5'>FLASH</b>

    SPI Nand Flash简介

    1.SPI Nand Flash简介SPI Nand Flash顾名思义就是串行接口的Nand Flash,它和普通并行的Nand
    发表于 12-02 10:51 33次下载
    <b class='flag-5'>SPI</b> Nand <b class='flag-5'>Flash</b>简介

    单片机学习笔记————STM32使用SPI读写串行Flash(三)

    第一步:读写相关函数在向 FLASH 芯片存储矩阵写入数据前,首先要使能写操作,通过“Write Enable”命令即可写使能。1.写使能命令/** * @brief 向Flash发送写使能命令
    发表于 12-22 19:15 4次下载
    单片机学习笔记————STM32使用<b class='flag-5'>SPI</b><b class='flag-5'>读写</b>串行<b class='flag-5'>Flash</b>(三)

    STM32F103学习笔记——SPI读写Flash(二)

    介绍1.软件设计流程SPI读写Flash流程:初始化通讯引脚及端口时钟;使能SPI时钟;配置SPI结构体;编写基本
    发表于 12-22 19:30 10次下载
    STM32F103学习笔记——<b class='flag-5'>SPI</b><b class='flag-5'>读写</b><b class='flag-5'>Flash</b>(二)

    SPI控制EF3内置FLASH读写

    电子发烧友网站提供《SPI控制EF3内置FLASH读写.pdf》资料免费下载
    发表于 09-27 10:19 1次下载
    <b class='flag-5'>SPI</b>控制EF3内置<b class='flag-5'>FLASH</b><b class='flag-5'>读写</b>

    SPI控制EF2内置FLASH读写

    电子发烧友网站提供《SPI控制EF2内置FLASH读写.pdf》资料免费下载
    发表于 09-26 15:16 2次下载
    <b class='flag-5'>SPI</b>控制EF2内置<b class='flag-5'>FLASH</b><b class='flag-5'>读写</b>

    基于FPGA的SPI Flash控制器的设计方案

    一个基于FPGA的SPI Flash读写硬件实现方案,该方案利用硬件对SPI Flash进行控制,能够非常方便地完成
    的头像 发表于 07-15 16:55 1280次阅读
    基于FPGA的<b class='flag-5'>SPI</b> <b class='flag-5'>Flash</b>控制器的设计方案