1

我使用Yocto和meta-atmel来构建嵌入式Linux(4.4.19)。在我的主板上是一个通过SPI连接的Flash。 我尝试了几种写法。但他们都失败了。 如何读取/写入数据?如何在嵌入式Linux(ARM)中通过SPI连接的Flash中读取/写入数据?

一些信息:

的FlashType的4Mbit:

spi1: [email protected] { 
     cs-gpios = <&pioC 25 GPIO_ACTIVE_HIGH>; 
     status = "okay"; 

     [email protected] { 
      compatible = "spansion,s25fl164k"; 
      spi-max-frequency = <50000000>; 
      reg = <0>; 
     }; 
    }; 

内核配置:

dmesg打印在启动时:

[ 2.630000] Creating 8 MTD partitions on "atmel_nand": 
[ 2.640000] 0x000000000000-0x000000040000 : "bootstrap" 
[ 2.640000] 0x000000040000-0x0000000c0000 : "uboot" 
[ 2.650000] 0x0000000c0000-0x000000100000 : "env" 
[ 2.660000] 0x000000100000-0x000000140000 : "env_redundant" 
[ 2.660000] 0x000000140000-0x000000180000 : "spare" 
[ 2.670000] 0x000000180000-0x000000200000 : "dtb" 
[ 2.670000] 0x000000200000-0x000000800000 : "kernel" 
[ 2.680000] 0x000000800000-0x000010000000 : "rootfs" 
[ 2.690000] atmel_spi f0004000.spi: version: 0x213 
[ 2.690000] atmel_spi f0004000.spi: DMA TX channel not available, SPI unable to use DMA 
[ 2.700000] atmel_spi f0004000.spi: Atmel SPI Controller using PIO only 
[ 2.700000] atmel_spi f0004000.spi: Atmel SPI Controller at 0xf0004000 (irq 25) 
[ 2.710000] m25p80 spi32766.0: at25df321a (4096 Kbytes) 

fdisk打印(看mtdblock8):

[email protected]:~# fdisk -l 
Disk /dev/ram0: 8 MiB, 8388608 bytes, 16384 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/4096 bytes 
I/O size (minimum/optimal): 4096 bytes/4096 bytes 


Disk /dev/ram1: 8 MiB, 8388608 bytes, 16384 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/4096 bytes 
I/O size (minimum/optimal): 4096 bytes/4096 bytes 


Disk /dev/ram2: 8 MiB, 8388608 bytes, 16384 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/4096 bytes 
I/O size (minimum/optimal): 4096 bytes/4096 bytes 


Disk /dev/ram3: 8 MiB, 8388608 bytes, 16384 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/4096 bytes 
I/O size (minimum/optimal): 4096 bytes/4096 bytes 


Disk /dev/mtdblock0: 256 KiB, 262144 bytes, 512 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock1: 512 KiB, 524288 bytes, 1024 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock2: 256 KiB, 262144 bytes, 512 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock3: 256 KiB, 262144 bytes, 512 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock4: 256 KiB, 262144 bytes, 512 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock5: 512 KiB, 524288 bytes, 1024 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock6: 6 MiB, 6291456 bytes, 12288 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock7: 248 MiB, 260046848 bytes, 507904 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mtdblock8: 4 MiB, 4194304 bytes, 8192 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 


Disk /dev/mmcblk0: 7.4 GiB, 7985954816 bytes, 15597568 sectors 
Units: sectors of 1 * 512 = 512 bytes 
Sector size (logical/physical): 512 bytes/512 bytes 
I/O size (minimum/optimal): 512 bytes/512 bytes 
Disklabel type: dos 
Disk identifier: 0x00000000 

Device   Boot Start  End Sectors Size Id Type 
/dev/mmcblk0p1  8192 15597567 15589376 7.4G b W95 FAT32 

读/写测试:

cat /dev/mtdblock8 
echo "hello" > /dev/mtdblock8 
cat /dev/mtdblock8 

我没有得到任何结果/错误。

安装:

mkdir /tmp/abc 
mount -t jffs2 /dev/mtdblock8 /tmp/abc 
mount: /dev/mtdblock8: can't read superblock 

任何想法?

我喜欢做一个演示。假设在SPI闪存的12345位写上“hello Linux”。

