linux驱动之spi(铁电fm25v02a)

一、前言

在嵌入式开发领域,数据存储的“速度”与“可靠性”往往是一对矛盾。传统的 EEPROM 写入缓慢,而 Flash 又面临擦除寿命和掉电风险的挑战。铁电存储器 (FRAM) 的出现,以其近乎无限的读写寿命和 RAM 级的高速写入性能,成为了工业控制和车载电子中的“存储宠儿”。

然而,在高性能 SoC 如 Rockchip RK3506 上,如何让 Linux 内核精准识别并高效驱动一块 SPI 接口的 FRAM?为什么我们在 /dev 下找不到熟悉的设备节点,却要在 sysfs 的深处寻其踪迹?本文将结合笔者的实战经历,深入解析 Linux 内核 at25 驱动框架,带你打通从设备树配置到用户态读写的全链路。

二、驱动及设备树

1.开启at25 eeprom驱动
image
CONFIG_EEPROM_AT25=y
2.开启rockchip spi control driver
image
CONFIG_SPI_ROCKCHIP=y

3.设备树配置
由于原理图看出来spi0引脚用的全部是rmio
image
我们从rk3506-pinctrl-rmio.dtsi找到对应rmio功能标签写到pinctrl-0中

&spi0 {
    status = "okay";
    pinctrl-names = "default";
	pinctrl-0 = <&rm_io1_spi0_clk &rm_io3_spi0_mosi &rm_io6_spi0_miso &rm_io7_spi0_csn0>;

    fram@0 {
        compatible = "cypress,fm25", "fram-spi";
        reg = <0>;               // CS0
        spi-max-frequency = <20000000>;  // FM25V02A 支持到 40MHz,保守用 20MHz
        pagesize = <256>;
    };
};

三、开机log

可以看到铁电已经被识别到,但是/dev下没有出现可以操作的设备,是因为 at25 驱动根据设备树配置,直接在 sysfs 层级下创建了一个名为 fram 的二进制属性文件

root@rk3506-buildroot:/# dmesg | grep spi
[    1.191710] rockchip-spi ff120000.spi: no high_speed pinctrl state
[    1.192828] at25 spi0.0: 32 KByte fm25 fram, pagesize 4096
[    1.192890] rockchip-spi ff120000.spi: probed, poll=0, rsd=0, cs-inactive=0, ready=0
[    1.194190] spi-nand spi2.0: XINCUN SPI NAND was found.
[    1.194201] spi-nand spi2.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
[    1.196351] 8 cmdlinepart partitions found on MTD device spi-nand0
[    1.196362] Creating 8 MTD partitions on "spi-nand0":
root@rk3506-buildroot:/# dmesg | grep fram
[    1.192828] at25 spi0.0: 32 KByte fm25 fram, pagesize 4096
root@rk3506-buildroot:/#

四、测试

查看前64字节内容

root@rk3506-buildroot:~# hexdump -C /sys/bus/spi/devices/spi0.0/fram | head -n 4
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008000
root@rk3506-buildroot:~#

写入一段文本,再次读取确认

root@rk3506-buildroot:~# echo "Hello_RK3506_FRAM" > /sys/bus/spi/devices/spi0.0/fram
root@rk3506-buildroot:~# cat /sys/bus/spi/devices/spi0.0/fram | head -c 17
Hello_RK3506_FRAMroot@rk3506-buildroot:~#

使用dd命令清空整个32k后再读取确认清零成功

root@rk3506-buildroot:~# dd if=/dev/zero of=/sys/bus/spi/devices/spi0.0/fram bs=1k count=32
32+0 records in
32+0 records out
root@rk3506-buildroot:~# hexdump -C /sys/bus/spi/devices/spi0.0/fram | head -n 4
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008000
root@rk3506-buildroot:~#
posted @ 2026-03-19 14:39  上善若淼  阅读(5)  评论(0)    收藏  举报