Linux内核中,SPI和I2C两个子系统的软件架构是一致的,且Linux内核的驱动模型都以bus,driver,device三种抽象对象为基本元素构建起来。下文的分析将主要用这三种抽象对象的创建过程及其相互调用关系和作用来进行说明。

1.      SPI各对象的初始流程

1.1 创建spi_bus_type总线

postcore_initcall(抽象层spi.c中)

bus_register(&spi_bus_type);

class_register(&spi_master_class);

1.2 把板级信息注册到全局链表中

embedsky_evm_dev_cfg(arch_initcall(customize_machine) -->init_machine())

spi1_init

spi_register_board_info(am335x_spi1_slave_info,  ..)

static struct spi_board_info am335x_spi1_slave_info[] = {

{

.modalias      = "smb380",

.platform_data = &Acceleration_sensor,

.irq           = -1,

.mode                  =SPI_MODE_0,

.max_speed_hz  = 120000,

.bus_num       = 2,

.chip_select   = 0,

},

};

list_add_tail(&bi->list, &board_list);//把当前boardinfo放到全局board_list中

list_for_each_entry(master, &spi_master_list, list)//此时spi_master_list中没有内容,故下面两条语句不执行

spi_match_master_to_boardinfo(master, &bi->board_info)

spi_new_device(master, bi);// =spi_alloc_device() + spi_add_device

1.3 创建platform总线上的平台特定spi device

arch_initcall(omap2_init_devices);//创建特定spi device

omap_init_mcspi();// device name: "omap2_mcspi"

omap_mcspi_init

omap_device_build

omap_device_build_ss

omap_device_alloc

omap_device_register

1.4 创建platform总线上的平台特定spi driver

subsys_initcall(具体spi设备驱动文件spi-omap2-mcspi.c中)

platform_driver_probe(&omap2_mcspi_driver, omap2_mcspi_probe);//drive name: "omap2_mcspi",使用name在platform虚拟总线上进行匹配

spi_alloc_master

INIT_WORK(&mcspi->work, omap2_mcspi_work);

spi_register_master

list_for_each_entry(bi, &board_list, list)//根据bi,一个master可以对应多个slave

spi_match_master_to_boardinfo(master, &bi->board_info);

spi_new_device(master, bi);

spi_alloc_device(master)

spi_setup(spi)// spi->master->setup(spi);

spi_add_device ()

1.5 用户创建spi_bus_type上的driver(名字匹配spi master)

module_init(spidev_init);

spi_register_driver(&spidev_spi_driver);//spi device & spi driver匹配(device modalias和driver name相同)后,执行该driver的probe函数

spidev_probe

device_create(..."spidev%d.%d" ..)//spi_driver创建设备:spidevX.Y,让该device的->p->driver_data为spi_device,换言之,spi_driver只是一个桥梁,应用层open spi driver时候获得该device,继而在别的操作如release、read/write时通过该device获取spi_device,即实际让spi工作的只是spi_device,而spi_device也是通过其对应的spi_master进行的,如spi_setup,transfer等。另,spi_master和这里创建的spidevX.Y是放在sys/class/spi_master及sys/class/spidev目录下的,并没有对应的bus和driver。

2.      I2C子系统启动流程

2.1 板级相关的初始化:

包括1)板级信息注册到全局链表__i2c_board_list;

2)注册i2c device到platform总线上。

embedsky_evm_dev_cfg(arch_initcall(customize_machine) -->init_machine())

i2c2_init

omap_register_i2c_bus(3, 100, am335x_i2c_boardinfo2。。

i2c_register_board_info//注册板级i2c信息到__i2c_board_list

omap_i2c_add_bus(bus_id);

omap2_i2c_add_bus(bus_id);

omap_device_build// 创建platform device:"omap_i2c"

omap_device_build_ss

2.2 platform总线上i2c相关driver和device的注册

I2c driver 到platform总线上,该总线上的i2c driver & i2c device匹配后:

I2c adapter device注册到i2c_bus_type总线,i2c client device注册到i2c_bus_type总线

subsys_initcall(omap_i2c_init_driver);

platform_driver_register(&omap_i2c_driver);//以"omap_i2c"名字匹配后调用相关probe

omap_i2c_probe

//omap i2c 本身的一些初始化

//设置i2c板级特定信息到该driver对应的device上,比如slave对应的adapter(master),设置该adapter的algo

i2c_add_numbered_adapter

i2c_add_adapter(adap);

i2c_register_adapter(adap);//把adapter device(device类型为i2c_adapter_type)注册到i2c_bus_type上,该总线以id进行匹配

__process_new_adapter

i2c_do_add_adapter

i2c_detect(adap, driver);

i2c_detect_address(temp_client, driver);

i2c_new_device(adapter, &info);//把client(device类型为i2c_client_type)注册到i2c_bus_type上

2.3 i2c使用者

用户新建并注册i2c driver到i2c_bus_type上,通过id和i2c client device(板级信息中的type字段)匹配后调用用户新建driver的probe函数。

同样的,作为master的adapter抽象为一个device,挂载到i2c_bus_type总线上,但是没有相应的driver与之匹配,因为数据流是上层用户如这里的i2c使用者创建的driver call对应的client device,该client device有与之匹配的adapter device。一般情况下,driver的目的是让上层用户调用对应device拥有的接口,这里的i2c adapter和i2c client是同级,只需要client有对应adapter的连接通路,adapter自己就不需要自己的driver。这种方式和spi子系统是一样的:

1) driver的作用是作为暴露在外部的接口,内部的实际操作放置于device中;