+0

Flash_erase似乎工作。但写入闪存失败。你能举个例子怎么做? –

回答

1

我的设备树表文件出现错误。 spi1,图像传感器接口(isi1)和i2c(i2c1)使用相同的引脚。编译内核+ dts时没有显示错误。 通常,fdisk + mtd_debug的组合对于检查驱动程序和低级别的硬件非常有用。在我的情况SAMA5D35 +主板拥有DTS @:

ahb { 
    apb { 
     spi1: [email protected] { 
      cs-gpios = <&pioC 25 GPIO_ACTIVE_LOW>; 
      status = "okay"; 
      [email protected] { 
       compatible = "spansion,s25fl132k", "jedec,spi-nor"; 
       spi-max-frequency = <108000000>; 
       reg = <0>; 
       m25p,fast-read; 
      }; 
     }; 

     // conflicts with spi1 
     i2c1: [email protected] { 
      status = "disabled"; 
     }; 
     // confilcts with spi1 (pin PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10) 
     isi: [email protected] { 
      status = "disabled"; 
     }; 
}; 

现在它工作正常

1

您可以使用内存技术设备(MTD)子系统在闪存分区上进行擦除/写入/读取操作。 SPI闪存安装在您的case.Use到mtdblock8下面的命令来查看所有现有分区

cat /proc/mtd 

要写入MTD设备,使用nandwrite命令。它与busybox一起提供。

有关MTD安装试

mount -t jffs2 /dev/block/mtdblock8 /tmp/abc 

详情: http://free-electrons.com/blog/managing-flash-storage-with-linux/

细节上MTD utils的: http://processors.wiki.ti.com/index.php/Mtdutils

2

那么,让我们一步一步来。您的SPI NOR闪存在devicetree中进行了描述,似乎您已经设法正确配置您的内核(即添加相关驱动程序)。这是由你的日志证实:

[ 2.710000] m25p80 spi32766.0: at25df321a (4096 Kbytes) 

这也似乎真的的/ dev/mtd8是与设备(从大小分析)相关的MTD设备。您应该能够通过检查/ sys/class/mtd来确认它。

现在,为了对设备进行编程,您需要1)擦除要写入的扇区,2)写入这些扇区,最后回读并确认。 要写入,可以使用write()系统调用(即cat somefile > /dev/mtd8)。要清除,您需要一个ioctl系统调用,即flash_erase命令。

的MTD网站有一些相关的信息:

http://www.linux-mtd.infradead.org/index.html

在hashdefine答复中提到的自由电子后是没关系。

+0

spi与mtd8关联: mtd8 - > ../../devices/soc0/ahb/ahb:apb/f0004000.spi/spi_master/spi32766/spi32766.0/mtd/mtd8 –

+0

现在尝试: flash_eraseall/dev/mtd8 echo“hello”>/dev/mtd8 cat/dev/mtd8 但失败 –

+0

相信我,那个序列看起来是正确的:flash_erase,write,read,就是要走的路。所以你需要检查其他的东西:1)驱动程序工作正常(可能是)? 2)CS线是否正常工作? 3)设备是否正确连接在SPI总线上?......我想说的是,在这一点上,你需要逻辑分析仪的帮助。 –

0

您可以尝试较低的时钟频率,这解决了我的问题与SPI FLASH:

spi-max-frequency = <10000000> 
+0

SPI闪存指定为54MHz(正常)和108MHz(快速)。检查降低频率。它对问题没有影响,写入似乎不起作用。 –

1

可以使用mtd_debug命令工具。使用此工具可以测试读/写一个字节。这对于本地化问题非常方便。

2

也许该设备被U-Boot锁定,并且ioctl UNLOCK未在您的内核的m25p80驱动程序中实现。我以前见过,请参阅erasing-flash-nor-ioctlmemunlock-return-status

+0

解锁没有在m25p80驱动程序中实现。我将检查uboot代码。 –

+0

flash_unlock/dev/mtd8 flash_unlock:错误!:无法解锁设备:/ dev/mtd8 错误95(操作不支持) –

+0

我检查了我的sama5d35开发板的引导程序(sama5d3xek.c)。没有函数调用m25p80驱动程序。 –

相关问题