LINUX SPI设备驱动模型分析之四 SPI 通信接口(spi_sync、spi_async)分析

      上两篇文章完成了spi总线、设备、驱动、master的分析,下面我们分析下spi模块提供的通信方法,通过该通信方法,即可完成cpu与具体spi设备之间的通信(借助spi controller)。

      其实,spi_sync、spi_async的实现也不是太复杂,但是由于在新版内核中,针对spi_sync,spi核心提供了基于worker线程的处理方式,基于该方式则所有spi master均不需要提供spi_transfer接口,而使用spi核心定义的spi_queued_transfer即可。而这两个接口也是与具体的spi master相关联的。

spi_sync、spi_async

       Spi 核心提供两种通信方法spi_sync、spi_async(同步、异步),这两种方法最终均是通过调用__spi_async接口实现数据的通信。

这两个接口的处理流程图如下所示:

  1. 对于同步通信,设置本次传输的spi_message类型变量的complete函数指针指向spi_complete,借助完成量机制,完成spi的同步通信操作(主要借助完成量的complete、wait_for_completion这两个接口,其实这两个接口也就是借助内核的等待队列,根据等待队列的sleep、wakeup实现完成量);
  2. 对于异步通信,则不必执行上述1中的内容;
  3. 对本次通信的spi_message类型变量进行合法性检查,包括spi_message->transfer链表上所有需要输出的spi_transfer类型的数据进行合法性检测、传输速率等信息的合法性检测。
  4. 调用spi控制器的transfer接口,进行数据传输操作。

spi核心提供的spi queue处理方式

针对spi核心提供的spi_sync、spi_async接口,基本上完成上面的框架接口,然后每一个spi_master则通过实现spi_master->transfter接口,即实现了数据通信。但在新版的内核中,spi核心模块又提供了kthread_worker机制,通过为每一个spi控制器创建worker线程,由该worker线程处理该spi总线上所有需要处理的通信数据。

Spi 控制器的worker kthread的创建

  1. 当调用spi_register_master接口注册一个spi控制器,若该控制器支持队列模式,则调用spi_master_initialize_queue接口创建一个worker kthread,同时将master->kworker绑定到该线程生;
  2. 初始化master->pump_messages,用于注册到master->kworker上。

Spi 控制器queue机制的transfer接口

扫描二维码关注公众号,回复: 9646576 查看本文章

针对提供queue机制的spi控制器,其transfer接口均指向spi_queued_transfer,该接口的实现流程如下,主要实现功能如下:

  1. 将该spi_message类型的变量加入到spi->master的queue队列上;
  2. 将master->pump_messages加入到master->kworker上。

当spi_queued_transfer完成将master->pump_messages加入到master->kworker上后,worker kthread线程的处理函数kthread_worker_fn即会从master->kworker上取出一个kthread_work,并调用该变量的func接口,对于spi控制器而言,即为spi_pump_messages接口。该接口的实现功能如下:

  1. 然后调用该master->prepare_transfer_hardware、transfer_one_message接口,完成针对该spi_message类型变量的数据传输,这就由具体控制器的接口来实现相应功能。

       以上便是spi核心提供的基于队列模式(借助LINUX的worker kthread机制)相关的spi核心层提供的接口分析。

此篇文章简要说明了spi_sync、spi_async的实现方式,以及与spi master之间的调用关联。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/103226586
SPI
今日推荐