码迷,mamicode.com
首页 > 其他好文 > 详细

led驱动程序设计

时间:2015-02-16 23:21:01      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:

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!\n");
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 }

 

led驱动程序设计

标签:

原文地址:http://www.cnblogs.com/51qianrushi/p/4294580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!