首页/新闻资讯/正文详情

Jetson Orin Nano GPIO配置避坑指南:从devmem到设备树

发布时间:2026/9/25 6:16:27 来源:云帆数科 栏目:资讯中心
Jetson Orin Nano GPIO配置避坑指南:从devmem到设备树
1. 为什么 Jetson Orin Nano 的 GPIO 配置总让人踩坑Jetson Orin Nano 这块板子算力强、功耗低、接口丰富做边缘计算和嵌入式控制的人几乎绕不开它。但真正上手之后你会发现最让人头疼的往往不是跑模型而是点一个灯、读一个按键这种最基础的事。GPIO 配置就是典型代表明明在树莓派上两行代码搞定的事情到了 Orin Nano 上可能折腾一整天都出不来电平变化。问题的根源在于Jetson Orin 系列和传统单片机、甚至和树莓派的 GPIO 体系完全不是一回事。它内部有一个庞大的Pinmux引脚复用控制器几十个引脚每一个都可能在多个功能之间切换比如 UART、I2C、SPI、PWM、GPIO 之间来回复用。上电之后这些引脚到底处于什么状态取决于引导阶段加载的设备树Device Tree和 pinmux 配置。你在用户空间用devmem去写寄存器很可能写的是一个被其他功能占用的引脚或者写完之后被某个驱动重新覆盖了配置。我见过太多人卡在这一步用devmem读出来寄存器值是对的写进去也没报错但万用表一量电平纹丝不动。或者更诡异的是写进去瞬间有变化过一会儿又弹回去了。这些现象背后都是 pinmux 和设备树在“作祟”。这篇内容就是把我自己在 Orin Nano 上反复折腾 GPIO 的经验整理出来从最底层的devmem直接操作寄存器到中间层的 pinmux 配置再到设备树层面的固化方案把整条链路讲清楚。适合已经拿到板子、想用 GPIO 做实际控制、但被各种“玄学”问题卡住的开发者。不管你是刚接触 Jetson 的新手还是从 STM32、RK3568 这类平台转过来的老手这里面的坑和思路都能帮你省下不少时间。2. 先搞清楚 Orin Nano 的 GPIO 体系到底长什么样2.1 从 STM32 和 RK3568 的经验为什么直接套不过来如果你之前玩过 STM32习惯了HAL_GPIO_WritePin这种直接操作或者玩过 RK3568改改设备树就能把触摸屏从竖屏转横屏那你可能会觉得 GPIO 配置无非就是“找到引脚编号设置方向写电平”。但在 Orin Nano 上这套直觉会害了你。STM32 的 GPIO 是相对“扁平”的每个引脚有固定的寄存器地址模式输入、输出、复用、模拟、上下拉、速度这些配置项直接写在对应的寄存器里你配置完就生效没有中间层来干扰。RK3568 虽然也用了设备树和 pinmux但它的 pinmux 配置相对直观Rockchip 的 pinctrl 驱动也比较成熟社区资料多。Orin Nano 的问题在于它用的是 NVIDIA 自己的 Tegra 系列 SoCpinmux 控制器非常复杂。每个引脚的功能选择不是简单的一个寄存器位而是分散在多个寄存器组里而且很多配置在引导阶段就被 Bootloader 和早期内核初始化锁定了。更麻烦的是NVIDIA 的文档虽然全但分散在 TRM技术参考手册、pinmux 表格、设备树绑定文档等多个地方没有一个“从零到一”的完整流程。所以你不能把 STM32 那套“直接写寄存器”的思路直接搬过来也不能完全照搬 RK3568 的设备树改法。Orin Nano 需要你同时理解三层硬件寄存器层、pinmux 配置层、设备树描述层。这三层是层层递进的关系跳过任何一层都可能出问题。2.2 三层结构寄存器、Pinmux、设备树的职责划分我把 Orin Nano 的 GPIO 体系拆成三层来理解这样后面操作的时候思路会清晰很多。第一层是寄存器层。这是最底层的物理寄存器包括 GPIO 控制器的数据寄存器、方向寄存器、中断寄存器等。你可以用devmem直接读写这些寄存器看到最原始的值。这一层的特点是“所见即所得”但前提是 pinmux 已经把这个引脚配置成了 GPIO 功能否则你读写的可能是某个外设的寄存器。第二层是 Pinmux 层。这一层决定了每个物理引脚当前“扮演”什么角色。比如 PIN 某号它可以是 GPIO也可以是 I2C 的 SCL还可以是 PWM 输出。Pinmux 控制器里有一堆寄存器每个引脚对应几个位用来选择功能。这一层的关键在于很多引脚的 pinmux 配置在系统启动时就被设备树里的 pinctrl 节点设定了你在用户空间改起来很麻烦。第三层是设备树层。这是 Linux 内核用来描述硬件拓扑的机制。设备树里会定义每个 GPIO 控制器、每个引脚的功能、默认状态、上下拉等。内核启动时pinctrl 驱动会根据设备树里的配置去初始化 pinmux 和 GPIO。这一层是“固化”配置的地方改完之后重启依然生效。三层的关系可以这样理解设备树告诉内核“这个引脚应该是什么功能”内核通过 pinctrl 驱动去写 pinmux 寄存器pinmux 寄存器把物理引脚连接到 GPIO 控制器然后你才能在寄存器层看到并操作这个 GPIO。任何一层出问题最终表现都是“GPIO 不听话”。2.3 常见误区为什么 devmem 写完了没反应很多人第一次尝试 Orin Nano GPIO都是直接搜到一个寄存器地址然后用devmem写。结果发现写完了没反应或者反应不对。我总结了几种典型情况。第一种是引脚被其他功能占用。比如你想用某个引脚做 GPIO 输出但这个引脚在设备树里被配置成了 I2C 的 SDA。这时候你写 GPIO 数据寄存器实际上写的是一个被 I2C 控制器占用的引脚pinmux 根本没把信号路由到 GPIO 控制器当然没反应。第二种是方向寄存器没设对。Orin Nano 的 GPIO 控制器有独立的方向寄存器默认可能是输入。你只写了数据寄存器但方向还是输入输出驱动根本没使能电平自然不会变。第三种是被内核驱动覆盖。有些引脚被某个驱动比如 LED 驱动、按键驱动接管了你在用户空间改完驱动下一次操作时又给你改回去了。这种“弹回去”的现象特别让人抓狂。第四种是寄存器地址算错了。Tegra 的 GPIO 控制器有多个 bank每个 bank 的基地址不同引脚编号到寄存器的映射也不是线性的。你如果直接拿一个网上搜到的地址去写很可能写到了别的 bank 或者别的寄存器上。理解了这些误区后面的操作就有了方向先确认 pinmux再确认方向最后才是写数据。3. 用 devmem 直接操作寄存器快速验证与调试3.1 找到正确的 GPIO 基地址和引脚编号在 Orin Nano 上GPIO 控制器不是只有一个而是分成了多个 bank。每个 bank 有自己的基地址引脚编号也是全局编号。你要操作某个具体引脚第一步就是找到它属于哪个 bank、对应的全局编号是多少。NVIDIA 的文档里通常会给出一个 GPIO 编号表但那个表是给 40-pin 排针用的。如果你用的是其他接口或者板载引脚就需要查 TRM 里的 GPIO 章节。一个比较实用的方法是看/sys/kernel/debug/gpio这个文件里面列出了当前系统里所有已注册的 GPIO 控制器和它们管理的引脚范围。sudo cat /sys/kernel/debug/gpio输出里会看到类似gpiochip0、gpiochip1这样的条目每个 chip 后面跟着它的基地址和引脚数量。比如gpiochip0: GPIOs 0-31说明这个控制器管理 0 到 31 号引脚。你要操作的引脚全局编号如果是 144那就属于某个后面的 chip。找到 chip 之后基地址可以从设备树或者/proc/iomem里查。不过更直接的办法是看 Tegra 的 GPIO 驱动文档里面会列出每个 bank 的寄存器基地址。以 Orin Nano 为例常见的 GPIO bank 基地址大概是这样的具体值以你的板子和 JetPack 版本为准Bank基地址示例管理引脚范围GPIO_A0x022000000-7GPIO_B0x022100008-15GPIO_C0x0222000016-23.........注意这些地址只是示例不同 JetPack 版本和不同 Orin 型号可能不一样。一定要以你实际系统里/sys/kernel/debug/gpio和设备树里的reg属性为准。3.2 devmem 读写寄存器的正确姿势找到基地址和引脚编号之后就可以用devmem来读写了。devmem是 busybox 里的一个工具用法很简单# 读一个 32 位寄存器 devmem 0x02200000 32 # 写一个 32 位寄存器 devmem 0x02200000 32 0x00000001但这里有几个关键点容易出错。第一偏移量计算。GPIO 控制器的寄存器不是从基地址开始的连续空间而是有固定的偏移。比如数据输出寄存器通常在基地址 0x00方向寄存器在基地址 0x04输入寄存器在基地址 0x08。你要根据 Tegra 的 GPIO 寄存器手册来算偏移。第二位操作。一个 32 位寄存器通常管理 32 个引脚每个引脚占一位。你要操作第 N 号引脚就要操作寄存器的第 N 位。直接写整个寄存器会影响到同 bank 的其他引脚所以通常要先读出来改对应位再写回去。# 假设要设置 bank 基地址 0x02200000 的第 3 位为输出高 # 先读方向寄存器偏移 0x04 devmem 0x02200004 32 # 假设读出来是 0x00000000表示全是输入 # 设置第 3 位为输出0x00000008 devmem 0x02200004 32 0x00000008 # 再写数据寄存器偏移 0x00第 3 位为 1 devmem 0x02200000 32 0x00000008第三上下拉和驱动能力。Tegra 的 GPIO 还有上下拉配置寄存器通常在 pinmux 控制器里而不是 GPIO 控制器里。如果你发现引脚电平不对可能是上下拉没设对。这部分后面讲 pinmux 的时候再说。3.3 实测案例点亮一个 LED 并读取按键我拿手头这块 Orin Nano 做了个最简单的测试用一个 GPIO 输出驱动 LED另一个 GPIO 输入接按键。整个过程记录下来方便你复现。首先确认引脚。我选的是 40-pin 排针上的 PIN 7 和 PIN 11。查 NVIDIA 的 40-pin 映射表PIN 7 对应的是 GPIO09PIN 11 对应的是 GPIO17。然后在/sys/kernel/debug/gpio里找到它们所属的 chip 和全局编号。sudo cat /sys/kernel/debug/gpio | grep -i gpio-假设输出显示 GPIO09 全局编号是 9GPIO17 全局编号是 17都属于 gpiochip0基地址 0x02200000。接下来配置 PIN 7 为输出# 设置方向寄存器第 9 位为 1输出 devmem 0x02200004 32 0x00000200 # 设置数据寄存器第 9 位为 1高电平 devmem 0x02200000 32 0x00000200用万用表量 PIN 7 对地电压应该能看到 3.3V 左右。然后拉低devmem 0x02200000 32 0x00000000电压应该变成 0V。LED 如果接对了会看到亮灭变化。读取按键的话PIN 11 配置为输入方向寄存器对应位清零然后读输入寄存器偏移 0x08# 方向寄存器第 17 位清零 devmem 0x02200004 32 0x00000000 # 读输入寄存器 devmem 0x02200008 32按下按键时对应位会变化。不过这里有个坑如果按键没有外部上拉或下拉读出来的值可能是浮空的忽高忽低。这时候就需要配置内部上下拉而上下拉配置在 pinmux 里不在 GPIO 控制器里。这就是为什么单纯用devmem操作 GPIO 经常不够用。实操心得用devmem做快速验证很方便但每次重启后配置都会丢失而且容易影响到同 bank 的其他引脚。建议只在调试阶段用正式方案还是要走设备树。4. Pinmux 配置让引脚真正变成 GPIO4.1 Pinmux 寄存器在哪里怎么找Pinmux 控制器在 Tegra SoC 里是一个独立的模块有自己的寄存器空间。它的基地址和 GPIO 控制器不一样通常在 TRM 的“Pinmux”章节里有详细说明。以 Orin Nano 为例pinmux 基地址大概在 0x02430000 附近具体以你的手册为准。每个引脚在 pinmux 控制器里对应一组寄存器通常包括功能选择寄存器决定这个引脚是 GPIO 还是其他外设功能。上下拉配置寄存器设置内部上拉、下拉或悬空。驱动能力寄存器设置输出驱动电流大小。输入使能寄存器有些引脚需要单独使能输入。这些寄存器的偏移量和位定义在 TRM 的 pinmux 表格里都能查到。但那个表格非常长几十个引脚每个都有好几页。我的建议是先确定你要用的引脚然后只查那几个引脚的配置不要试图一次看完。4.2 用 devmem 修改 Pinmux 的实操步骤假设我要把某个引脚从默认的 I2C 功能改成 GPIO。首先查 TRM 找到这个引脚的 pinmux 寄存器地址和功能选择位的定义。假设功能选择寄存器地址是 0x02430000 偏移功能值 0 是 I2C1 是 GPIO。# 先读当前值 devmem 0x02430000 32 # 假设读出来是 0x00000000表示当前是 I2C # 改成 GPIO写 0x00000001 devmem 0x02430000 32 0x00000001然后配置上下拉。假设上下拉寄存器在偏移 0x04上拉使能位是第 0 位# 使能上拉 devmem 0x02430004 32 0x00000001改完之后再用devmem去操作 GPIO 控制器应该就能看到效果了。但这里有几个非常容易踩的坑。第一个坑是寄存器写保护。有些 pinmux 寄存器在写之前需要先解锁或者需要特定的写序列。Tegra 的 pinmux 有些寄存器是只读的或者需要先写一个 magic value 才能修改。这个在 TRM 里会有说明但很容易被忽略。第二个坑是功能值不是 0 和 1。不同引脚的功能编码不一样有的引脚 GPIO 功能是 0有的是 1有的是 3。一定要查表确认不能想当然。第三个坑是改完之后被内核覆盖。如果你改的引脚在设备树里被某个驱动声明了内核可能在某个时刻重新初始化 pinmux把你的修改覆盖掉。这种问题在系统启动完成后改可能没事但如果有驱动动态加载就可能出问题。4.3 Pinmux 与 GPIO 的联动关系Pinmux 和 GPIO 的关系可以用一个比喻来理解pinmux 就像是一个“信号路由器”它决定物理引脚上的信号是送到 GPIO 控制器还是送到 I2C 控制器还是送到 PWM 控制器。只有 pinmux 把信号路由到 GPIO 控制器之后你在 GPIO 寄存器里的操作才会反映到物理引脚上。所以正确的操作顺序是先配 pinmux再配 GPIO 方向最后写数据。顺序反了或者漏了任何一步都可能没反应。另外pinmux 还负责上下拉和驱动能力。如果你发现 GPIO 输出高电平但电压只有 1.8V 而不是 3.3V可能是驱动能力没设够或者引脚所在的电压域不对。Orin Nano 的引脚分属不同的电压域有些是 1.8V有些是 3.3V这个在硬件设计时就要确认好。注意事项修改 pinmux 寄存器之前一定要备份原始值。改错了可能导致某个外设不工作甚至系统启动异常。建议先用devmem读出所有相关寄存器的值记录下来出问题了再写回去。5. 设备树配置一劳永逸的固化方案5.1 设备树里 GPIO 和 Pinmux 是怎么描述的用devmem和手动改 pinmux 都只是临时方案重启就没了。真正要在产品里用 GPIO必须通过设备树来固化配置。设备树是 Linux 内核用来描述硬件的它把 GPIO 控制器、pinmux、引脚功能都描述成节点和属性。在 Orin Nano 的设备树里你会看到类似这样的结构gpio: gpio2200000 { compatible nvidia,tegra234-gpio; reg 0x0 0x02200000 0x0 0x10000; gpio-controller; #gpio-cells 2; // ... }; pinmux: pinmux2430000 { compatible nvidia,tegra234-pinmux; reg 0x0 0x02430000 0x0 0x10000; // ... };然后在具体的外设节点里会引用这些控制器。比如你要用一个 GPIO 控制 LED可以这样写leds { compatible gpio-leds; led1 { gpios gpio 9 GPIO_ACTIVE_HIGH; default-state off; }; };这里的gpio引用了 GPIO 控制器9是引脚编号GPIO_ACTIVE_HIGH表示高电平有效。内核启动时gpio-leds 驱动会解析这个节点自动配置 GPIO 方向和初始状态。但这里有个关键问题设备树里只描述了 GPIO 的使用没有描述 pinmux。pinmux 的配置通常在另一个地方叫 pinctrl 节点。你需要确保这个引脚在 pinctrl 里被配置成了 GPIO 功能否则 gpio-leds 驱动操作的时候可能没反应。5.2 修改设备树并编译烧录的完整流程Orin Nano 的设备树修改不像树莓派那样直接改/boot/config.txt就行它涉及到设备树源码DTS的编译和烧录。完整流程大概是这样的。第一步找到你的 JetPack 版本对应的设备树源码。通常在 NVIDIA 的 Linux 内核源码包里路径大概是hardware/nvidia/platform/t23x/下面。Orin Nano 用的是 T234 平台所以找 t23x 相关的目录。第二步找到你要修改的 DTS 文件。Orin Nano 的 DTS 文件通常叫tegra234-p3767-0000-p3509-a02.dts之类的具体名字取决于你的载板型号。你可以从/proc/device-tree/model里看到当前使用的型号。第三步在 DTS 里添加或修改节点。比如你要加一个 GPIO 控制的 LED就在根节点下加一个leds节点引用正确的 GPIO 控制器和引脚编号。同时确认 pinctrl 里这个引脚被配置成了 GPIO。第四步编译设备树。NVIDIA 的源码包里通常有make dtbs之类的命令或者你可以用dtc直接编译dtc -I dts -O dtb -o tegra234-p3767-0000-p3509-a02.dtb tegra234-p3767-0000-p3509-a02.dts第五步把编译好的 DTB 文件放到/boot/目录下替换原来的文件。然后重启系统。第六步重启后检查/sys/kernel/debug/gpio和dmesg确认 GPIO 是否注册成功有没有报错。实操心得修改设备树之前一定要备份原始 DTB 文件。如果改错了导致系统起不来可以用串口或者恢复模式把备份的 DTB 写回去。另外NVIDIA 的 JetPack 版本更新比较频繁不同版本的设备树结构可能有差异建议以你实际使用的版本为准。5.3 用设备树覆盖Overlay快速验证直接改主设备树风险比较大改错了可能系统都起不来。一个更安全的办法是用设备树覆盖Overlay。Overlay 是一种在运行时动态修改设备树的机制你可以在不重新编译整个 DTB 的情况下给系统“打补丁”。Orin Nano 的 JetPack 支持 Overlay你可以在/boot/目录下找到extlinux.conf里面可以配置加载哪些 Overlay。具体步骤是第一步写一个 Overlay 的 DTS 文件比如my-gpio-overlay.dts/dts-v1/; /plugin/; / { fragment0 { target-path /; __overlay__ { my_led { compatible gpio-leds; led1 { gpios gpio 9 GPIO_ACTIVE_HIGH; default-state off; }; }; }; }; };第二步编译成 DTBOdtc -I dts -O dtb -o my-gpio-overlay.dtbo my-gpio-overlay.dts第三步把 DTBO 放到/boot/目录然后在extlinux.conf里添加OVERLAYS /boot/my-gpio-overlay.dtbo第四步重启系统检查 Overlay 是否生效。Overlay 的好处是如果出问题了你只需要把extlinux.conf里的那行删掉重启就恢复了不会影响主设备树。这对于调试阶段非常友好。6. 常见问题与排查技巧实录6.1 GPIO 不响应从现象到根因的排查路径GPIO 不响应是最常见的问题表现可能是写了数据寄存器但电平不变或者电平变了但马上弹回去。我整理了一个排查路径按顺序走一遍基本能定位到问题。现象可能原因排查方法写数据寄存器无反应pinmux 未配置为 GPIO读 pinmux 寄存器确认功能选择位写数据寄存器无反应方向寄存器未设为输出读方向寄存器确认对应位为 1电平变化后弹回被内核驱动覆盖检查dmesg是否有驱动占用该引脚电平变化后弹回上下拉配置冲突读 pinmux 上下拉寄存器电压不对1.8V vs 3.3V电压域不匹配查硬件原理图确认引脚电压域读输入始终为 0 或 1上下拉未配置引脚浮空配置内部上拉或下拉排查的时候建议从 pinmux 开始一层一层往下查。先用devmem读 pinmux 寄存器确认功能选择正确再读 GPIO 方向寄存器确认方向正确最后读数据寄存器和输入寄存器确认数据通路正常。6.2 系统启动黑屏与 GPIO 配置的关联有人可能会遇到 Orin Nano 启动后黑屏的问题然后怀疑是不是 GPIO 配置改坏了。这个关联确实存在但通常不是直接原因。Orin Nano 的显示输出HDMI 或 DP也涉及到 pinmux 配置。如果你在改 pinmux 的时候不小心把显示相关的引脚功能改掉了或者设备树里显示节点的 pinctrl 配置被覆盖了就可能导致黑屏。另外如果你改的设备树有语法错误内核可能无法正确解析导致显示驱动初始化失败。遇到黑屏首先用串口连上去看内核日志。如果串口也没输出可能是引导阶段就出问题了需要用恢复模式重新烧录。如果串口有输出但显示没起来检查dmesg里显示相关的报错看看是不是 pinctrl 冲突。避坑技巧改设备树或 pinmux 之前先把串口调试环境搭好。Orin Nano 的串口在 40-pin 排针上有引出接一个 USB 转串口模块就能用。有了串口即使显示起不来你也能看到内核日志定位问题。6.3 独家避坑清单我踩过的五个坑第一个坑是引脚编号混淆。NVIDIA 的文档里40-pin 排针的引脚编号和 SoC 的 GPIO 全局编号是两套体系。PIN 7 对应的可能是 GPIO09但 GPIO09 的全局编号可能是 9也可能是 400 多。一定要以/sys/kernel/debug/gpio里的实际编号为准。第二个坑是pinmux 寄存器写保护。有些 Tegra 的 pinmux 寄存器需要先写一个解锁序列才能修改直接写会被忽略。这个在 TRM 里有说明但很容易漏看。如果你发现写了没反应先查一下是不是需要解锁。第三个坑是设备树节点顺序。设备树里节点的顺序有时候会影响初始化顺序。如果 pinctrl 节点在 GPIO 节点之后初始化可能导致 GPIO 驱动先操作了引脚然后 pinctrl 又把它改回去了。建议把 pinctrl 节点放在前面。第四个坑是JetPack 版本差异。不同版本的 JetPack设备树结构和 pinmux 寄存器地址可能不一样。网上搜到的教程可能是基于旧版本的直接套用会出问题。一定要以你实际系统的文档为准。第五个坑是忘记配置上下拉。输入引脚如果不配置上下拉读出来的值会飘。输出引脚如果上下拉配置不对可能导致驱动电流过大或过小。上下拉配置在 pinmux 里不在 GPIO 控制器里这点很容易忘。6.4 快速参考表常用寄存器偏移与操作为了方便查阅我把 Orin Nano GPIO 和 pinmux 的常用寄存器偏移整理成表。注意这些是示例值具体以你的 TRM 为准。寄存器偏移示例作用操作要点GPIO 数据输出0x00设置输出电平按位操作避免影响其他引脚GPIO 方向0x04设置输入/输出1 为输出0 为输入GPIO 输入0x08读取输入电平只读GPIO 中断使能0x0C使能中断需要配合中断控制器Pinmux 功能选择0x00选择引脚功能查表确认功能值Pinmux 上下拉0x04配置上下拉注意电压域Pinmux 驱动能力0x08设置驱动电流根据负载选择操作的时候建议先用devmem读出原始值记录下来改完之后再读出来确认。如果出问题可以快速写回原始值恢复。7. 从调试到量产我的实际经验总结折腾 Orin Nano 的 GPIO 这段时间我最大的体会是不要试图跳过任何一层。很多人想直接用devmem搞定结果卡在 pinmux 上或者想直接改设备树结果因为不熟悉 pinctrl 结构而改错。正确的路径是先用devmem验证寄存器和引脚理解 pinmux 的作用然后再用设备树固化。另一个体会是文档和实际系统一定要对照着看。NVIDIA 的 TRM 很全但版本多、更新快你手头的文档可能和实际系统有差异。每次操作前先用/sys/kernel/debug/gpio和/proc/device-tree确认实际状态再动手改。最后分享一个小技巧如果你不确定某个引脚能不能用作 GPIO可以先在设备树里把它配置成 GPIO然后重启看dmesg有没有报错。如果没有报错再用devmem或 sysfs 去操作。如果报错了说明这个引脚被其他驱动占用了需要先解决冲突。这个内容后续还可以这样扩展比如用 libgpiod 在用户空间操作 GPIO比 sysfs 更规范或者用 PWM 控制 LED 亮度涉及 pinmux 和 PWM 控制器的配合再或者用 GPIO 中断做按键响应涉及中断控制器和设备树里的 interrupt-parent 配置。这些都是在 GPIO 基础上进一步深入的方向后面有机会再单独整理。

