嵌入式软件开发:带你一起认识下Linux总线及代码匹配流程
做嵌入式驱动开发的同学都知道总线这个概念

以bear手机项目为例,我们看下linux下sys文件下注册的总线:

linux sys文件夹下注册的总线
platform总线
platform总线为 linux 自身虚拟出来的一种概念总线,也有 device 和 driver 的概念,分别对
应 platform_device 和 platform_driver。
I2C bus
i2c 总线由于其自身的优势, 上面挂的设备比较多, 在 Bettle 上 i2c 的 source 有 3 根 mt-i2c.0,mt-i2c.1, mt-i2c.2。在 i2c 的驱动中 device 和 driver 分别对应 i2c_client, i2c_driver

以i2c-0 为例上面挂了 i2c-0/0-0018( BMA222E) , i2c-0/0-0026( mtk-tpd) , i2c-0/0-0038(ft5316), i2c-0/0-0039(TMD2771), i2c-0/0-0048( stk3x1x)。
不同的数字表示了不同的设备在 i2c bus0 上的 address,由 i2c_board_info 结构指定,如:Msg_driver.c
static struct i2c_board_info __initdata i2c_tpd={ I2C_BOARD_INFO("mtk-tpd", (0x4c>>1))};
//0x4c>>1 = 26
i2c_register_board_info(0, &i2c_tpd, 1); //0 为 bus number
ft6306_driver.c
static struct i2c_board_info __initdata ft5316_i2c_tpd={ I2C_BOARD_INFO("ft5316",
(0x70>>1))}; //0x70>>1 = 38
i2c_register_board_info(0, &ft5316_i2c_tpd, 1 )
在register driver 的时候, 如果是挂在 BUS 上的 driver 和 device, 都需要一个 match 的过程,match 成功后才能注册。



可知 i2c driver 和 device 的 match 是通过 name 来匹配的(对于挂在 sdio bus 上的 device的 match 是通过 vendor_id 和 device_id 来匹配的, 以下会做说明)。 虽然 i2c 的 match 过程中
是通过 name 来匹配的,但是很多时候还是需要读出 chip id(vendor_id),根据 id 号可以做
一些操作判断。 比如在有备料的时候, 有两套驱动在代码里面, 如何判断实际使用的是那颗controller ic 就需要去读 ic 的 id。如 触摸屏ft6306:

上面可以看到,如果 vendor_id 号不匹配,则直接 mask 中断,关 LDO 。其 中FT5X0X_REG_FT5316ID 寄存器的值应该是由这颗 controller ic 的 datasheet 指定的
SDIO bus
SDIO 接口(卡) 由 SD 接口(卡)发展而来。 现阶段有很多类型的 SDIO 卡( Camera,BT,WLAN等) 。
sdio 驱动中 device 和 driver 对应 sdio_func 和 sdio_driver。和 i2c 一样,也是通过 bus 的match 函数来做匹配。最终是使用下面的函数进行匹配。

以下说明如何读取 sdio_func 中的 vendor_id 和 device_id。通过该过程可以熟悉下 SDIO 的Spec 规范。(以下过程以 yokoto项目为例)

跳过 card detect 部分,直接从 mmc_attach_sdio()开始


SD卡CIS信息

注意上述过程中由于 CMD52 的 response 每次只能返回一个 byte, 故有些时候需要根据 SDIO
spec 的规定,读取一定的次数才能拿到完整的值。最后通过 cistpl_manfid()函数得到vendor=0x2d0 和 device=0x4330 。
上述以最简化的步骤给出了如果读取 sdio card 的 vendor 和 device 号,以保证 chip supplier的代码能够正确地被注册,其中省略了很多读取其他寄存器组的操作。 (参加完整代码和SDIO 的 spec )。

好了,简单介绍了下linux下的i2cbus,sdio bus的匹配过程。详细的代码还需要根据spec去读取linux内核源码。针对有缘人,请佛系阅读,喜欢的话,请三连,后面有时间会多写写Linux内核驱动开发、inux调试及性能优化、嵌入式开发中经常用到的软件开发技能栈,比如netlink、mmap、dma、大数据传输、中断、多线程调度优化等常用必备技能
相关推荐
-
nginx检查提示“unknown directive "stream" in /etc/*/nginx.conf”
nginx检查提示“unknown directive "stream" in /etc/*/nginx.conf”2025-02-26 00:38:21 -
php之多级目录下查找文件中是否含有某个字符串功能实现2025-02-26 00:36:35
-
mysql 启动不了1067错误如何解决?2025-02-26 00:33:31
-
MySQL简单INSERT超慢原因排查2025-02-26 00:22:42
-
mysql分布式数据库的主要构架是什么?2025-02-26 00:06:23