随着NVIDIA Jetson平台的不断发展,尤其是在JetPack 6.2版本发布后,Jetson Orin系列开发套件对GPIO(通用输入输出)的处理方式出现了一些显著变化。默认情况下,GPIO仅支持输入功能,这对许多嵌入式开发者来说既是挑战也是机会。要解决这一问题,设备树覆盖(Device Tree Overlays)成为了重要的工具。设备树覆盖看似复杂和吓人,但深入理解后却非常有趣且实用。设备树是一种描述硬件布局的机制,旨在告诉Linux内核硬件各部分所处的位置及其配置信息。在嵌入式系统中,每块开发板的硬件设计各不相同,因此其设备树也必然不同。
简单来说,设备树是一张硬件“地图”,它将硬件资源名称映射到具体的物理地址和寄存器。通常设备树源文件(扩展名.dts)经过设备树编译器(dtc)编译后生成设备树二进制文件(扩展名.dtb),由内核加载使用。针对复杂或部分硬件变更,修改整个设备树存在较大风险,设备树覆盖技术允许在不更改基础设备树的前提下,动态添加或修改设备信息,极大简化了开发过程。设备树覆盖文件(扩展名.dtbo)是一段附加的设备树代码,能在系统启动时被加载,实现对原设备树的有效补充。Jetson Orin Nano开发板的基础设备树源代码约有1100行,覆盖大量硬件和信号资源。因此,设备树覆盖的作用不仅仅是方便,更是保障系统稳定运行和快速定位问题的利器。
Linux内核通过设备树将硬件信号与驱动绑定起来。驱动程序通常带有参数,设备树会为驱动提供必要的配置细节。例如,GPIO针脚会被绑定至tegra-gpio模块,该模块管理其输入输出状态和相关控制信号。但由于Jetson平台信号复杂,单个针脚可能涵盖多个功能且通过多路复用器(pinmux)进行信号路由,理解设备树中信号如何命名和映射非常关键。信号推广时既涉及SoC芯片内部也牵涉模块PCB底层,继而到载板(Carrier Board)上的接口,名称与地址层层递进,稍有不慎便会陷入混淆。Jetson框架中,SoC采用球栅阵列(BGA)封装,通过大量引脚连接到模块,再由模块的260针连接器与载板相连。
该传输过程利用多路复用器实现信号选择与切换。多路复用器允许多个输入信号共享单一输出,但任何时刻只允许一个信号通过。对于开发者而言,理解并正确配置多路复用是正确驱动硬件的关键。Jetson软件平台提供了一个名为jetson-io的工具,可供用户在一定范围内配置40针扩展头、CSI摄像头接口及M.2 Key E插槽的信号功能。该工具本身涵盖了部分典型功能选项,如I2S、SPI、UART及PWM等接口的启用,为非深度内核开发者提供了相对便捷的外围硬件配置方式。然而,当需求超出jetson-io支持的范围,例如自定义GPIO配置或扩展固件功能时,设备树覆盖就成为不可或缺的方案。
了解并掌握Jetson Orin的引脚复用表(pinmux spreadsheet),是深入定制设备树的基础。该表详细列举了载板上所有信号的设备树引脚名称,以及对应的硬件功能。虽然信息量大且复杂,但对于准确定位和配置信号至关重要。而且JetsonHacks社区整理的开源资源,包括官方提供的内核源码和引脚头文件,有助于开发者快速查找与调整配置。针对例如将特定引脚(如扩展头的第7脚)由默认输入模式切换为支持输出功能的例子,可以通过编写相应的.dts覆盖文件,并将enable-input参数设置成允许输出,实现GPIO双向控制。此外,设备树覆盖不仅允许单个引脚的调整,也支持多个引脚同时配置,只需在覆盖文件中定义对应节点并保持结构正确即可。
值得注意的是,不同型号Jetson(如Orin Nano与Orin AGX)的设备树结构和引脚定义存在差异,开发者应结合具体的硬件版本,使用对应的设备树源码和pinmux表进行配置,以避免因版本或硬件差异导致的兼容问题。对于开发者而言,设备树覆盖除了是硬件配置的必备技能,更是理解系统底层运作机制的窗口。通过掌握设备树覆盖,能够更灵活地控制Jetson开发板的GPIO、接口以及外设功能,实现高度定制化系统需求。虽然设备树的庞大信息量和多层级关联可能令初学者望而生畏,但每个部分的原理并不复杂。结合丰富的社区资源和官方文档,逐步深入设备树覆盖的实践应用,将极大提升嵌入式开发的自信和效率。总之,设备树覆盖为Jetson开发者提供了一条通往“金属层”硬件控制的捷径,在硬件资源多样复杂的嵌入式领域中,每一次对设备树的探索与改写都是一次宝贵的成长经历。
掌握设备树覆盖,不但能解决实际的GPIO和外设访问问题,更能为实现自定义硬件方案打下坚实基础。随着NVIDIA不断优化JetPack平台和Jetson生态,设备树覆盖技术必将在未来的嵌入式AI开发中发挥更加重要的作用。