• led驱动程序设计


    LED的驱动程序很简单,按照张字符型设备驱动设计方法顺下来即可实现,这里主要讲几个注意事项。
      一、在linux系统中,操作硬件不能够使用物理地址,一定要用虚拟地址。将物理地址转化为虚拟地址的函数如下:
        #define    ioremap(cookie,size)
        其中cookie为要转化的物理地址,size为转化空间的大小,单位为字节。返回值为转化后的虚拟地址。
      二、在执行程序时我们需要顺带输入参数进去,但是是以字符串的形式输入的,不方便操控。所以用atoi函数将字符串转化为整数,函数原型如下:
        int    atoi(const char *nptr);
      三、点亮LED是对设备的控制,而不是读写。即在驱动程序中ioctl函数里相对应的寄存器的虚拟地址写入值即可。向某个地址写入值的函数为writel函数,原型:
        static    inline    void    writel(unsigned int b, volatile void __iomem *addr)
        第一个参数为写入的值,第二个参数是虚拟地址。
      接下来也没什么了,最关键的就是驱动程序模型。要想写出字符设备驱动一定要学好它,特别重要!!

    头文件:

     1 #include <linux/module.h>
     2 #include <linux/init.h>
     3 #include <linux/cdev.h>
     4 #include <linux/fs.h>
     5 #include <linux/io.h>
     6 
     7 #define LED_MAGIC 'L'
     8 #define LED_OFF _IO(LED_MAGIC,0)
     9 #define LED_1 _IO(LED_MAGIC,1)
    10 #define LED_2 _IO(LED_MAGIC,2)
    11 #define LED_3 _IO(LED_MAGIC,3)
    12 #define LED_4 _IO(LED_MAGIC,4)
    13 #define LED_ALL _IO(LED_MAGIC,5)

    驱动程序代码:

      

     1 #include "led.h"
     2 
     3 #define GPBCON 0x56000010
     4 #define GPBDAT 0x56000014
     5 
     6 /*控制LED寄存器的物理地址*/
     7 unsigned int *led_config;
     8 unsigned int *led_data;
     9 
    10 /*存储设备号*/
    11 dev_t devno;
    12 
    13 /*分配cdev*/
    14 struct cdev cdev;
    15 
    16 int led_open(struct inode *node, struct file *filp)
    17 {
    18     /*将物理地址转为虚拟地址*/
    19     led_config = ioremap(GPBCON,3);
    20     led_data = ioremap(GPBDAT,2);
    21 
    22     /*向某一地址写入值*/
    23     writel(0x15400,led_config);
    24 
    25     return 0;
    26 }
    27 /*驱动程序里的设备控制函数*/
    28 long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    29 {
    30     switch(cmd)
    31     {
    32         case LED_1:
    33             writel(0b00011100000,led_data);
    34             return 0;
    35         case LED_2:
    36             writel(0b00101100000,led_data);
    37             return 0;
    38         case LED_3:
    39             writel(0b00110100000,led_data);
    40             return 0;
    41         case LED_4:
    42             writel(0b00111000000,led_data);
    43             return 0;
    44         case LED_OFF:
    45             writel(0b00111100000,led_data);
    46             return 0;
    47         case LED_ALL:
    48             writel(0,led_data);
    49             return 0;
    50 
    51         default:
    52             return -EINVAL;
    53     }
    54 }
    55 
    56 /*函数映射关系表*/
    57 struct file_operations led_fops = 
    58 {
    59     .open = led_open,
    60     .unlocked_ioctl = led_ioctl,
    61 };
    62 
    63 
    64 
    65 static int led_init()
    66 {
    67 
    68     /*初始化cdev*/
    69     cdev_init(&cdev, &led_fops);
    70     /*注册cdev*/
    71     alloc_chrdev_region(&devno, 0, 1,"myled");                    //动态分配设备号,第四个参数为设备名称
    72     cdev_add(&cdev, devno, 1);
    73     return 0;
    74 }
    75 
    76 static void led_exit()
    77 {
    78     /*删除设备*/
    79     cdev_del(&cdev);
    80     /*释放设备号*/
    81     unregister_chrdev_region(devno,1);
    82 }
    83 
    84 MODULE_LICENSE("GPL");
    85 module_init(led_init);
    86 module_exit(led_exit);

    应用程序代码:

     1 #include <sys/types.h>
     2 #include <sys/stat.h>
     3 #include <fcntl.h>
     4 #include <sys/ioctl.h>
     5 #include <stdio.h>
     6 #include "led.h"
     7 
     8 int main(int argc, char *argv[])
     9 {
    10     int fd;
    11     int cmd;
    12          
    13     if (argc <2 )
    14     {
    15         printf("please enter the second para!
    ");
    16         return 0;    
    17     }
    18          
    19     cmd = atoi(argv[1]); 
    20          
    21     fd = open("/dev/myled",O_RDWR);
    22     
    23     if(cmd == 0)
    24         ioctl(fd,LED_OFF);    
    25     if(cmd == 1)
    26         ioctl(fd,LED_1);
    27     if(cmd == 2)
    28         ioctl(fd,LED_2);
    29     if(cmd == 3)
    30         ioctl(fd,LED_3);
    31     if(cmd == 4)
    32         ioctl(fd,LED_4);
    33     if(cmd == 5)
    34         ioctl(fd,LED_ALL);
    35              
    36     return 0;
    37 }
  • 相关阅读:
    gitlab+jenkens+maven私服
    记录一次gitlab+jenkins入坑到排坑的过程
    python进阶之路一,变量、运算符、判断、while循环
    cat EOF追加与覆盖
    tcpdump使用
    iptables学习
    Java生产消费模型—ArrayBlockingQueue详解
    Java泛型详解(透彻)
    Java源码初探_logging日志模块实现
    Java设计模式学习总结
  • 原文地址:https://www.cnblogs.com/51qianrushi/p/4294580.html
Copyright © 2020-2023  润新知