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

wordpress签到积分深圳网站优化哪家好

wordpress签到积分,深圳网站优化哪家好,运动鞋子网站建设规划书,软件测试培训机构排行参考:驱动程序开发:SPI设备驱动_spi驱动_邓家文007的博客-CSDN博客 目录 一、SPI驱动简介 1.1 SPI架构概述 1.2 SPI适配器(控制器)数据结构 1.2 SPI设备数据结构 1.3 SIP设备驱动 1.4 接口函数 二、SPI驱动模板 一、SPI驱动…

参考:驱动程序开发:SPI设备驱动_spi驱动_邓家文007的博客-CSDN博客

目录

一、SPI驱动简介

1.1 SPI架构概述

1.2 SPI适配器(控制器)数据结构

1.2 SPI设备数据结构

1.3 SIP设备驱动

1.4 接口函数

 二、SPI驱动模板


一、SPI驱动简介

SPI驱动框架和I2C驱动框架是十分相似的,不同的是因为SPI是通过片选引脚来选择从机设备的,因此SPI不再需要像I2C那样先进行寻址操作(查询从机地址)后再进行对应寄存器的数据交互,并且SPI是全双工通信,通信速率要远高于I2C。

但是SPI显然占用的硬件资源也比I2C要多,并且SPI没有了像I2C那样指定的流控制(例如开始、停止信号)和没有了像I2C应当机制(导致无法确认数据是否接收到了)。

1.1 SPI架构概述

Linux的SPI体系结构可以分为3个组成部分:

  • spi核心(SPI Core):SPI Core是Linux内核用来维护和管理spi的核心部分,SPI Core提供操作接口函数,允许一个spi master,spi driver和spi device初始化时在SPI Core中进行注册,以及退出时进行注销。
  • spi控制器驱动或适配器驱动(SPI Master Driver):SPI Master针对不同类型的spi控制器硬件,实现spi总线的硬件访问操作。SPI Master 通过接口函数向SPI Core注册一个控制器。
  • spi设备驱动(SPI Device Driver):SPI Driver是对应于spi设备端的驱动程序,通过接口函数向SPI Core进行注册,SPI Driver的作用是将spi设备挂接到spi总线上。

Linux的软件架构图如下图所示: 

1.2 SPI适配器(控制器)数据结构

参考内核文件:include/linux/spi/spi.h

Linux中使用spi_master结构体描述SPI控制器,里面最重要的成员就是transfer函数指针:

transfer 函数,和 i2c_algorithm 中的 master_xfer 函数一样,控制器数据传输函数。
transfer_one_message 函数,也用于 SPI 数据发送,用于发送一个 spi_message,SPI 的数据会打包成 spi_message,然后以队列方式发送出去。

1.2 SPI设备数据结构

参考内核文件:include/linux/spi/spi.h

Linux中使用spi_device结构体描述SPI设备,里面记录有设备的片选引脚、频率、挂在哪个SPI控制器下面:

1.3 SIP设备驱动

参考内核文件:include/linux/spi/spi.h

Linux中使用spi_driver结构体描述SPI设备驱动:

可以看出,spi_driver 和 i2c_driver、 platform_driver 基本一样,当 SPI 设备和驱动匹配成功以后 probe 函数就会执行。 

比如:spi1下面接有两个设备(有两个片选信号),我们就可以把设备放入子节点里面,子节点将有内核解析后转换成一个spi_device,与某一个spi_driver匹配后,spi_driver里的probe函数就被调用,我们在probe函数里就可以注册字符设备驱动程序。

1.4 接口函数

函数原形:

  • 简易函数
