简体   繁体   English

为串口控制的LED设备制作Linux LED类驱动程序

[英]Making Linux LED class driver for serial port controlled LED device

I have a hardware device that controls LEDs on a panel, and it has a serial port for a PC to control the LEDs.我有一个控制面板上 LED 的硬件设备,它有一个供 PC 控制 LED 的串行端口。

I would like to be able to control the LEDs from a userspace application using the Linux LED class API, ie via /sys/class/leds/whatever/brightness .我希望能够使用 Linux LED 类 API,即通过/sys/class/leds/whatever/brightness从用户空间应用程序控制 LED。 So I'd like to make a Linux kernel driver for this device.所以我想为这个设备制作一个 Linux 内核驱动程序。

However, from what I've read, it seems unusual for a Linux kernel driver to open a serial device.但是,根据我的阅读,Linux 内核驱动程序打开串行设备似乎很不寻常。 Eg StackOverflow question Accessing a serial port from a linux kernel module .例如 StackOverflow 问题Accessing a serial port from a linux kernel module I've read about filp_open() which can be used by kernel drivers to open device files, but its use seems to be discouraged.我读过关于filp_open()内容,内核驱动程序可以使用它来打开设备文件,但似乎不鼓励使用它。

On the other hand, it seems impossible to implement this in userspace because I'm not aware of a way to create a Linux LED class device from userspace.另一方面,在用户空间中实现这一点似乎是不可能的,因为我不知道从用户空间创建 Linux LED 类设备的方法。

What would be a good way to provide a Linux LED class API interface to a serial port controlled LED device?为串行端口控制的 LED 设备提供 Linux LED 类 API 接口的好方法是什么?

  • Disregard the cautions against accessing a serial port from a Linux driver using filp_open() ?忽略使用filp_open()从 Linux 驱动程序访问串行端口的注意事项?
  • Is there some userspace way to create a Linux LED class device, so I could implement this in userspace?有没有一些用户空间的方式来创建一个 Linux LED 类设备,所以我可以在用户空间中实现它?
  • Give up on the idea of using the Linux LEDs class API, and use an alternative API for the userspace application to control the LEDs?放弃使用 Linux LED 类 API 的想法,而使用用户空间应用程序的替代 API 来控制 LED?
  • Other?其他?

Custom tty line discipline driver自定义 tty 线路纪律驱动程序

As far as I can tell, one way to do this in Linux would be to write a custom tty line discipline kernel driver that implements the Linux LED API and sends the commands to the serial port.据我所知,在 Linux 中执行此操作的一种方法是编写自定义 tty 线路规则内核驱动程序,该驱动程序实现 Linux LED API 并将命令发送到串行端口。 Then the Linux LED code can be in a kernel driver, but it's not tied to a specific serial port.然后 Linux LED 代码可以在内核驱动程序中,但它不绑定到特定的串行端口。

Then, to link it to a particular serial port, a userspace program would open the serial port, and use an ioctl(serial_fd, TIOCSETD, ...) call to attach the serial port to the custom line discipline driver.然后,要将其链接到特定的串行端口,用户空间程序将打开串行端口,并使用ioctl(serial_fd, TIOCSETD, ...)调用将串行端口附加到自定义线路规则驱动程序。 The line discipline driver does all the work from that point.生产线纪律驱动程序从那时起完成所有工作。 The userspace program's only purpose is really to associate the custom line discipline driver with the right serial device.用户空间程序的唯一目的是将自定义线路规则驱动程序与正确的串行设备相关联。

Pseudo-driver using FUSE filesystem使用 FUSE 文件系统的伪驱动程序

One alternative would be to write a userspace program that is a "pseudo-driver", that connects to the serial device, and provides an LED API resembling the Linux kernel LED class API, but at a different location, using a FUSE filesystem .一种替代方法是编写一个用户空间程序,它是一个“伪驱动程序”,它连接到串行设备,并提供类似于 Linux 内核 LED 类 API 的 LED API,但在不同的位置,使用FUSE 文件系统

For example, the program might be named foo-serial-leds and it could provide a number of LEDs under /var/run/foo-serial-leds/ with an API resembling the Linux kernel LED class drivers.例如,该程序可能命名为foo-serial-leds ,它可以在/var/run/foo-serial-leds/下提供多个/var/run/foo-serial-leds/ ,其 API 类似于 Linux 内核 LED 类驱动程序。

Then another program could control the LEDs by writing to eg /var/run/foo-serial-leds/status/brightness .然后另一个程序可以通过写入例如/var/run/foo-serial-leds/status/brightness来控制 LED。 That would be very similar to the program controlling a real Linux kernel LED class at /sys/class/leds/status/brightness , except the location on the filesystem is different.这与在/sys/class/leds/status/brightness控制真正的 Linux 内核 LED 类的程序非常相似,只是文件系统上的位置不同。 That program would be portable to another platform, with different LED devices, as long as the program has a configurable filesystem path for the LEDs it wants to control.该程序可以移植到具有不同 LED 设备的另一个平台,只要该程序具有用于它想要控制的 LED 的可配置文件系统路径。

