centec cnos spi 驱动调用流程
驱动分层思想
如果直接通过写寄存器的方式进行驱动开发,驱动开发的过程看起来就没那么复杂了,只要读通芯片厂家给的用户手册,或者利用芯片厂家给的例子程序,思路比较清晰。但是这样做的存在的一个问题,就是驱动的可移植和夸平台特性并不好。每换一个平台(cpu)就需要对驱动重新移植,或者每换个cpu也需要对相应的设备(例如SPI设备)驱动做改变。linux为了屏蔽这样的问题,让驱动程序拥有更好的可移植性和跨平台特性,驱动采用了分层的思想来进行设计。下面我们拿I2C和SPI做进一步说明。
core给设备端和adapter的控制器端都提供了通用的接口,这样设备端换个平台(cpu),设备端的驱动不需要做任何修改;同理设备端更换器件,只需调整设备端的驱动,cpu端的控制器部分不需要改变。
对于SPI也是同样,因为I2C驱动和SPI驱动并非是一个人,所以所取的名称有所不同,但是基本的思想是一致的,也是分层的思想,增加了跨平台 可移植能力。I2C驱动,在linux驱动在linux的驱动体系中是一个比较典型的案例,只要能把I2C驱动看懂,在去看spi驱动就很容易理解了。下图为I2C驱动和SPI驱动的对应关系。

注册流程
在系统启动的时候,相应的驱动需要注册到内核中,并在/dev/ 下创建相应的设备文件。以便后续对弈进行open write read 等操作。
spi的注册流程,如下
函数从上往下调用
spidev_init //linux系统初始化的时候调用到
spi_register_driver //注册驱动
driver_register
bus_add_driver 驱动添加函数
driver_attach //遍历没一个设备进行驱动匹配
__driver_attach
driver_match_device drv->bus->match //调用匹配函数做匹配
spi_register_driver-- spi_bus_type--spi_match_device //实际调用的match函数是在这里挂载的。
driver_probe_device
really_probe 调用dev->bus->probe或者drv->probe 应该调用的是 spidev_probe
driver_sysfs_add 应该就是添加了dev下的内容
SPI的读写流程
函数从上往下的调用序列
spidev_ioctl //ioctl 会调用驱动的这个函数
spidev_message
spidev_sync
__spi_async
master->transfer = mpc8xxx_spi_transfer
mpc8xxx_spi_transfer 数据入队列
mpc8xxx_spi_work 数据出队列
spi_do_one_msg
fsl_espi_do_one_msg
fsl_espi_rw_trans
fsl_espi_do_trans
fsl_espi_bufs
fsl_espi_cpu_bufs
mpc8xxx_spi_write_reg //通过写寄存器将数据发送出去。
应用层对改spi的使用调用流程
初始化时创建spi 的 句柄
从上往下的函数调用过程
_lcm_init_e350_48t4xg_clk_gen
ds3104_init
ds3104_register
ds3104_spi_register
spi_create_handle
spi_cpu_create_handle //挂载读写
//ds3104 调用 ds3104_write 去读写操作时,调用了挂载的->write函数,实际上是调用了spi_cpu_write
ds3104_write //调用函数指针 ->write 实际调用的是 spi_cpu_write 写的
spi_cpu_write // 这里通过ioctrl 进入内核的spi驱动执行。
spidev.c - //是内核里边驱动的实现。
ds3104_api.c 定义了ds3104_wirte ds3104_read, 这个两个调用了挂载到spi_cpu.c里的读写函数。我们要实现应该就是实现这个文档。
我们实现也是在system\drvs\device\ 目录下添加新的文件,类似于ds3104_api.c 的文件。
本文深入探讨了SPI驱动的分层设计思想,分析了注册与读写流程,以及应用层如何调用SPI驱动。通过分层设计,提高了驱动的可移植性和跨平台特性。
1154

被折叠的 条评论
为什么被折叠?