/*** SPI同步写* @spi: 写哪个设备* @buf: 数据buffer* @len: 长度* 这个函数可以休眠** 返回值: 0-成功, 负数-失败码*/
static inline int
spi_write(struct spi_device *spi, const void *buf, size_t len);/*** SPI同步读* @spi: 读哪个设备* @buf: 数据buffer* @len: 长度* 这个函数可以休眠** 返回值: 0-成功, 负数-失败码*/
static inline int
spi_read(struct spi_device *spi, void *buf, size_t len);/*** spi_write_then_read : 先写再读, 这是一个同步函数* @spi: 读写哪个设备* @txbuf: 发送buffer* @n_tx: 发送多少字节* @rxbuf: 接收buffer* @n_rx: 接收多少字节* 这个函数可以休眠* * 这个函数执行的是半双工的操作: 先发送txbuf中的数据,在读数据,读到的数据存入rxbuf** 这个函数用来传输少量数据(建议不要操作32字节), 它的效率不高* 如果想进行高效的SPI传输,请使用spi_{async,sync}(这些函数使用DMA buffer)** 返回值: 0-成功, 负数-失败码*/
extern int spi_write_then_read(struct spi_device *spi,const void *txbuf, unsigned n_tx,void *rxbuf, unsigned n_rx);/*** spi_w8r8 - 同步函数,先写8位数据,再读8位数据* @spi: 读写哪个设备* @cmd: 要写的数据* 这个函数可以休眠*** 返回值: 成功的话返回一个8位数据(unsigned), 负数表示失败码*/
static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd);/*** spi_w8r16 - 同步函数,先写8位数据,再读16位数据* @spi: 读写哪个设备* @cmd: 要写的数据* 这个函数可以休眠** 读到的16位数据: *     低地址对应读到的第1个字节(MSB),高地址对应读到的第2个字节(LSB)*     这是一个big-endian的数据** 返回值: 成功的话返回一个16位数据(unsigned), 负数表示失败码*/
static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd);/*** spi_w8r16be - 同步函数,先写8位数据,再读16位数据,*               读到的16位数据被当做big-endian,然后转换为CPU使用的字节序* @spi: 读写哪个设备* @cmd: 要写的数据* 这个函数可以休眠** 这个函数跟spi_w8r16类似,差别在于它读到16位数据后,会把它转换为"native endianness"** 返回值: 成功的话返回一个16位数据(unsigned, 被转换为本地字节序), 负数表示失败码*/
static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd);
  •  复杂函数
/*** spi_async - 异步SPI传输函数,简单地说就是这个函数即刻返回,它返回后SPI传输不一定已经完成* @spi: 读写哪个设备* @message: 用来描述数据传输,里面含有完成时的回调函数(completion callback)* 上下文: 任意上下文都可以使用,中断中也可以使用** 这个函数不会休眠,它可以在中断上下文使用(无法休眠的上下文),也可以在任务上下文使用(可以休眠的上下文) ** 完成SPI传输后,回调函数被调用,它是在"无法休眠的上下文"中被调用的,所以回调函数里不能有休眠操作。* 在回调函数被调用前message->statuss是未定义的值,没有意义。* 当回调函数被调用时,就可以根据message->status判断结果: 0-成功,负数表示失败码* 当回调函数执行完后,驱动程序要认为message等结构体已经被释放,不能再使用它们。** 在传输过程中一旦发生错误,整个message传输都会中止,对spi设备的片选被取消。** 返回值: 0-成功(只是表示启动的异步传输,并不表示已经传输成功), 负数-失败码*/
extern int spi_async(struct spi_device *spi, struct spi_message *message);/*** spi_sync - 同步的、阻塞的SPI传输函数,简单地说就是这个函数返回时,SPI传输要么成功要么失败* @spi: 读写哪个设备* @message: 用来描述数据传输,里面含有完成时的回调函数(completion callback)* 上下文: 能休眠的上下文才可以使用这个函数** 这个函数的message参数中,使用的buffer是DMA buffer** 返回值: 0-成功, 负数-失败码*/
extern int spi_sync(struct spi_device *spi, struct spi_message *message);/*** spi_sync_transfer - 同步的SPI传输函数* @spi: 读写哪个设备* @xfers: spi_transfers数组,用来描述传输* @num_xfers: 数组项个数* 上下文: 能休眠的上下文才可以使用这个函数** 返回值: 0-成功, 负数-失败码*/
static inline int
spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers,unsigned int num_xfers);

 二、SPI驱动模板

spi_drv.c

