在嵌入式Linux(ARM)中,如何从通过SPI连接的闪存读/写?

在嵌入式Linux(ARM)中,如何从通过SPI连接的闪存读/写?,linux,linux-kernel,embedded-linux,kernel-module,flash-memory,Linux,Linux Kernel,Embedded Linux,Kernel Module,Flash Memory,我正在使用Yocto和meta-atmel构建一个嵌入式Linux(4.4.19)。在我的电路板上有一个通过SPI连接的闪存。 我试过几种方法在上面写字。但他们都失败了。 如何将数据读/写到其中 一些信息: Flashtype 4Mbit: s25fl164k() 通过设备树包括: spi1: spi@f8008000 { cs-gpios = <&pioC 25 GPIO_ACTIVE_HIGH>; status = "okay";

我正在使用Yocto和meta-atmel构建一个嵌入式Linux(4.4.19)。在我的电路板上有一个通过SPI连接的闪存。 我试过几种方法在上面写字。但他们都失败了。 如何将数据读/写到其中

一些信息:

Flashtype 4Mbit:
s25fl164k()

通过设备树包括:

    spi1: spi@f8008000 {
        cs-gpios = <&pioC 25 GPIO_ACTIVE_HIGH>;
        status = "okay";

        m25p80@0 {
            compatible = "spansion,s25fl164k";
            spi-max-frequency = <50000000>;
            reg = <0>;
        };
    };
fdisk
打印(查看
mtdblock8
):

阅读/写作测试:

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”。

您可以使用内存技术设备(MTD)子系统在闪存分区上执行擦除/写入/读取操作。 在您的情况下,SPI闪存已安装到mtdblock8。请使用以下命令查看所有现有分区

cat /proc/mtd
要写入mtd设备,请使用nandwrite命令。它可与busybox一起使用

安装尝试

mount -t jffs2 /dev/block/mtdblock8 /tmp/abc
MTD详情:

mtd UTIL的详细信息:
所以,让我们一步一步走。您的SPI NOR闪存在devicetree中进行了描述,您似乎已经成功地正确配置了内核(即,添加了相关的驱动程序)。这已由您的日志确认:

[    2.710000] m25p80 spi32766.0: at25df321a (4096 Kbytes)
似乎/dev/mtd8是与该设备关联的MTD设备(根据您的大小分析),这也是事实。您应该能够通过检查/sys/class/mtd来确认它

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

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


hashdefine回复中提到的自由电子帖子也不错。

您可以尝试更低的时钟频率,这可以解决我在SPI闪存方面的问题:

spi-max-frequency = <10000000>
spi最大频率=

您可以使用mtd_调试命令工具。使用此工具可以测试读/写一个字节。这对于定位问题非常方便。

可能设备是通过U-Boot锁定的,并且在内核的m25p80驱动程序中没有实现ioctl UNLOCK。我以前见过,请参阅

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

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

        // conflicts with spi1 
        i2c1: i2c@f0018000 {
            status = "disabled";
        };
        // confilcts with spi1 (pin PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10)
        isi: isi@f0034000 {
            status = "disabled";
        };
};
ahb{
apb{
spi1:spi@f8008000 {
cs gpios=;
status=“好”;
m25p80@0 {
compatible=“spansion,s25fl132k”,“jedec,spi nor”;
spi最大频率=;
reg=;
m25p,快速读取;
};
};
//与spi1冲突
i2c1:i2c@f0018000 {
status=“disabled”;
};
//与spi1冲突(插脚PC27外围B TWCK1插脚,与spi1\U NPCS2、ISI\U D10冲突)
isi:isi@f0034000 {
status=“disabled”;
};
};

现在它工作正常了

spi与mtd8关联:mtd8->../devices/soc0/ahb/ahb:apb/f0004000.spi/spi_master/spi32766/spi32766.0/mtd/mtd8立即尝试:flash_eraseall/dev/mtd8 echo“hello”>/dev/mtd8 cat/dev/mtd8但失败请相信我,该顺序看起来是正确的:闪存擦除、写入、读取是正确的。因此,您需要检查其他事项:1)驱动程序工作正常吗(可能是的)?2)CS线路工作正常吗?3)设备是否正确连接在SPI总线上?…我想说,在这一点上,您需要逻辑分析仪的帮助。我同意您的意见。明天我将检查scematic/pcb。我将更新该问题。闪存擦除似乎工作正常。但写入闪存失败。您能给出一个如何做到这一点的示例吗?SPI闪存是s指定为54MHz(正常)和108MHz(快速)。已检查降低频率。这对问题没有影响,写入似乎不起作用。m25p80驱动程序中未实现解锁。我将检查uboot代码。flash_解锁/dev/mtd8 flash_解锁:错误!:无法解锁设备:/dev/mtd8错误95(不支持操作)我检查了我的sama5d35板(sama5d3xek.c)的引导加载程序。没有对m25p80驱动程序的函数调用。这个答案很有意义。我建议检查数据表并确保分区已解锁。转储寄存器和检查它应该很容易,还可以检查您是否以某种方式硬件锁定了设备。
spi-max-frequency = <10000000>
ahb {
    apb {
        spi1: spi@f8008000 {
            cs-gpios = <&pioC 25 GPIO_ACTIVE_LOW>;
            status = "okay";
            m25p80@0 {
                compatible = "spansion,s25fl132k", "jedec,spi-nor";
                spi-max-frequency = <108000000>;
                reg = <0>;
                m25p,fast-read;
            };
        };

        // conflicts with spi1 
        i2c1: i2c@f0018000 {
            status = "disabled";
        };
        // confilcts with spi1 (pin PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10)
        isi: isi@f0034000 {
            status = "disabled";
        };
};