SPI message基础

Contents

.Part 1 - Linux SPI系统概览

.Part 2 - SPI message 基础

.Part 3 - 异步写

LinuxSPI 通信基础

在SPI总线上是通过封装一系列的spi_transfer到一个spi_message中,然后将spi_message提交到SPI子系统去。

下面是spi_transfer结构:

struct spi_transfer {const void*tx_buf;  //驱动提供的发送缓冲区dma,void *rx_buf;    //接收缓冲区unsigned len;dma_addr_ttx_dma;  //发送dma,controller使用dma_addr_t rx_dma;   //接收dmaunsigned cs_change:1;    //片选位 u8 bits_per_word; //每字长度u16 delay_usecs;  //延迟u32 speed_hz;    //速度struct list_headtransfer_list; //transfer 链表
};

len is always the # of 8-bitbytes to clock, could be send ,receive or both.

tx_dmarx_dma可通过dma_map_single()来初始化或者让controller来填充这些域。如果你手动的映射这些dma,就必须将spi_message.is_dma_mappped置为1,来告知controller你已经做好映射了。既然手动的做映射也必须手的unmapped掉。并不是所有的transfer都会使用dma,比如,有的控制器在transfer小于8字节时会使用PIO(ProgrammingI/O,cpu执行I/O端口指令进行读写,大数据交换是会提高cpu占有率)模式。

cs_change置1会引起CS线在spi_message序列中transfers间变高。通常,CS会在第一个transfer前变低并一直保持直至spi_message序列中最后一个transfer到来(这是本次spi_message中最后一个)。这种反转在和某些设备通信时会非常有用。

bit_per_word对于单个spi_transfer可用来覆盖spi_device.bits_per_word域。清零不做覆盖。

delay_usecs会在spi_message序列中一个transfer之后,CS状态改变前或者下一个transfer修正延迟。

speed_hz允许这个transfer可以有高于spi_device.max_speed_hz的速率。清零不作变化。

transfer_listspi_message序列中用于维护transfer的链表。

在spi_transfer中时常更改的域也许只有len,tx_buf和rx_buf。剩下的当以0来初始化。

单个spi_transfer可表示一次读,一次写或者是一次读写。在SPIcontroller驱动下,所有操作常是全双工的。向spi_transfer中rx_buf传递一个NULL,这就是一次只写操作,会丢弃MISO线上的数据。同样向tx_buf传递一个NULL,这就是一次只读操作了。spi_transfer中len域代表(已经多少字节数据流过总线了)howmany bytes to clock the bus。

spi_message结构:

struct spi_message {struct list_head transfers;struct spi_device *spi;unsigned is_dma_mapped:1;void (*complete)(void*context);void *context;unsigned actual_length;int status;struct list_head queue;void *state;
};

transfer这个spi_message所包含有的spi_transfer链表头。

is_dma_mappedspi_transfer中tx_dma和rx_dma是否已经mapped。

complete回调函数

context 提供给complete的可选参数

actual_lengthspi_message已经传输了的字节数

status 出错与否,错误时返回errorcode

queuestate 供controller驱动内部使用

在每次使用spi_message可以使用函数:

void spi_message_init(structspi_message *m);

来初始化。

向spi_message添加transfers可以使用spi_message_add_tail()函数:

void spi_message_add_tail(structspi_transfer *t, struct spi_message *m);

一旦你准备好了spi_message,就可以使用spi_async()来向SPI系统提交了:

int spi_async(struct spi_device *spi,struct spi_message *message);

因为是异步的,一提交就立马返回了,这也就是说需要同步机制(complete就是了)。他确保不会睡眠,可安全的在中断handler或其他不可休眠的代码中调用。稍后会念念他的好的。

使用spi_async()需要注意的是,在complete()未返回前不要轻易访问你一提交的spi_transfer中的buffer。也不能释放SPI系统正在使用的buffer。一旦你的complete返回了,这些buffer就又是你的了。

使用完成回调机制稍显复杂,可以使用SPI系统提供的另一个同步版本:spi_sync():

int spi_sync(struct spi_device *spi,struct spi_message *message);

因为是同步的,spi_sync提交完spi_message后不会立即返回,会一直等待其被处理。一旦返回就可以重新使用buffer了。spi_sync()在drivers/spi/spi.c中实现,其调用了spi_async(),并休眠直至complete返回。

SPI message 基础 Part 2相关推荐

  1. 【STM32H7教程】第72章 STM32H7的SPI总线基础知识和HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第72章       STM32H7的SPI总线基础知识和HA ...

  2. Dubbo SPI的基础Cooma微容器

    为什么80%的码农都做不了架构师?>>>    从dubbo的SPI理念开始,由于dubbo的项目Leader一开始就把其定义成一个方便扩展的服务框架,所以在dubbo的架构设计中始 ...

  3. PX4模块设计之四十一:I2C/SPI Bus Instance基础知识

    PX4模块设计之四十一:I2C/SPI Bus Instance基础知识 1. 基础知识 2. 基础类和定义 2.1 ListNode类 2.2 List类 2.3 BusCLIArguments类 ...

  4. 沁恒CH32V307使用记录:SPI基础使用

    文章目录 目的 基础说明 使用演示 其它补充 总结 目的 SPI是单片机中比较常用的一个功能.这篇文章将对CH32V307中相关内容进行说明. 本文使用沁恒官方的开发板 (CH32V307-EVT-R ...

  5. SPI接口的FPGA实现(一)——SPI接口的相关基础知识

    SPI系列文章主要介绍SPI接口的一些基础知识,并用DAC芯片81416的配置为例来具体说明SPI接口的具体FPGA实现. 一.SPI的基础 SPI的全称是Serial Peripheral Inte ...

  6. Linux kernel SPI源码分析之SPI设备驱动源码分析(linux kernel 5.18)

    SPI基础支持此处不再赘述,直接分析linux中的SPI驱动源码. 1.SPI设备驱动架构图 2.源码分析 本次分析基于kernel5.18,linux/drivers/spi/spidev.c 设备 ...

  7. 【MM32F5270】RT-Thread SPI 驱动适配指南

    目录 drv_spi.h rt_hw_spi_device_attach接口声明 drv_spi.c SPI总线配置 SPI总线对象 SPI总线设备注册 rt_hw_spi_device_attach ...

  8. SPI驱动框架源码分析

     SPI驱动框架源码分析 2013-04-12 16:13:08 分类: LINUX SPI驱动框架源码分析 SPI协议是一种同步的串行数据连接标准,由摩托罗拉公司命名,可工作于全双工模式.相关通讯设 ...

  9. OPENWRT lede MT7628dan 增加SPI接口

    SPI是可以全双工通信的一种串行总线,两个设备之间双向通信的话一般使用3根线:SCLK,MISO,MOSI,多个设备之间双向通信的话,每个设备还需要再加上一根地址线CSn.相比之下I2C只能半双工,而 ...

最新文章

  1. “蓝桥杯”软件大赛入门训练4道题
  2. 深入分析Linux内核源码oss.org.cn/kernel-book/
  3. 第一节:ASP.NET开发环境配置
  4. 解决“Class org.apache.hadoop.hdfs.DistributedFileSystem not found“问题
  5. 语言密码加密变星号_为什么汉字不能设成密码,你想过吗?
  6. 3.凤凰架构:构建可靠的大型分布式系统 --- 事务处理
  7. 项目管理软件-禅道-内网部署
  8. 编写谷歌浏览器插件入门
  9. 阿里云平台购买域名 域名配置 域名解析步骤
  10. 申请美国密歇根州立大学需要具备哪些条件?
  11. 钢铁骑士团服务器端文件,《钢铁骑士团》新手必读 游戏道具介绍
  12. 开关电源原理、电路组成部分
  13. 易周金融观点:遏制NFT金融化等打下监管良基
  14. 怎么在FLASH的场景中控制影片剪辑的播放和停止
  15. oracle序列号、
  16. RHCE 第十一天 mail postfix dovecot SSL
  17. 关于 GeneXus 起源的几点思考
  18. 用python画佩奇_使用python画个小猪佩奇的示例代码
  19. 计算机课是怎样查出勤的,基于计算机视觉技术的课堂自动考勤系统研究
  20. 一款超方便超强大的16进制编辑器软件-HxD

热门文章

  1. 没有空间的感觉是什么样子的
  2. 主管发话:一周搞不定用友U8 ERP跨业务数据分析,明天就可以“毕业”了
  3. hive中的四大排序
  4. 【老生谈算法】matlab实现马氏链算法源码——马氏链
  5. UPI,QPI,CSI,FSB
  6. ERP管理系统是什么?
  7. adobe全家桶摄影计划
  8. 基于STM32任意键薄膜键盘代码
  9. yolov5部署以及训练10种中药材分类数据集
  10. 如何提高办公效率?不如试试智能化OA办公系统