Two disadvantages of this:这样做的两个缺点:

  • The program that wants to control the LED must be flexible enough to access the LED file API in a different location than the normal /sys/class/leds/想要控制 LED 的程序必须足够灵活,可以在与普通/sys/class/leds/不同的位置访问 LED 文件 API
  • These pseudo-driver LEDs can't use Linux kernel LED triggers这些伪驱动 LED 不能使用 Linux 内核 LED 触发器

Custom driver to allow userspace creation of LED devices允许用户空间创建 LED 设备的自定义驱动程序

Another option would be to write a Linux kernel driver that allows for userspace programs to create LED devices in the Linux kernel LED class.另一种选择是编写一个 Linux 内核驱动程序,允许用户空间程序在 Linux 内核 LED 类中创建 LED 设备。 The driver could use configfs to allow userspace programs to create the LED devices, which would then appear under /sys/class/leds/ .驱动程序可以使用configfs来允许用户空间程序创建 LED 设备,然后这些设备将出现在/sys/class/leds/ It would need to provide a way to notify the userspace program when the LED brightness is changed (maybe via sysfs_notify() on a custom sysfs attribute, which the userspace program can poll() ).它需要提供一种方法来在 LED 亮度改变时通知用户空间程序(可能通过自定义 sysfs 属性上的sysfs_notify() ,用户空间程序可以poll() )。

With that driver in place, a userspace program could implement the LED API and write to the serial device to achieve the LED control.有了该驱动程序,用户空间程序就可以实现 LED API 并写入串行设备以实现 LED 控制。 This program is kind of a userspace driver.这个程序是一种用户空间驱动程序。 Ie it would use the Linux driver to create one or more LED-class LEDs, and open the serial port to talk to the LED hardware.即它将使用 Linux 驱动程序创建一个或多个 LED 级 LED,并打开串行端口与 LED 硬件对话。 When it is notified that something has written to the LED brightness, it would need to send the relevant command to the serial device.当通知有东西写入 LED 亮度时,它需要向串行设备发送相关命令。

Then other userspace programs that want to control LEDs would be able to write to the LED-class API in the usual location under /sys/class/leds/ .然后其他想要控制 LED 的用户空间程序将能够在/sys/class/leds/下的通常位置写入 LED 类 API。

Linux kernel 4.10 userspace LED class driver Linux 内核 4.10 用户空间 LED 类驱动程序

Update November 2017: Linux kernel 4.10 adds a userspace LED class driver, uleds . 2017 年 11 月更新:Linux 内核 4.10 添加了用户空间 LED 类驱动程序uleds It implements something like what is described above.它实现了类似于上面描述的内容。 However, control is via a device /dev/uleds , not via configfs.但是,控制是通过设备/dev/uleds ,而不是通过 configfs 进行的。

An app should open the char device file /dev/uleds once for each user LED it wants to create.应用程序应该为它想要创建的每个用户 LED 打开字符设备文件/dev/uleds一次。 It should write a struct to the file, which specifies the name of the LED.它应该将一个结构写入文件,该文件指定 LED 的名称。 Then it should do reads from the open file handle, and will receive an int which specifies the brightness of the LED whenever that LED's brightness is changed by something else in the system.然后它应该从打开的文件句柄中读取,并且将接收一个 int 值,当系统中的其他东西改变 LED 的亮度时,它会指定 LED 的亮度。 If multiple LEDs are to be created, the app should open the char device file multiple times, once for each LED.如果要创建多个 LED,应用程序应多次打开字符设备文件,每个 LED 一次。

When the app closes, and the open file handle(s) to /dev/uleds is closed, then the user LED is automatically removed.当应用程序关闭并且/dev/uleds的打开文件句柄关闭时,用户 LED 将自动移除。

3 Ways: 3种方式:

1 - You must to understand the data send to CPU Board for modify as you want data for display your message on led board. 1 - 您必须了解发送到 CPU 板进行修改的数据,因为您需要在 LED 板上显示消息的数据。

2 - You must to have a linux API, but most of time the CPU is made in china, the chinese don't like linux. 2 - 你必须有一个 linux API,但大多数时候 CPU 是中国制造的,中国人不喜欢 linux。

3 - You write your own API for control LED Board with arduino or raspberry to control each pins of your LED Board. 3 - 您使用 arduino 或 raspberry 编写自己的 API 来控制 LED 板,以控制 LED 板的每个引脚。

Good luck !祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM