当前位置: 首页 > wzjs >正文

保定外贸网站建设邯郸网站优化公司

保定外贸网站建设,邯郸网站优化公司,wordpress倒计时代码,做网站一个月可以赚多少文章目录 参考资料:一、SPI传输概述二、SPI传输的两种方法2.1 旧方法2.2 新方法 参考资料: 参考资料: 参考内核源码: drivers\spi\spi.c 一、SPI传输概述 SPI控制器的作用是发起与它下面挂接的SPI设备之间的数据传输,那么控制…

文章目录

  • 参考资料:
  • 一、SPI传输概述
  • 二、SPI传输的两种方法
    • 2.1 旧方法
    • 2.2 新方法


参考资料:

参考资料:

  • 参考内核源码: drivers\spi\spi.c

一、SPI传输概述

SPI控制器的作用是发起与它下面挂接的SPI设备之间的数据传输,那么控制器驱动程序的核心就是实现与设备之间的数据传输过程。在内核中,SPI传输的最小单位是spi_transfer,对于一个设备,可以发起多个spi_transfer。这些spi_transfer,会放入一个spi_message里面。每个SPI设备都有一个自己的spi_message,同一个spi_master下的spi_message,放在一个队里。

  • spi_transfer:指定tx_buf、rx_buf、len
	struct spi_transfer {const void	*tx_buf;void		*rx_buf;...}
  • 同一个SPI设备的spi_transfer,使用spi_message来管理:
struct spi_message {struct list_head	transfers; //管理spi_transfer...
}
  • 同一个SPI Master下的spi_message,放在一个队列里:
struct spi_master {...struct list_head		queue;   //存放每个spi_device的spi_message...
}

所以,反过来,SPI传输的流程是:

  • spi_master的队列里取出每一个spi_message
    • spi_message的队里里取出一个spi_transfer
      • 处理spi_transfer

二、SPI传输的两种方法

spi_master结构中,有两个传输函数,函数指针transfer 代表旧方法,函数指针transfer_one代表新方法。

struct spi_master {
...
/* 旧方法 */
int	(*transfer) (struct spi_device *spi, struct spi_message *mesg);
/* 新方法 */
int (*transfer_one)(struct spi_master *master, struct spi_device *spi, struct spi_transfer *transfer);
...
}

2.1 旧方法

在这里插入图片描述
内核传输函数入口spi_sync()

int spi_sync(struct spi_device *spi, struct spi_message *message)
{ret = __spi_sync(spi, message);
}

继续调用__spi_sync(),里面设置了传输完成回调函数spi_complete,如果master->transfer == spi_queued_transfer表示使用新方法,新方法使用内核提供的transfer 函数,它会帮我们把spi_message放入queue并处理。else分支spi_async_locked表示的是旧方法,需要我们自己实现transfer函数,自己管理queue,自己触发传输。spi_async_locked是异步传输,触发传输后马上返回,随后wait_for_completion(&done)等待传输结果。

static int __spi_sync(struct spi_device *spi, struct spi_message *message)
{DECLARE_COMPLETION_ONSTACK(done);int status;struct spi_master *master = spi->master;unsigned long flags;status = __spi_validate(spi, message);if (status != 0)return status;message->complete = spi_complete; //传输完成回调函数message->context = &done;message->spi = spi;SPI_STATISTICS_INCREMENT_FIELD(&master->statistics, spi_sync);SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_sync);/* If we're not using the legacy transfer method then we will* try to transfer in the calling context so special case.* This code would be less tricky if we could remove the* support for driver implemented message queues.*/if (master->transfer == spi_queued_transfer) { //新方法spin_lock_irqsave(&master->bus_lock_spinlock, flags);trace_spi_message_submit(message);status = __spi_queued_transfer(spi, message, false);spin_unlock_irqrestore(&master->bus_lock_spinlock, flags);} else {status = spi_async_locked(spi, message); //老方法,异步传输}if (status == 0) {/* Push out the messages in the calling context if we* can.*/if (master->transfer == spi_queued_transfer) {SPI_STATISTICS_INCREMENT_FIELD(&master->statistics,spi_sync_immediate);SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics,spi_sync_immediate);__spi_pump_messages(master, false);}wait_for_completion(&done); //等待传输结果status = message->status;}message->context = NULL;return status;
}

继续看spi_async_locked(), 它调用__spi_async(), 继续往下,最终调用master->transfer(spi, message),这个就是自己实现的transfer函数。

int spi_async_locked(struct spi_device *spi, struct spi_message *message)
{struct spi_master *master = spi->master;int ret;unsigned long flags;ret = __spi_validate(spi, message);if (ret != 0)return ret;spin_lock_irqsave(&master->bus_lock_spinlock, flags);ret = __spi_async(spi, message);spin_unlock_irqrestore(&master->bus_lock_spinlock, flags);return ret;}static int __spi_async(struct spi_device *spi, struct spi_message *message)
{struct spi_master *master = spi->master;message->spi = spi;SPI_STATISTICS_INCREMENT_FIELD(&master->statistics, spi_async);SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics, spi_async);trace_spi_message_submit(message);return master->transfer(spi, message); //需要自己实现transfer
}

2.2 新方法

在这里插入图片描述
新方法第一步会调用__spi_queued_transfer()spi_message放入队列,然后在调用__spi_pump_messages()压出数据进行处理。流程如上图。

http://www.dtcms.com/wzjs/212699.html

相关文章:

  • 做珠宝商城网站搜索引擎优化培训中心
  • 石家庄网站制作视频全球新闻最新消息
  • 上海闵行网seo诊断书
  • 装饰设计培训项目优化seo
  • 数据库对于做网站的重要性百度站长工具怎么关闭
  • 网站代理访问是什么意思网站seo优化是什么意思
  • wordpress自带主题太原seo自媒体
  • 贵州省安顺市网站建设百度上做推广怎么做
  • 免费课程网站有哪些广州seo网站推广公司
  • 网站建设销售话术推广图片大全
  • 做网站是什么专业时事新闻最新
  • 广告联盟下载app西安网站建设方案优化
  • 网站大改版宁波seo推广方式排名
  • 网站做如何联系百度人工客服电话
  • 搭建一个网站多少钱哈尔滨电脑网络销售公司怎么运作
  • 成都用设计公司网站陕西百度代理公司
  • 深圳做app网站公司零基础学seo要多久
  • wordpress添加媒体上海seo搜索优化
  • 个人网站变现com天堂网
  • 做瞹瞹瞹视频网站比较好网站制作公司
  • 龙岗网站建设_公司推广google官网
  • django做网站和js做网站sem是什么检测分析
  • 最经济 网站建设怎么样才能引流客人进店
  • video.js wordpress搜索关键词排名优化服务
  • 站群系统开发关键词排名是什么意思
  • 湖州网站建设策划推广产品的渠道
  • 免费设计软件网站公司网站建设服务机构
  • 专做展厅设计网站网络运营怎么做
  • 网站的用户注册怎么做怎么搭建属于自己的网站
  • 晋中北京网站建设深圳网络推广渠道