2) 对于硬件上存在master和slave概念的驱动,device中也会包括master和slave两个device,且这两个device之间互相联系(使用结构体中的指针)。

3.      从文件角度看spi/i2c子系统的地位及其构成

Linux内核中SPI/I2c子系统剖析的更多相关文章

  1. Linux内核中SPI总线驱动分析

    本文主要有两个大的模块:一个是SPI总线驱动的分析 (研究了具体实现的过程): 另一个是SPI总线驱动的编写(不用研究具体的实现过程). 1 SPI概述 SPI是英语Serial Peripheral ...

  2. linux内核中的MFD子系统

    分析用的内核版本为5.1.3 1.MFD全称 Multi-function Device,多功能设备 2. 为何会出现MFD子系统 由于出现了一类具有多种功能的外围设备或cpu内部集成的硬件模块 3. ...

  3. KSM剖析——Linux 内核中的内存去耦合

    简介: 作为一个系统管理程序(hypervisor),Linux® 有几个创新,2.6.32 内核中一个有趣的变化是 KSM(Kernel Samepage Merging)  允许这个系统管理程序通 ...

  4. 剖析linux内核中的宏---------container_of

    #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); ...

  5. Linux内核中的GPIO系统之(3):pin controller driver代码分析

    一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...

  6. Linux内核中的GPIO系统之(3):pin controller driver代码分析--devm_kzalloc使用【转】

    转自:http://www.wowotech.net/linux_kenrel/pin-controller-driver.html 一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道 ...

  7. Linux内核调用SPI平台级驱动_实现OLED的显示功能

    Linux内核调用SPI驱动_实现OLED显示功能 0. 导语 进入Linux的世界,发现真的是无比的有趣,也发现搞Linux驱动从底层嵌入式搞起真的是很有益处.我们在单片机.DSP这些无操作系统的裸 ...

  8. Linux 内核中的 Device Mapper 机制

    本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...

  9. [转] Linux 内核中的 Device Mapper 机制

    本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...

随机推荐

  1. ajax请求遇到服务器重启或中断

    常会有不断轮询发送ajax请求,处理一些业务的场景. 要考虑到: 1. 服务器重启,中断,恢复后仍然能恢复正常业务处理. 服务器重启过程中,再次发送请求,请求状态将变为net::ERR_CONNECT ...

  2. 结合rpyc使用python实现动态升级的方法

    动态升级,就是程序不退出的情况下,将其代码更新的策略.假设集群含有多个机器,然后每个机器部署一套程序,当升级的时候就要去所有的上面部署一把. (1)有个包装程序专门负责接口并检查是否需要更新,当需要更 ...

  3. Bridage

    对于有两个以上的维度的对象,如下图:这张图的业务逻辑是这样的,Hayes,USR以及Emie都是上网的猫,现在有两条线路,一条是传统Dial,还有一条线路是专线,不需要拨号,这样每创建一种线路就意味着 ...

  4. Objective-C的反射

          我第一次接触Java的时候就觉得整个反射包都很新颖,它使得Java和解释型的脚本语言更接近了,与此同时也拉开了和主流的C和C++的距离.在运行时可以窥视到一个对象的类元数据真的很不可思议, ...

  5. CSS样式的优先级

    1.相同权值情况下,CSS样式的优先级总结来说,就是--就近原则(离被设置元素越近优先级别越高): 内联样式表(标签内部)> 嵌入样式表(当前文件中)> 外部样式表(外部文件中). 2.权 ...

  6. POJ 2260(ZOJ 1949) Error Correction 一个水题

    Description A boolean matrix has the parity property when each row and each column has an even sum, ...

  7. UVa816 Abbott's Revenge

    Abbott's Revenge Time limit: 3.000 seconds Abbott’s Revenge  Abbott’s Revenge The 1999 World FinalsC ...

  8. RAM和DDR

    DDR内存现在渐渐成为内存市场中新的宠儿,因其合理的性价比从其诞生以来一直受到人们热烈的期望,希望这一新的内存产品全面提升系统的处理速度和带宽,就连对Rambus抱有无限希望的Intel公司也向外界宣 ...

  9. 最详细的JavaScript和事件解读

    与浏览器进行交互的时候浏览器就会触发各种事件.比如当我们打开某一个网页的时候,浏览器加载完成了这个网页,就会触发一个 load 事件:当我们点击页面中的某一个“地方”,浏览器就会在那个“地方”触发一个 ...

  10. Google网页搜索

    本博文的主要内容有 .Google网页搜索的介绍 .Google网页搜索的使用偏好设置 .Google网页搜索的普通搜索 .Google网页搜索的高级搜索 .Google高级搜索之一:布尔逻辑搜索   ...