当前位置 主页 > 技术大全 >

    Linux下SPI EEPROM操作指南
    linux eeprom spi

    栏目:技术大全 时间:2024-12-09 12:37



    Linux下的EEPROM SPI驱动开发与应用 在现代电子系统中,EEPROM(电可擦可编程只读存储器)作为一种非易失性存储器,广泛应用于各种嵌入式设备和系统中

        它们不仅用于存储配置参数和校准数据,还常用于固件更新和存储关键的系统信息

        而SPI(Serial Peripheral Interface,串行外围设备接口)作为一种高速、全双工、同步的通信协议,由于其简单易用和占用芯片管脚少的特性,成为EEPROM连接的主要接口之一

        本文将详细介绍如何在Linux系统下开发和应用基于SPI接口的EEPROM驱动

         SPI总线概述 SPI总线是由Motorola在其MC68HCXX系列处理器上首先定义的,主要用于EEPROM、FLASH存储器、实时时钟、AD转换器以及数字信号处理器和数字信号解码器之间的通信

        SPI总线在芯片的管脚上只占用四根线:MOSI(主设备数据输出,从设备数据输入)、MISO(主设备数据输入,从设备数据输出)、CLK(时钟信号,由主设备产生)和nCS(从设备使能信号,由主设备控制)

        这种设计不仅节约了芯片的管脚,还为PCB的布局节省了空间

         SPI总线传输数据采用高位在前(MSB first),低位在后的方式

        在CLK的下降沿上数据改变,而在上升沿时一位数据被存入移位寄存器

        一个SPI时钟周期内会完成以下操作: 1. 主设备通过MOSI线发送1位数据,同时从设备通过MOSI线读取这1位数据

         2. 从设备通过MISO线发送1位数据,同时主设备通过MISO线读取这1位数据

         主设备和从设备各有一个移位寄存器,这两个移位寄存器连接成环状

        依照CLK的变化,数据以MSB first的方式依次移出主设备寄存器和从设备寄存器,并依次移入从设备寄存器和主设备寄存器

        当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换

         SPI总线传输一共有四种模式,分别由时钟极性(CPOL)和时钟相位(CPHA)来定义

        这四种模式决定了时钟信号空闲状态的电平和数据是在时钟的上升沿还是下降沿被采样

        其中,模式0(CPOL=0, CPHA=0)和模式3(CPOL=1, CPHA=1)较为常用

         Linux SPI框架 Linux系统对SPI设备提供了良好的支持,其SPI驱动程序从逻辑上可以分为三个部分:SPI核心(SPI Core)、SPI控制器驱动(SPI Master Driver)和SPI设备驱动(SPI Device Driver)

         1.SPI核心(SPI Core): SPI Core是Linux内核用来维护和管理SPI设备的核心部分

        它提供操作接口函数,允许SPI主控制器、SPI驱动和SPI设备在初始化时在SPI Core中进行注册,并在退出时进行注销

         2.SPI控制器驱动(SPI Master Driver): SPI Master Driver针对不同类型的SPI控制器硬件,实现SPI总线的硬件访问操作

        它通过接口函数向SPI Core注册一个控制器

         3.SPI设备驱动(SPI Device Driver): SPI Device Driver是对应于SPI设备端的驱动程序,通过接口函数向SPI Core进行注册

        它的作用是将SPI设备挂接到SPI总线上

         EEPROM SPI驱动开发 在Linux系统下开发EEPROM SPI驱动,通常需要参考EEPROM的具体数据手册,并基于Linux提供的SPI框架进行开发

        以下以AT25M02 EEPROM为例,详细介绍驱动开发的步骤

         AT25M02 EEPROM简介 AT25M02是一款2Mbit(262,144 x 8)的SPI串行EEPROM,适用于许多低功率和低压操作必不可少的工业和商业应用

        它支持SPI模式0(0,0)和模式3(1,1),具有5MHz的时钟速率和256字节的页模式,寻址方式为24位

         驱动开发步骤 1.设备树配置: 在Linux系统中,EEPROM通过设备树(Device Tree)进行配置

        首先,在SPI节点的子节点中添加EEPROM节点,并根据EEPROM的数据手册和驱动程序进行配置

        例如: dts &spi0{ is-decoded-cs=<0>; num-cs=<1>; status=okay; eeprom: eeprom-at25m02@0 { compatible=atmel,at25; spi-max-frequency=<5000000>; // 5MHz reg=<0>; // 在 drivers/misc/eeprom/at25.c 和 include/linux/spi/eeprom.h 中定义 at25,addr-mode=<4>; // address bits: 24 bit at25,page-size=<256>; // Page: 256 Byte at25,byte-len=<262144>; // 262144bytes (2-Mbit) }; }; 2.驱动程序开发: Linux内核已经提供了EEPROM设备的通用驱动程序,位于`drivers/misc/eeprom`目录下

        对于SPI接口的EEPROM,重点关注`at25.c`文件

        该文件定义了一些操作指令和参数,如写使能、读状态寄存器、写状态寄存器、读字节(s)和写字节(s)/扇区等

         驱动程序提供了以下接口函数: -`at25_bin_read()` -`at25_bin_write()` -`at25_ee_read()` -`at25_ee_write()` -`at25_mem_read()` -`at25_mem_write()` -`at25_np_to_chip()` -`at25_probe()` -`at25_remove()` 在`at25_driver`结构体中的`driver`成员中增加`of_match_table`,该表定义了与设备树中兼容的设备匹配信息

        例如: c static const structof_device_id at25_of_match【】 ={ { .compatible = atmel,at25,}, {}, }; MODULE_DEVICE_TABLE(of, at25_of_match); static struct spi_driver at25_driver ={ .driver ={ .name = at25, .owner =THIS_MODULE, .of_match_table = at25_of_match, }, .probe = at25_probe, .remove = at25_remove, }; module_spi_driver(at25_driver); MODULE_DESCRIPTION(Driver for most SPI EEPROMs); MODULE_AUTHOR(David Brownell); MODULE_LICENSE(GPL); MODULE_ALIAS(spi:at25); 3