我正在尝试将 OEM 模块集成到运行嵌入式 Linux 的产品中。我只能通过 UART 与模块进行通信,我需要从中获取的最重要的信息是它的温度。
该系统是基于 ARM 的系统,我已经使用 I2C 温度传感器和风扇以及设备树进行了热设计,一切都运行良好。添加这个模块是事情开始变得棘手的地方。 OEM 模块是一个选项,在给定系统中可能存在也可能不存在。硬件需要检测 OEM 模块的存在并加载适当的内核模块/设备树覆盖,以启用已安装硬件的热管理。
这里的困难在于,似乎没有通过 UART 进行通信的热传感器。我找到了 SPI 的驱动程序(LM70)、I2C(LM75)和 1 线(DS18S20)温度传感器,但还没有与 Linux 热子系统结合使用异步串行的先例。
我最初的计划是读取用户空间中的温度并将其写入热子系统。除非您在内核配置中启用 set_emul_temp,否则这是不允许的(有充分的理由)。我不想允许用户空间代码写入我的所有温度传感器,从而覆盖系统的实际温度,因此我正在寻求不同的策略。
计划 2 是编写一个“插入”到具有可写属性的 hwmon 子系统的内核模块。这样,我可以配置热控制方案以使用较高的温度传感器来控制风扇。如果恶意代码覆盖了 OEM 模块温度控制,板载 I2C 传感器仍将正确读取,并且风扇将根据读取的温度运行。当我对此进行深入研究时,我也不确定这是否可能。
最终计划是弄清楚如何在内核模块和用户空间 TTY 驱动程序之间共享 UART。内核模块可以向 hwmon 注册自身,并在访问温度值(4 字节 @ ~900k 波特)时获取设备驱动程序的锁定,从而在不采样温度时使设备保持开放状态以供用户空间应用程序使用。温度值的刷新周期并不是至关重要,只要温度每秒左右更新一次,因此使用该设备的用户空间应用程序就不会造成重大问题,因为系统和 OEM 模块之间的所有传输都会相对地进行。小(>500B)。
我开始根据以下人员编写的几个非常好的指南开发一个内核模块罗伯特·W·奥利弗二世和德里克·莫洛伊。这些使我能够编写一个模块,其中包含写入其中的值以供以后使用。我试图完成的下一个任务是如何将其集成到 hwmon 中。这带我去Linux 硬件监控内核 API。
我遇到的问题是我的 char 设备似乎没有父设备,所以我无法调用devm_hwmon_device_register_with_info
.我似乎也不能注册为 hwmon 设备和 char 设备。我现在正在考虑将我的驱动程序注册为平台驱动程序,module_platform_driver
以便devm_hwmon_device_register_with_info
在内部调用.probe()
。这似乎可能会让我达到这样的地步:我有一个用 hwmon 注册的“设备”,即使我无法写入它。
由于缺乏从用户空间写入设备的方法,我认为我需要直接与串行端口连接作为模块的一部分。这变得更加令人困惑,因为它的定义似乎比 I2C 或 SPI 更不明确。我被引导到锁书之书和线路规则是这里可能的解决方案,但如果这不是正确的路径,我会犹豫是否要深入研究它。
考虑到我列出的限制,我的任何选择似乎都是正确的路径吗?以前有过这样的事情吗?我无法找到任何证据表明有人在我之前解决了这个问题,所以我正在努力了解适合内核设计的细节。如果我可以简单地用更高的速度覆盖风扇速度,那就太好了,但这种功能似乎被锁定在用户空间之外(同样,有充分的理由)。