diff --git a/07_virtual_leds_more_complex/Makefile b/07_virtual_leds_more_complex/Makefile new file mode 100644 index 0000000..b909b3c --- /dev/null +++ b/07_virtual_leds_more_complex/Makefile @@ -0,0 +1,7 @@ +obj-m += test_module.o + +all: + make -C $(LINUX_MODULES_FOLDER)/build M=$(PWD) modules + +clean: + make -C $(LINUX_MODULES_FOLDER)/build M=$(PWD) clean diff --git a/07_virtual_leds_more_complex/test_module.c b/07_virtual_leds_more_complex/test_module.c new file mode 100644 index 0000000..3cc1796 --- /dev/null +++ b/07_virtual_leds_more_complex/test_module.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#define NUM_LEDS 5 + +struct flo_device { + struct led_classdev *leds[NUM_LEDS]; +}; + +static struct flo_device flo_dev; + +static void virtual_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { + pr_info("Luminosité défini sur la LED %s à %d\n", led_cdev->name, brightness); +} + +static enum led_brightness virtual_led_brightness_get(struct led_classdev *led_cdev) { + pr_info("Luminosité lu sur la LED %s, valeur actuelle: %d\n", led_cdev->name, led_cdev->brightness); + return led_cdev->brightness; +} + +static int __init virtual_led_init(void) { + int ret, i; + pr_info("Chargement du module pour les LEDs virtuelles\n"); + + for (i = 0; i < NUM_LEDS; i++) { + struct led_classdev *led = kzalloc(sizeof(struct led_classdev), GFP_KERNEL); + if (!led) { + pr_err("Échec de l'allocation de mémoire pour la LED %d\n", i); + ret = -ENOMEM; + goto fail; + } + + led->name = kasprintf(GFP_KERNEL, "flo-led:white:flo-%d", i + 1); + led->color = LED_COLOR_ID_WHITE; + led->brightness = 0; + led->max_brightness = 255; + led->brightness_set = virtual_led_brightness_set; + led->brightness_get = virtual_led_brightness_get; + + ret = led_classdev_register(NULL, led); + if (ret < 0) { + pr_err("Impossible d'ajouter la LED virtuelle %d\n", i); + kfree(led->name); + kfree(led); + goto fail; + } + + flo_dev.leds[i] = led; + } + + pr_info("Les LEDs virtuelles sont ajoutées\n"); + return 0; + +fail: + for (i--; i >= 0; i--) { + led_classdev_unregister(flo_dev.leds[i]); + kfree(flo_dev.leds[i]->name); + kfree(flo_dev.leds[i]); + } + pr_err("Les LEDs virtuelles n'ont pas pu être ajoutées\n"); + return ret; +} + +static void __exit virtual_led_exit(void) { + int i; + pr_info("Déchargement du module pour les LEDs virtuelles\n"); + + for (i = 0; i < NUM_LEDS; i++) { + if (flo_dev.leds[i]) { + led_classdev_unregister(flo_dev.leds[i]); + kfree(flo_dev.leds[i]->name); + kfree(flo_dev.leds[i]); + } + } + + pr_info("Les LEDs virtuelles sont bien retirées\n"); +} + +module_init(virtual_led_init); +module_exit(virtual_led_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Florian RICHER"); +MODULE_DESCRIPTION("Un module noyau qui ajoute des LEDs virtuelles"); +MODULE_VERSION("1.0");