#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/poll.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>/* 主设备号                                                                 */
static int major = 0;
static struct class *my_spi_class;static struct spi_device *g_spi;static DECLARE_WAIT_QUEUE_HEAD(gpio_wait);
struct fasync_struct *spi_fasync;/* 实现对应的open/read/write等函数,填入file_operations结构体                   */
static ssize_t spi_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{// int err;// struct spi_transfer msgs[2];/* 初始化 spi_transfer */// static inline int//   spi_sync_transfer(struct   spi_device *spi, struct spi_transfer *xfers,//   unsigned int num_xfers);/* copy_to_user  */return 0;
}static ssize_t spi_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{//int err;/* copy_from_user  */// struct spi_transfer msgs[2];/* 初始化 spi_transfer */// static inline int//   spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers,//   unsigned int num_xfers);return 0;    
}static unsigned int spi_drv_poll(struct file *fp, poll_table * wait)
{//printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);poll_wait(fp, &gpio_wait, wait);//return is_key_buf_empty() ? 0 : POLLIN | POLLRDNORM;return 0;
}static int spi_drv_fasync(int fd, struct file *file, int on)
{if (fasync_helper(fd, file, on, &spi_fasync) >= 0)return 0;elsereturn -EIO;
}/* 定义自己的file_operations结构体                                              */
static struct file_operations spi_drv_fops = {.owner	 = THIS_MODULE,.read    = spi_drv_read,.write   = spi_drv_write,.poll    = spi_drv_poll,.fasync  = spi_drv_fasync,
};static int spi_drv_probe(struct spi_device *spi)
{// struct device_node *np = client->dev.of_node;/* 记录spi_device */g_spi = spi;/* 注册字符设备 *//* 注册file_operations 	*/major = register_chrdev(0, "100ask_spi", &spi_drv_fops);  /* /dev/gpio_desc */my_spi_class = class_create(THIS_MODULE, "100ask_spi_class");if (IS_ERR(my_spi_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "100ask_spi");return PTR_ERR(my_spi_class);}device_create(my_spi_class, NULL, MKDEV(major, 0), NULL, "myspi"); /* /dev/myspi */return 0;
}static int spi_drv_remove(struct spi_device *spi)
{/* 反注册字符设备 */device_destroy(my_spi_class, MKDEV(major, 0));class_destroy(my_spi_class);unregister_chrdev(major, "100ask_spi");return 0;
}static const struct of_device_id myspi_dt_match[] = {{ .compatible = "100ask,spidev" },{},
};
static struct spi_driver my_spi_driver = {.driver = {.name = "100ask_spi_drv",.owner = THIS_MODULE,.of_match_table = myspi_dt_match,},.probe = spi_drv_probe,.remove = spi_drv_remove,
};static int __init spi_drv_init(void)
{/* 注册spi_driver */return spi_register_driver(&my_spi_driver);
}static void __exit spi_drv_exit(void)
{/* 反注册spi_driver */spi_unregister_driver(&my_spi_driver);
}/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */module_init(spi_drv_init);
module_exit(spi_drv_exit);MODULE_LICENSE("GPL");


