zoukankan      html  css  js  c++  java
  • 11.ok6410之led驱动程序编写

                       led驱动程序编写

      本文主要包含三部分,led驱动程序led.c编写,编译驱动程序的makefile的编写,以及使用驱动程序的应用程序led_app的编写

    一、led.c编写

     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 #include "led.h"
     7 #define GPMCON 0x7f008820
     8 #define GPMDAT 0x7f008824 
     9 
    10 unsigned int *led_config;
    11 unsigned int *led_data;
    12 
    13 struct cdev cdev;  //静态分配描述符
    14 dev_t devno;
    15 
    16 int led_open (struct inode *node, struct file *filp)
    17 {
    18     led_config = ioremap(GPMCON,4);  //地址转化为虚拟地址
    19     writel(0x1111,led_config); //为虚拟地址写入值
    20     
    21     led_data = ioremap(GPMDAT,4);  //物理地址转化为虚拟地址
    22     return 0;
    23 }
    24 
    25 //响应系统调用函数的驱动函数
    26 long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    27 {
    28     switch (cmd)   //通过不同命令执行控制命令
    29     {
    30         case LED_ON:
    31             writel(0x00,led_data);
    32             return 0;
    33         
    34         case LED_OFF:
    35             writel(0xff,led_data);
    36             return 0;
    37         
    38         default:
    39             return -EINVAL;
    40     }
    41 }
    42 
    43 static struct file_operations led_fops =
    44 {
    45     .open = led_open,
    46     .unlocked_ioctl = led_ioctl,
    47 };
    48 
    49 static int led_init()
    50 {
    51     cdev_init(&cdev,&led_fops);   //初始化设备描述
    52     alloc_chrdev_region(&devno, 0 , 1 , "myled");   //设备号分配
    53     cdev_add(&cdev, devno, 1);     //注册字符设备
    54     return 0;    
    55 }
    56 
    57 static void led_exit()
    58 {
    59     cdev_del(&cdev);   //驱动注销
    60     unregister_chrdev_region(devno,1);  //设备号释放
    61 }
    62 
    63 module_init(led_init);
    64 module_exit(led_exit);

    1.1控制led命令的编写---->led.h

    1 #define LED_MAGIC 'L'
    2 #define LED_ON  _IO(LED_MAGIC,0)
    3 #define LED_OFF _IO(LED_MAGIC,1)

    二、编译led.c的Makefile的编写

    obj-m := led.o
    KDIR :=/home/kernel/kernel/linux-ok6410
    all:
        make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
    clean:
        rm -f *.ko *.o *.order *.symvers *.mod.c *~

    三、应用程序的编写

     1 #include "led.h"
     2 #include <sys/types.h>
     3 #include <sys/stat.h>
     4 #include <fcntl.h>
     5 #include <sys/ioctl.h>
     6 #include <string.h>
     7 
     8 int main(int argc,char *argv[])
     9 {
    10     int fd;
    11     int cmd;
    12     if(argc<2)
    13     {
    14         printf("please enter the secnod para!
    ");
    15     }
    16     cmd = atoi(argv[1]);  //字符参数转化为整形
    17     fd = open("/dev/myled",O_RDWR);
    18     if(cmd==1)
    19     {
    20         ioctl(fd,LED_ON);
    21         printf ("led on!!!
    ");
    22     }
    23     else
    24         ioctl(fd,LED_OFF);
    25 }

     在完成以上步骤之后就可以安装内核模块并且运行应用程序了

    运行过程如下:

    首先安装内核模块:insmod led.ko

    接着查看注册的设备号:cat /proc/devices

            

    可以看出我注册的led驱动对应的设备号是252

    所以接着创建字符设备文件:mknod  /dev/myled  c  252  0   

    紧接着运行应用程序:

              

    可以看到开发板上面的所有灯都亮了!!!!!!!

    四、出现的问题解决

      在运行时候莫名奇妙的出现了一个Segmentation fault,后来查找了很久居然发现是应为在编写led.c的代码时候在

    1 int led_open (struct inode *node, struct file *filp)
    2 {
    3     led_config = ioremap(GPMCON,4);  //地址转化为虚拟地址
    4     writel(0x1111,led_config); //为虚拟地址写入值
    5     
    6     led_data = ioremap(GPMDAT,4);  //物理地址转化为虚拟地址
    7     return 0;
    8 }

      这个函数里面缺少了return 0这句差点酿成大祸了。。。。。。。。。。

  • 相关阅读:
    NFS服务
    SSH服务
    DNS服务器
    FTP服务器
    linux(磁盘配额)
    linux(ACL权限控制)
    linux(日志)
    linux(系统安全)
    linux(进程和计划任务)
    linux(引导)
  • 原文地址:https://www.cnblogs.com/wmx-learn/p/5352198.html
Copyright © 2011-2022 走看看