相关推荐

基于SpringBoot的学生信息管理系统设计与实现
基于SpringBoot的学生信息管理系统设计与实现

一、项目简介随着高校办学规模不断扩大,学生人数、课程数量、教学数据持续递增,传统人工教务管理方式存在效率低、数据零散、统计困难、成绩归档不便等诸多问题。为实现校园教务管理信息化、标准化、高效化,本文设计并实现了基于SpringBootTh… · 2026/9/25 6:16:27

WorkBuddy Skills 生态指南:10 个高星 GitHub 项目安装与避坑
WorkBuddy Skills 生态指南:10 个高星 GitHub 项目安装与避坑

1. 为什么 WorkBuddy 的 Skills 生态值得单独拿出来聊WorkBuddy 这类 Agent 工具真正拉开差距的地方,从来不是模型本身,而是它能不能调用外部能力。Skills 就是这套外部能力的封装单元——你可以把它理解成给 Agent 装的"插件包",每… · 2026/9/25 6:16:21

飞飞CMS安装部署与广告HTML嵌入实战指南
飞飞CMS安装部署与广告HTML嵌入实战指南

做影视类网站也有几年了,飞飞CMS这套系统我从最早开始就在用,中途也接触过苹果CMS、海洋CMS一类的竞品,兜兜转转最后还是把主力站留在了飞飞上。今天不聊虚的,就围绕三个最实在的问题讲透:飞飞CMS怎么安装、怎么在页面… · 2026/9/25 6:16:15

ESP32-C3+RP2040双芯协同:基于SWD的嵌入式OTA与运维代理
ESP32-C3+RP2040双芯协同:基于SWD的嵌入式OTA与运维代理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 7:24:33

MOS管开关电路设计实战:从原理、选型到驱动保护
MOS管开关电路设计实战:从原理、选型到驱动保护

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 7:24:27

BullMQ Pro 分组(Groups)中的沙盒处理器(Sandboxed Processors):gid 与隔离执行实战指南
BullMQ Pro 分组(Groups)中的沙盒处理器(Sandboxed Processors):gid 与隔离执行实战指南

后端消息队列任务调度 【免费下载链接】bullmq BullMQ - Message Queue and Batch processing for NodeJS, Python, .NET, Elixir, Rust and PHP based on Redis or PostgreSQL 项目地址: https://gitcode.com/gh_mirrors/bu/bullmq 点击查看 免费下载 在 BullMQ P… · 2026/9/25 7:24:15

BAML 基准测试 Workload 深度解析:string::split short literal 100k 与字符串 split 性能测试
BAML 基准测试 Workload 深度解析:string::split short literal 100k 与字符串 split 性能测试

编程语言AI Agent编译器CLI人工智能 【免费下载链接】baml The programming language for agents 项目地址: https://gitcode.com/gh_mirrors/ba/baml 点击查看 免费下载 本篇文章以仓库 baml_language/tools/speedtest 中的 Workload 定义文件 split-short-litera… · 2026/9/25 7:24:15

cyrus-sasl 2.1.21编译与配置:从源码包到SMTP/LDAP认证实战
cyrus-sasl 2.1.21编译与配置:从源码包到SMTP/LDAP认证实战

简介:这是Cyrus SASL 2.1.21的源码压缩包,面向邮件系统运维、后端开发及安全测试人员,用于为SMTP/IMAP/POP3等服务搭建可扩展的认证与安全层,重点解决Postfix邮件服务器在发送与接收环节的SASL认证配置问题。资源共620个文件&… · 2026/9/25 7:24:15

python的智能制造导论工业场景模拟第一百一十五篇:搭建离散事件仿真,模拟多品种混线生产,统计在制品库存,评估不同排产策略库存压力。
python的智能制造导论工业场景模拟第一百一十五篇:搭建离散事件仿真,模拟多品种混线生产,统计在制品库存,评估不同排产策略库存压力。

离散事件仿真:多品种混线生产,统计在制品库存,评估不同排产策略库存压力周四上午,生产计划员小刘把三张工单甩在会议桌上,脸色不太好看。"这个月第三条线要同时跑A、B、C三种产品,订单量分别是A 500件… · 2026/9/25 7:24:09

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码