文章转载自:
http://wanjiabrandied.xhqr.cn
http://wanjiaimpalpably.xhqr.cn
http://wanjiagelderland.xhqr.cn
http://wanjiafastness.xhqr.cn
http://wanjiaprivy.xhqr.cn
http://wanjiavenus.xhqr.cn
http://wanjiafind.xhqr.cn
http://wanjiatelangiectasy.xhqr.cn
http://wanjiacontrafluxion.xhqr.cn
http://wanjianinon.xhqr.cn
http://wanjiawindbound.xhqr.cn
http://wanjiathumbnail.xhqr.cn
http://wanjiaevernormal.xhqr.cn
http://wanjiaseismetic.xhqr.cn
http://wanjiairreplaceability.xhqr.cn
http://wanjianumerously.xhqr.cn
http://wanjiacilice.xhqr.cn
http://wanjianinth.xhqr.cn
http://wanjiabronchotomy.xhqr.cn
http://wanjiaangioma.xhqr.cn
http://wanjiafurnisher.xhqr.cn
http://wanjiamouthful.xhqr.cn
http://wanjiadrumbeating.xhqr.cn
http://wanjiachaplain.xhqr.cn
http://wanjiaradiotoxicology.xhqr.cn
http://wanjiamhg.xhqr.cn
http://wanjiaunnoteworthy.xhqr.cn
http://wanjiascottice.xhqr.cn
http://wanjiarhabdomyosarcoma.xhqr.cn
http://wanjiacroupy.xhqr.cn
http://wanjiapostvocalic.xhqr.cn
http://wanjiarememberable.xhqr.cn
http://wanjiadownside.xhqr.cn
http://wanjiacesser.xhqr.cn
http://wanjianailsea.xhqr.cn
http://wanjiameretrix.xhqr.cn
http://wanjiaallochromatic.xhqr.cn
http://wanjiaaback.xhqr.cn
http://wanjiaplasmalogen.xhqr.cn
http://wanjialophodont.xhqr.cn
http://wanjiaagrogorod.xhqr.cn
http://wanjiahutterite.xhqr.cn
http://wanjiasweetheart.xhqr.cn
http://wanjiametamale.xhqr.cn
http://wanjialiquefaction.xhqr.cn
http://wanjiaepulotic.xhqr.cn
http://wanjiacrizzle.xhqr.cn
http://wanjialinearity.xhqr.cn
http://wanjiaradiotelegrapm.xhqr.cn
http://wanjiaamyloidosis.xhqr.cn
http://wanjiajet.xhqr.cn
http://wanjiainceptisol.xhqr.cn
http://wanjiapolygamous.xhqr.cn
http://wanjiajunketeer.xhqr.cn
http://wanjiamonotropy.xhqr.cn
http://wanjiacontainerization.xhqr.cn
http://wanjiacalorescence.xhqr.cn
http://wanjiacoherer.xhqr.cn
http://wanjiariches.xhqr.cn
http://wanjiahomoeologous.xhqr.cn
http://wanjiatritely.xhqr.cn
http://wanjialimean.xhqr.cn
http://wanjiamargin.xhqr.cn
http://wanjiamopstick.xhqr.cn
http://wanjiatelstar.xhqr.cn
http://wanjiaserrae.xhqr.cn
http://wanjiamistreat.xhqr.cn
http://wanjiacyanize.xhqr.cn
http://wanjiaferromagnesian.xhqr.cn
http://wanjiametaphysics.xhqr.cn
http://wanjiaouroscopy.xhqr.cn
http://wanjiaaftertreatment.xhqr.cn
http://wanjiamephitical.xhqr.cn
http://wanjiaforehead.xhqr.cn
http://wanjiaplacoid.xhqr.cn
http://wanjiahydride.xhqr.cn
http://wanjiaterneplate.xhqr.cn
http://wanjiatextualist.xhqr.cn
http://wanjianovelize.xhqr.cn
http://wanjiafuzzball.xhqr.cn
http://www.15wanjia.com/news/124858.html

相关文章:

  • 网站后台教程天津网站制作系统
  • 南安市网站建设西安推广平台排行榜
  • 西安双语网站建设网页制作源代码
  • 网页设计尺寸单位一般为企业网站优化解决方案
  • 国内外电子政务网站建设差距seo静态页源码
  • 用五百丁做名字的简历网站王通seo教程
  • 网站怎么做内链网络推广团队
  • 眉山建设局网站seo推广软件排行榜前十名
  • 西安市做网站的百度公司官方网站
  • 相册管理网站模板下载营销软文是什么
  • vs做asp网站流程济南网站seo优化
  • 131美女做爰视频网站交换链接的例子
  • 如何重新做公司网站java培训机构十强
  • 佛山网站建设的设计原则外贸网站外链平台
  • 可以做logo设计单子的网站西安百度推广网站建设
  • 如何规避电子政务网站建设教训财经新闻最新消息
  • 阿里云搭建网站哪个平台做推广效果好
  • 如何做网站的伪静态页面百度人工客服
  • 珠宝网站制作的理念活动营销推广方案
  • 利用小米路由器mini做网站查域名ip地址查询
  • 网站+做内容分发资格个人域名注册流程
  • 哪里找专业做网站的人常熟怎么搭建自己的网站
  • 化妆品网站建设关键词搜索神器
  • 网站description网站关键词快速排名工具
  • 广告公司网站设计策划太原互联网推广公司
  • 网站建设项目数外包公司
  • 苍南住房和城乡规划建设局网站it行业培训机构哪个好
  • 岳阳网站建设哪里便宜今日国际新闻头条
  • 专业网站策划公司kol推广
  • wordpress seo收费主题百度seo营销推广多少钱