自定义 tty 线路规则驱动程序
据我所知,在 Linux 中执行此操作的一种方法是发送至write a custom tty line discipline kernel driver,它实现了 Linux LED API 并将命令发送到串行端口。然后 Linux LED 代码可以在内核驱动程序中,但它不绑定到特定的串行端口。
然后,要将其链接到特定的串行端口,用户空间程序将打开串行端口,并使用ioctl(serial_fd, TIOCSETD, ...) 调用将串行端口附加到自定义线路规则驱动程序。线路纪律司机从那时起完成所有工作。用户空间程序的唯一目的实际上是将自定义线路规则驱动程序与正确的串行设备相关联。
使用 FUSE 文件系统的伪驱动程序
另一种方法是编写一个“伪驱动程序”的用户空间程序,它连接到串行设备,并提供类似于 Linux 内核 LED 类 API 的 LED API,但在不同的位置,使用 @ 987654322@.
例如,该程序可能被命名为foo-serial-leds,它可以在/var/run/foo-serial-leds/ 下提供许多LED,其API 类似于Linux 内核LED 类驱动程序。
然后另一个程序可以通过写入来控制 LED。 /var/run/foo-serial-leds/status/brightness。这与控制/sys/class/leds/status/brightness 的真正 Linux 内核 LED 类的程序非常相似,只是文件系统上的位置不同。该程序可以移植到具有不同 LED 设备的另一个平台,只要该程序具有可配置的文件系统路径,用于它想要控制的 LED。
这样做的两个缺点:
- 想要控制 LED 的程序必须足够灵活,以便在不同于普通
/sys/class/leds/ 的位置访问 LED 文件 API
- 这些伪驱动 LED 不能使用 Linux 内核 LED 触发器
允许用户空间创建 LED 设备的自定义驱动程序
另一种选择是编写一个 Linux 内核驱动程序,允许用户空间程序在 Linux 内核 LED 类中创建 LED 设备。驱动程序可以使用configfs 来允许用户空间程序创建LED 设备,然后这些设备将出现在/sys/class/leds/ 下。当 LED 亮度发生变化时,它需要提供一种通知用户空间程序的方法(可能通过自定义 sysfs 属性上的sysfs_notify(),用户空间程序可以poll())。
使用该驱动程序,用户空间程序可以实现 LED API 并写入串行设备以实现 LED 控制。该程序是一种用户空间驱动程序。 IE。它将使用 Linux 驱动程序创建一个或多个 LED 类 LED,并打开串行端口与 LED 硬件通信。当通知有东西写入LED亮度时,需要向串口设备发送相关命令。
然后其他想要控制 LED 的用户空间程序将能够在/sys/class/leds/ 下的通常位置写入 LED 类 API。
Linux 内核 4.10 用户空间 LED 类驱动程序
2017 年 11 月更新:Linux 内核 4.10 添加了用户空间 LED 类驱动程序 uleds。它实现了类似于上面描述的东西。但是,控制是通过设备 /dev/uleds,而不是通过 configfs。
应用应该为它想要创建的每个用户 LED 打开一次字符设备文件/dev/uleds。它应该将一个结构写入文件,该结构指定 LED 的名称。然后它应该从打开的文件句柄中读取,并且将接收一个 int,它指定 LED 的亮度,只要 LED 的亮度被系统中的其他东西改变。如果要创建多个 LED,应用应多次打开 char 设备文件,每个 LED 一次。
当应用程序关闭,/dev/uleds 的打开文件句柄关闭时,用户 LED 将自动移除。