I am trying to build a kernel module for Linux to try to control a list of LED devices that will turn them on/off in a sequence. For example, green --> red --> green --> orange, and then repeat.
I know it can be done simply in userspace, but this LED sequence needs to be happening when CPU is used intensively where the sequence will be slowed down dramatically, so I need to control it through Hardware. I've using delay_on/delay_off, with usleep(), but just cannot get the timing right between 3 LEDs.
I know how to trigger each LEDs and assign them pattern individually, but I cannot do it collectively.
Can anyone show me how to obtain a list of LED devices?
To list the available LEDs in kernel code:
extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
...
struct led_classdev *led_cdev;
...
down_write(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
printk(KERN_INFO "LED %s\n", led_cdev->name);
}
up_write(&leds_list_lock);
In kernel code, you can use the following function to retrieve a 'struct led_classdev' matching a given LED name:
struct led_classdev *led_get_by_name(const char *name)
{
struct led_classdev *led_cdev0 = NULL;
struct led_classdev *led_cdev;
if (name == NULL) {
return NULL;
}
down_write(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
if ((led_cdev->name != NULL) && (strcmp(led_cdev->name, name) == 0)) {
led_cdev0 = led_cdev;
break;
}
}
up_write(&leds_list_lock);
return led_cdev0;
}
Once the 'struct led_classdev' retrieved, all kernel LED APIs can be used.
Pay attention that the LED name may be null in the registered 'struct led_classdev' while the LED name appears under /sys/class/leds. E.g., this the case for the ACT and PWR LEDs on my Raspberry PI 4 under Debian 12.