我的征尘是星辰大海。。。
The dirt and dust from my pilgrimage forms oceans of stars...
-------当记忆的篇章变得零碎,当追忆的图片变得模糊,我们只能求助于数字存储的永恒的回忆
作者:黄教授
手机视频列表
一个嵌入式开发门外汉的感悟
视频
音频
原始脚本
从 CH9329的坑到 Arduino 的光,一位嵌入式门外汉的 USB 输入设备,顿悟之旅。 最近这两天的折腾,像是一场沉浸式的嵌入式启蒙课。 从抱着 CH9329+CH470模块满怀期待,到最终转向 Arduino Pro Micro,过程里踩过的坑、绕不过的弯,以及最终豁然开朗的认知。 让我突然读懂了 USB 输入设备的底层逻辑,也读懂了嵌入式平民化背后的深层意义。 这段经历无关高深的代码技巧,无关复杂的协议细节,而是关于如何理解设备与系统的对话,关于技术门槛的本质,更关于一次从想当然到懂本质的认知蜕变。 最初听到 CH9329,我和很多新手一样,把它当成一个万能捷径。 淘宝上的详细让我感觉它是串口转 USB 键鼠的完美方案。 无需复杂的底层开发,只需通过官方工具修改配置,就能实现串口指令到 USB 键鼠信号的转换。 我甚至天真的以为,这就是嵌入式开发的轻量化捷径,预期20分钟搞定。 这种想当然很快就被现实狠狠打脸,我有两个想当然的谬误。 首先是对绝对鼠标相对鼠标的认知错误。 我一直以为这两种模式就像开关一样,通过修改串口包的某个模式就能动态切换,就像调节台灯的亮度、切换风扇的档位一样简单。 第二个错误的认知以为这个是需要依赖不同的桌面系统的支持,以为桌面系统才能告知鼠标它的绝对坐标。 首先一个输入设备自己的能力,就像人与人之间的对话,第一句话必须说清楚我们说的是中文还是法语。 操作系统与 USB 设备的握手,本质上也是一次语言定义。 在设备插入的瞬间,枚举阶段,USB 设备必须一次性向操作系统宣告自己的身份。 我是相对鼠标,我发送的是增量坐标,dx、dy。 我是绝对鼠标,我发送的是归一化坐标,0~32767,0~32767。 这个宣告写在 HID 报告描述符,Report Descriptor 里,一旦枚举完成,就再也无法修改。 就像我们一旦约定了对话的语言,就不可能中途突然切换成另一种语言,否则对方只会一脸茫然。 其次,绝对坐标就是输入设备自己维护的一个内部的数据结构。 它是输入设备的选择,桌面系统自己的内部坐标,不可能也没必要告诉输入设备。 这是我认知的输入设备的角色反转。 在此之前,我一直有一个错误的认知,桌面系统是主人,输入设备是仆人。 我以为鼠标的位置由桌面决定,所以绝对坐标是由桌面告诉。 实际上,输入设备才是说话的人,操作系统是听话的人。 就像键盘的逻辑,键盘敲下的是物理按键的扫描码,而不是直接的字符。 如果不告诉操作系统我是美式键盘,它就无法把扫描码0×1一翻译成 A,反而会翻译成法语键盘的 Q,这就是鸡同鸭讲。 同理,绝对鼠标内部维护着0~32767的坐标体系。 它告诉桌面,我现在在100,200,桌面就必须按这个坐标移动指针。 相对鼠标告诉桌面,我向左移动了10个单位,桌面就必须按增量叠加指针位置。 操作系统没有资格纠正输入设备的指令,它唯一的职责是解码和执行。 这个认知的反转是我这两天最深刻的顿悟。 原来我们日常使用的鼠标和键盘从来不是被动接收指令的工具。 而是主动输出信号的独立设备,它们的逻辑核心是自我定义,而非服从安排。 C H 9329的黑盒特性恰恰让我无法直观体会这个核心逻辑,我看不到它内部的坐标计算,看不到它的 HID 描述符定义。 只能依赖第三方工具,这种隔靴搔痒的体验让我对输入设备的理解始终停留在表面。 也正是在这个时候,我开始重新审视 Arduino,这个之前被我当成小孩子玩具的东西。 我对 Arduino 的偏见源于对嵌入式开发的刻板印象。 嵌入式开发是专业门槛极高的领域,需要精通 C C 加加编译器工具链、Bootloader 配置、USB 协议栈,需要调试器、烧录工具、底层驱动开发能力,这些都是普通程序员难以触及的高山。 而 Arduino 作为开发板,是把这些复杂的底层逻辑封装起来,变成了乐高积木,让十几岁的孩子也能做出简单的电子项目。 他把原本需要专业工程师花数月时间功课的 Bootloader 配置、USB 协议栈实现、HID 描述符编写、串口通信调试全部封装成了简单的 API 接口。 更让我震撼的是 Arduino 的原验证价值 正如我之前感慨的,嵌入式开发的核心痛点从来不是代码实现,而是环境配置和底层调试。 一个普通的嵌入式项目,前期80%的时间都花在搭建编译环境、调试驱动、解决兼容性问题上。 而真正用于实现功能的时间只有20%。 但 Arduino 彻底改变了这个比例,它的开发环境一键搭建,烧录方式简单便捷,直接 USB 连接,生态丰富完善,几乎所有的底层问题都被官方解决了。 这让 Arduino 成为了完美的概念验证平台。 无论是验证串口转 USB 的逻辑,还是测试绝对鼠标的坐标映射,亦或是验证 Linux 下,Dev Input 事件的监听,而 do no 都能让我在短短几分钟内完成从想法到实物的转化。 它就像一个嵌入式开发的脚手架,让我们可以专注于核心功能的实现。 它的伟大之处在于打破了嵌入式开发的精英垄断。 在 Arduino 出现之前,嵌入式开发是少数专业工程师的专属领域。 普通程序员甚至爱好者很难触及底层的 USB HID 驱动开发,而 Arduino 用乐高化的开发模式,让每个人都能参与到嵌入式项目中,让硬件动起来变成了一件像写代码一样简单的事情。 这两天的经历也让我对技术通用性有了新的理解。 USB HID 协议作为通用的输入设备协议,看似复杂,本质上是一套通用语言规则。 无论是 CH9329这样的专用芯片,还是 Arduino 这样的开发板,亦或是未来的其他嵌入式设备,都必须遵守这套规则。 技术的通用性本质是规则的统一性。 所有的设备无论多么复杂,最终都要在枚举阶段完成一次语言定义。 这是 USB 协议的铁律,也是输入设备与操作系统对话的基础。 CH9329的坑让我看到了黑盒硬件的局限性,我们无法看透它的内部逻辑,只能依赖官方工具,一旦出现问题往往束手无策。 而 Arduino 的优势恰恰在于它的开源透明,我们可以通过代码看到它的 HID 描述符,看到它的串口通信逻辑,每一个细节都清晰可控。 这种可控性对于技术探索来说,比便捷性更重要。 现在回头看,这两天的折腾其实是一次非常宝贵的认知升级。 我从 CH9329的黑河迷雾中走出来,终于理解了 USB 输入设备的核心逻辑。 输入设备是语言的定义者,操作系统是语言的解码者。 HID 协议是通用的语言规则,枚举阶段的一次性声明是不可违背的铁律。 技术学习从来不是一蹴而就的,而是需要亲手实践的。 很多时候我们对一个技术的误解源于只闻其名,未见其实。 纸上得来终觉浅,踩过坑后悟才深。 说到底,技术的魅力从来不是高深莫测,而是触手可及。
修正脚本
从 CH9329的坑到 Arduino 的光,一位嵌入式门外汉的 USB 输入设备顿悟之旅。 最近这两天的折腾,像是一场沉浸式的嵌入式启蒙课。 从抱着 CH9329+CH470模块满怀期待,到最终转向 Arduino Pro Micro,过程里踩过的坑、绕不过的弯,以及最终豁然开朗的认知。 让我突然读懂了 USB 输入设备的底层逻辑,也读懂了嵌入式平民化背后的深层意义。 这段经历无关高深的代码技巧,无关复杂的协议细节,而是关于如何理解设备与系统的对话,关于技术门槛的本质,更关于一次从想当然到懂本质的认知蜕变。 最初听到 CH9329,我和很多新手一样,把它当成一个万能捷径。 淘宝上的详情让我感觉它是串口转 USB 键鼠的完美方案。 无需复杂的底层开发,只需通过官方工具修改配置,就能实现串口指令到 USB 键鼠信号的转换。 我甚至天真地以为,这就是嵌入式开发的轻量化捷径,预期20分钟搞定。 这种想当然很快就被现实狠狠打脸,我有两个想当然的谬误。 首先是对绝对鼠标、相对鼠标的认知错误。 我一直以为这两种模式就像开关一样,通过修改串口包的某个模式就能动态切换,就像调节台灯的亮度、切换风扇的档位一样简单。 第二个错误的认知是,以为这需要依赖不同的桌面系统的支持,以为桌面系统才能告知鼠标它的绝对坐标。 首先,一个输入设备自己的能力,就像人与人之间的对话,第一句话必须说清楚我们说的是中文还是法语。 操作系统与 USB 设备的握手,本质上也是一次语言定义。 在设备插入的瞬间,枚举阶段,USB 设备必须一次性向操作系统宣告自己的身份。 我是相对鼠标,我发送的是增量坐标,dx、dy。 我是绝对鼠标,我发送的是归一化坐标,0~32767,0~32767。 这个宣告写在 HID 报告描述符,Report Descriptor 里,一旦枚举完成,就再也无法修改。 就像我们一旦约定了对话的语言,就不可能中途突然切换成另一种语言,否则对方只会一脸茫然。 其次,绝对坐标就是输入设备自己维护的一个内部的数据结构。 它是输入设备的选择,桌面系统自己的内部坐标,不可能也没必要告诉输入设备。 这是我认知的输入设备的角色反转。 在此之前,我一直有一个错误的认知,桌面系统是主人,输入设备是仆人。 我以为鼠标的位置由桌面决定,所以绝对坐标是由桌面告诉输入设备。 实际上,输入设备才是说话的人,操作系统是听话的人。 就像键盘的逻辑,键盘敲下的是物理按键的扫描码,而不是直接的字符。 如果不告诉操作系统我是美式键盘,它就无法把扫描码0×01翻译成 A,反而会翻译成法语键盘的 Q,这就是鸡同鸭讲。 同理,绝对鼠标内部维护着0~32767的坐标体系。 它告诉桌面,我现在在100,200,桌面就必须按这个坐标移动指针。 相对鼠标告诉桌面,我向左移动了10个单位,桌面就必须按增量叠加指针位置。 操作系统没有资格纠正输入设备的指令,它唯一的职责是解码和执行。 这个认知的反转是我这两天最深刻的顿悟。 原来我们日常使用的鼠标和键盘从来不是被动接收指令的工具。 而是主动输出信号的独立设备,它们的逻辑核心是自我定义,而非服从安排。 CH9329的黑盒特性恰恰让我无法直观体会这个核心逻辑,我看不到它内部的坐标计算,看不到它的 HID 描述符定义。 只能依赖第三方工具,这种隔靴搔痒的体验让我对输入设备的理解始终停留在表面。 也正是在这个时候,我开始重新审视 Arduino,这个之前被我当成小孩子玩具的东西。 我对 Arduino 的偏见源于对嵌入式开发的刻板印象。 嵌入式开发是专业门槛极高的领域,需要精通 C、C++ 编译器工具链、Bootloader 配置、USB 协议栈,需要调试器、烧录工具、底层驱动开发能力,这些都是普通程序员难以触及的高山。 而 Arduino 作为开发板,是把这些复杂的底层逻辑封装起来,变成了乐高积木,让十几岁的孩子也能做出简单的电子项目。 它把原本需要专业工程师花数月时间攻克的 Bootloader 配置、USB 协议栈实现、HID 描述符编写、串口通信调试全部封装成了简单的 API 接口。 更让我震撼的是 Arduino 的原型验证价值,正如我之前感慨的,嵌入式开发的核心痛点从来不是代码实现,而是环境配置和底层调试。 一个普通的嵌入式项目,前期80%的时间都花在搭建编译环境、调试驱动、解决兼容性问题上。 而真正用于实现功能的时间只有20%。 但 Arduino 彻底改变了这个比例,它的开发环境一键搭建,烧录方式简单便捷,直接 USB 连接,生态丰富完善,几乎所有的底层问题都被官方解决了。 这让 Arduino 成为了完美的概念验证平台。 无论是验证串口转 USB 的逻辑,还是测试绝对鼠标的坐标映射,亦或是验证 Linux 下,Dev Input 事件的监听,而 Arduino 都能让我在短短几分钟内完成从想法到实物的转化。 它就像一个嵌入式开发的脚手架,让我们可以专注于核心功能的实现。 它的伟大之处在于打破了嵌入式开发的精英垄断。 在 Arduino 出现之前,嵌入式开发是少数专业工程师的专属领域。 普通程序员甚至爱好者很难触及底层的 USB HID 驱动开发,而 Arduino 用乐高化的开发模式,让每个人都能参与到嵌入式项目中,让硬件动起来变成了一件像写代码一样简单的事情。 这两天的经历也让我对技术通用性有了新的理解。 USB HID 协议作为通用的输入设备协议,看似复杂,本质上是一套通用语言规则。 无论是 CH9329这样的专用芯片,还是 Arduino 这样的开发板,亦或是未来的其他嵌入式设备,都必须遵守这套规则。 技术的通用性本质是规则的统一性。 所有的设备无论多么复杂,最终都要在枚举阶段完成一次语言定义。 这是 USB 协议的铁律,也是输入设备与操作系统对话的基础。 CH9329的坑让我看到了黑盒硬件的局限性,我们无法看透它的内部逻辑,只能依赖官方工具,一旦出现问题往往束手无策。 而 Arduino 的优势恰恰在于它的开源透明,我们可以通过代码看到它的 HID 描述符,看到它的串口通信逻辑,每一个细节都清晰可控。 这种可控性对于技术探索来说,比便捷性更重要。 现在回头看,这两天的折腾其实是一次非常宝贵的认知升级。 我从 CH9329的黑盒迷雾中走出来,终于理解了 USB 输入设备的核心逻辑。 输入设备是语言的定义者,操作系统是语言的解码者。 HID 协议是通用的语言规则,枚举阶段的一次性声明是不可违背的铁律。 技术学习从来不是一蹴而就的,而是需要亲手实践的。 很多时候我们对一个技术的误解源于只闻其名,未见其实。 纸上得来终觉浅,踩过坑后悟才深。 说到底,技术的魅力从来不是高深莫测,而是触手可及。
back to top