当前位置: 首页 > 科技观察

你确定你的司机有问题吗?

时间:2023-03-12 19:55:21 科技观察

作者|赵庆尧审稿人|孙淑娟在Android驱动的开发中,定位了很多开发同事反馈的问题后,发现这些问题大多不是驱动本身的问题,而是开发者对驱动框架的了解不够透彻。.例如,有的开发者烧入硬件板的镜像不包含任何驱动信息,有的开发者在本地代码中没有对应的设备驱动。在这两种情况下,一些刚接触驱动的开发人员已经开始基于硬件环境进行调试了。此时他们的硬件环境中没有对应的设备驱动,设备100%不能工作。然而,没有经验的开发人员甚至可能会花几天时间来解决设备无法工作的原因。为了防止这种低端问题再次出现,我整理了一份驱动检查表。主要内容如下:你当前的软件代码中是否有设备对应的驱动和设备树信息如果没有驱动和设备树,如何处理如何保证你的驱动和设备树已经存在编译正常如何保证你的镜像包含正确的驱动和设备树如何保证在烧录镜像后的硬件环境中,有对应的驱动和设备树信息。以上五项环环相扣。只有上一步正确,才能进行下一步。对于初级开发者,强烈建议按照以上步骤进行开发调试,因为很多初级开发者不能像高级开发者那样,从机器状态和节点信息中快速推断出可能存在问题的模块或链接。接下来,我将详细描述如何确认每个链接。1.驱动和设备树信息的确认和获取对于Android机型,项目中使用的大部分设备的驱动和设备树都需要从设备厂的FAE获取,比如指纹、LCD、传感器、NFC等.我们得到这类设备的设备树和驱动后,就可以结合硬件原理图对设备树进行适配,将驱动和设备树放到本地代码对应的位置,然后进行编译配置。除了上述几类设备,还有一类设备,如SD卡驱动、按键驱动、指示灯驱动等,会随着平台的基线发布(高通、展锐、MTK等),但也有例外。最近在做MTK平台的项目,发布的baseline没有包含某个功能的驱动。最后向MTK平台要了驱动代码,然后调试功能。对于一些特殊的定制功能,可能没有供应商,平台默认不支持此类功能。在这种情况下,您需要编写自己的驱动程序和设备树。综上所述,如果当前代码缺少对应平台的驱动和设备树,需要通过平台提供的渠道获取,其他驱动可以从设备供应商处获取。那么问题来了,我们如何判断当前代码中是否包含我们需要的驱动和设备树呢?其实对于有经验的工程师来说,通常只看代码就能很快判断出是否缺少驱动或者设备树配置。毕竟,他们已经熟悉了代码实现。但对于新手来说,通常需要了解相应平台下某个模块的代码结构和实现,才能做出判断。以下是我在入门时使用的方法,供新手参考:从睿等提供的渠道获取相应的文档,如下图,是我获取的MTK文档。通过这种方式获得的文件更具权威性。在网上搜索相关的系列教程,网上的内容很多,系列教程的比例比较少。对于需要入门的开发者,尽量找系列教程。向别人请教,有些公司有自己的代码结构,只能通过公司内部渠道进一步了解,或者自己看代码和文档。2.驱动和设备树编译其实编译是一个庞大的系统,但是这篇文章并不打算讲解编译相关的内容,只是用来说明我们的驱动和设备树是否编译。对于驱动程序,编译后会在特定路径下生成相应的中间文件。我们可以通过检查是否有中间文件或者中间文件的时间戳是否更新来确认驱动是否已经编译。下图为中间文件的路径:out/target/product/(项目对应路径)/obj/KERNEL_OBJ/drivers(图中省略个人或项目信息)。对于devicetree,编译后也可以在out路径中找到。下图使用了在设备树编译的中间文件中查找关键字的方法。使用的命令是grep“cd-gpios”。–rn,这里找到的c??d-gpios是SD卡相关功能的设备树中的配置项。从下图中我们可以看到我的SD卡对应的当前devicetree确实已经编译好了,使用的cd检测引脚是GPIO4。如果在devicetree中修改了cddetectionpin,编译后可以重新使用下图的方法来确认修改是否生效。当你发现驱动或设备树没有被编译时,你需要检查配置是否正确。这里需要注意的是,部分公司会对代码进行部分重构,重构后的代码对应的中间文件可能存在于其他路径中,本文只描述上图中的两个标准路径,供大家学习理解.3、修改后的镜像是否包含在镜像中,本质上是打包压缩。因为是压缩的,所以无法使用grep或者其他类似的方法查询图片是否被修改过。要确认是否包含修改后的图像,可以使用反编译。,而大部分平台的代码路径都是在out/host/下用相应的反编译工具编译的,比如反编译dtbo.img(devicetreerelatedimage),就需要用到out/host下的反编译工具mkdtimg和dtc,但是这个方法是不常见,一般我只是用时间戳做简单的判断,刷的时候用最新的镜像。4.判断硬件环境中是否有对应的驱动和设备树信息还要感谢内核的sys架构,我们的驱动和设备树会在/sys/bus下的对应路径下创建对应的节点信息,只有在这个下path只有在对应的总线(如/sys/bus/platform/device和/sys/bus/platform/driver)下可以找到驱动和设备树信息,我们才能开始调试驱动,否则你的驱动调试工作将是徒劳的。如下图所示,在SPI总线(/sys/bus/spi)的drivers路径下可以找到对应的驱动信息和devices下的设备树信息。查找时,首先我们需要知道驱动和设备树对应的总线信息。上图中对应的驱动代码在加载时使用了spi_register_driver函数将对应的驱动注册到spi总线上,所以在spi下的总线上查找对应的信息。如果您在代码中使用platform_driver_register函数,您应该在/sys/bus/platformbus下搜索它。如果使用i2c_register_driver来注册驱动,那么应该在/sys/bus/i2cbus下查找。总之,你的代码中使用的司机注册函数决定了你的司机对应的公交车信息,在对应的公交车下搜索信息即可。如果你的设备树在spi节点下,需要在/sys/bus/spi/device下找到对应的设备树信息。如果你的设备在I2C节点下,需要在/sys/bus/i2c/device下找到对应的设备树信息。总之,节点在设备树中添加的位置决定了你的设备树对应的总线信息,你需要在对应的总线下找到对应的设备信息。5.小结本文不讲任何编写驱动和设备树的编写注意事项或技巧,也不是代码调试技巧,只是讲解代码调试过程中的几个关键点,只有当这些关键点都ok时才在此情况下,就可以开始代码调试了。笔者介绍赵庆尧,51CTO社区编辑,从事驱动开发多年。他的研究兴趣包括安全操作系统和网络安全,并发表了与网络相关的专利。