【SemeDrive】【X9H】SPI 通讯 —— 应用层到驱动层的调用

前言:

硬件平台:X9H
软件版本:PTG4.0
当应用层的 SPI 通讯失败时,需要弄清楚问题出现在哪个环节才能进行下一步动作。以下为 SPI 通讯时应用层到驱动层的代码调用流程。

一、整体架构

SPI 设备驱动:挂载在 SPI 总线上的设备的驱动,根据设备类型的不同有多种多样的驱动
SPI 通用接口:通用的 SPI 操作接口,API 库,SPI 设备驱动和 SPI 控制器驱动之间的纽带
SPI 控制器驱动:芯片内部的 SPI 控制器的驱动,封装了最基础的 SPI 操作接口,直接控制寄存器和中断响应
SPI 寄存器:硬件单元,使用 SPI 控制器驱动文件(kernel/drivers/spi/spi-dw.c)中的接口(dw_spi_show_regs)可以获取相关寄存器的值

SPI 控制器驱动注册时向 SPI 通用接口(spi.c)提供了 spi_controller 的数据结构,这个结构体里封装了对硬件 SPI 的操作函数。
SPI 设备驱动可以通过调用 spi.c 里提供的 API 接口来间接地调用 SPI 控制器驱动的函数。
SPI 控制器驱动和 SPI 设备驱动通过 spi.c 连接,耦合度低,可以随意搭配。


二、应用到驱动的代码调用

以下程序为例分析应用到驱动的代码调用:

应用程序:kernel/tools/spi/spi_test.c ,linux 内核自带的 spi_test 程序
SPI 设备驱动: kernel/drivers/spi/spidev.c 
SPI 通用接口:kernel/drivers/spi/spi.c
SPI 控制器驱动:kernel/drivers/spi/spi-dw-mmio.c 和 kernel/drivers/spi/spi-dw.c, spi-dw-mmio.c 主要负责设备注册,spi-dw.c 负责模式配置和数据传输。

spi 子节点注册完成后,会在 /dev/ 下创建一个设备节点。应用层通过这个节点和 ioctrl 接口调用驱动层的代码。

ioctrl 接口的参数可以分为两种: spi 模式配置和数据传输。

spi 模式配置 :

配置 spi 的 MAX_SPEED_HZ,BITS_PER_WORD,LSB_FIRST,WR_MODE 等属性。

代码流程:

spi 数据传输:


驱动在 spi.c 的 spi_transfer_one_message 函数中对片选线进行选中或取消,由程序可知,设备驱动每调用一次 spidev_sync,如果数据没有丢失,那么每 sync 一次则产生一次 spi 通讯。
一个 message 包含多个 xfer,一个 message 为一次通讯,一个 xfer 调用一次 spi 控制器驱动中的 dw_spi_transfer_one 接口,dw_spi_transfer_one 则通过 dw_writel 函数写入寄存器。

代码流程:

一次传输的大小即为一个 struct spi_message ,使用 spi_test 测试,携带的数据最大为 4096 bytes。

struct spi_message {
    struct list_head    transfers;
    struct spi_device   *spi;
    unsigned        is_dma_mapped:1;
    void            (*complete)(void *context);
    void            *context;
    unsigned        frame_length;
    unsigned        actual_length;
    int         status;
    struct list_head    queue;
    void            *state;
    struct list_head        resources;
};​
总结:以上为应用 spi_test.c 到设备驱动、控制器驱动、寄存器读写的大概代码调用流程。

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论