Maison >Opération et maintenance >exploitation et maintenance Linux >Réalisez un driver LED sous Linux sans taper une ligne de code !

Réalisez un driver LED sous Linux sans taper une ligne de code !

嵌入式Linux充电站
嵌入式Linux充电站avant
2023-07-31 17:04:551655parcourir

Avant-propos

Si vous souhaitez implémenter un pilote de périphérique, vous n'avez pas besoin d'écrire une seule ligne de code de pilote Cela ne ressemble-t-il pas à un fantasme ?

Mais ce n'est pas irréalisable, car les développeurs de noyau du monde entier sont très enthousiastes tant qu'ils peuvent écrire des pilotes, ils les ont essentiellement écrits.

Aujourd'hui, nous nous appuyons sur les épaules de géants et utilisons les pilotes écrits par les développeurs du noyau pour réaliser les fonctions que nous souhaitons. Cet article traite des pilotes LED.

Pilote LED

Nous prenons comme exemple la LED intégrée de la carte de développement imx6ull pro. Elle a une Led2 contrôlable à bord. Le schéma est le suivant :

Réalisez un driver LED sous Linux sans taper une ligne de code !

LED2 a une traction. -up résistance. L'autre broche est connectée à GPIO5_3,因此GPIO5_3 et produit un niveau bas pour allumer la LED. Voici comment contrôler cette LED.

Configuration du noyau :

 Device Drivers  --->
  [*] LED Support  --->
   <*>   LED Class Support
   <*>   LED Support for GPIO connected LEDs
   [*]   LED Trigger support  --->

Notre pilote LED est basé sur GPIO, nous devons donc activer la prise en charge du pilote LED du noyau.

Le noyau a deux pilotes correspondants, à savoir Pilote GPIO et Pilote LEDLe pilote LED basé sur GPIO appelle la fonction exportée par le pilote GPIO.

Pour le code d'implémentation du pilote LED, veuillez vous référer à : drivers/leds/leds-gpio.c Il implémente une classe LED pour contrôler les LED via l'interface sysfs.

设备树:

leds{
 compatible = "gpio-leds";
 
        led2{
            label = "led2";
            gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;//GPIO_ACTIVE_LOW,代表低电平点亮LED
            default-state = "on";
        };
}

在设备树中创建一个名为leds的节点,compatible"gpio-leds",这样可以匹配到leds-gpio.c的驱动。

然后创建一个子节点,名为led2。需要填三个属性:labelgpiosdefault-state

label:lable是出现在sys目录下的名字,即生成/sys/class/leds/led2

gpios:前两个值指定了该LED所连接的GPIO。第三个值可填GPIO_ACTIVE_HIGHGPIO_ACTIVE_LOWGPIO_ACTIVE_HIGH代表高电平点亮LED,GPIO_ACTIVE_LOW代表低电平点亮LED。GPIO_ACTIVE_HIGHGPIO_ACTIVE_LOWGPIO_ACTIVE_HIGH代表高电平点亮LED,GPIO_ACTIVE_LOW代表低电平点亮LED。

这里注意了,gpios属性的第三个参数,代表该gpio点亮LED是需要高电平还是低电平,注意是点亮LED,细品

default-state:on代表默认情况LED是点亮的,off代表默认LED熄灭

这里又注意了,当defalut-state为on时,实际上gpio输出的电平,就是gpios属性中指定的点亮LED时的电平

设备树配置好后,编译并更换dtb,然后重启开发板。可以看到/sys/class/leds/led2

/sys/class/leds/led2目录:🎜<figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"><img src="https://img.php.cn/upload/article/001/275/014/4273c46fe81bea65814fbece8c3741cc-1.png" alt="Réalisez un driver LED sous Linux sans taper une ligne de code !" ></figure></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><code style='font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);'>/sys/class/leds/led2/目录下有一个brightnes文件,可以通过echo cat的方式查看和修改LED的亮度。因为LED连接在GPIO上,所以亮度只有0和1,在本文示例的led2中,0表示点亮,1表示熄灭。

点亮LED:

echo 0 > /sys/class/leds/led2/brightness

熄灭LED:

echo 1 > /sys/class/leds/led2/brightness

应用层控制

除了可以在shell中通过echocat的方式控制Led,我们也可以在写一个应用层程序来操作/sys/class/leds/下的节点,应用层代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>

#include <sys/stat.h>
#include <sys/types.h>

#define LED_DEV_PATH "/sys/class/leds/led%d/brightness"
#define ON
#define OFF

int fs4412_set_led(unsigned int lednum, unsigned int mode)
{
 int fd;
    int ret;
    char devpath[128];
    char *on = "1\n";
    char *off = "0\n";
    char *m = NULL;
    
    snprintf(devpath, sizeof(devpath), LED_DEV_PATH, lednum);
    fd = open(devpath, O_WRONLY);
    if (fd == -1) {
  perror("fsled->open");
        return -1;
 }
    
    if (mode == ON)
         m = on;
    else
         m = off;
    
    ret = write(fd, m, strlen(m));
    if (ret == -1) {
  perror("fsled->wrtie");
        close(fd);
        return -1;
    }
    
    close(fd);
    return 0;

}

int main(int argc, char *argv[])
{
 unsigned int lednum = 2;
    
    while(1){
  fs4412_set_led(lednum, on);
        usleep(500000);
        fs4412_set_led(lednum, OFF);
  usleep(500000);
        
        lednum++;
        if (lednum > 5)
             lednum = 2;
 }

 return 0;
}

上述应用层代码执行后,led2会闪烁。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer