字符设备驱动程序的传统写法

以led驱动程序为例,介绍字符设备驱动程序的传统写法。

驱动程序:

程序代码来源于韦老大视频代码

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/fs.h>
  4 #include <linux/init.h>
  5 #include <linux/delay.h>
  6 #include <linux/uaccess.h>
  7 #include <asm/irq.h>
  8 #include <asm/io.h>
  9 #include <linux/of.h>
 10 #include <linux/of_device.h>
 11 #include <linux/of_platform.h>
 12 
 13 #define S3C2440_GPA(n)  (0<<16 | n)
 14 #define S3C2440_GPB(n)  (1<<16 | n)
 15 #define S3C2440_GPC(n)  (2<<16 | n)
 16 #define S3C2440_GPD(n)  (3<<16 | n)
 17 #define S3C2440_GPE(n)  (4<<16 | n)
 18 #define S3C2440_GPF(n)  (5<<16 | n)
 19 #define S3C2440_GPG(n)  (6<<16 | n)
 20 #define S3C2440_GPH(n)  (7<<16 | n)
 21 #define S3C2440_GPI(n)  (8<<16 | n)
 22 #define S3C2440_GPJ(n)  (9<<16 | n)
 23 
 24 static int led_pin = S3C2440_GPF(5);
 25 static volatile unsigned int *gpio_con;
 26 static volatile unsigned int *gpio_dat;
 27 
 28 /* 123. 分配/设置/注册file_operations 
 29  * 4. 入口
 30  * 5. 出口
 31  */
 32 
 33 static int major;
 34 static struct class *led_class;
 35 
 36 static unsigned int gpio_base[] = {
 37     0x56000000, /* GPACON */
 38     0x56000010, /* GPBCON */
 39     0x56000020, /* GPCCON */
 40     0x56000030, /* GPDCON */
 41     0x56000040, /* GPECON */
 42     0x56000050, /* GPFCON */
 43     0x56000060, /* GPGCON */
 44     0x56000070, /* GPHCON */
 45     0,          /* GPICON */
 46     0x560000D0, /* GPJCON */
 47 };
 48 
 49 static int led_open (struct inode *node, struct file *filp)
 50 {
 51     /* 把LED引脚配置为输出引脚 */
 52     /* GPF5 - 0x56000050 */
 53     int bank = led_pin >> 16;
 54     int base = gpio_base[bank];
 55 
 56     int pin = led_pin & 0xffff;
 57     gpio_con = ioremap(base, 8);
 58     if (gpio_con) {
 59         printk("ioremap(0x%x) = 0x%x\n", base, gpio_con);
 60     }
 61     else {
 62         return -EINVAL;
 63     }
 64     
 65     gpio_dat = gpio_con + 1;
 66 
 67     *gpio_con &= ~(3<<(pin * 2));
 68     *gpio_con |= (1<<(pin * 2));  
 69 
 70     return 0;
 71 }
 72 
 73 static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)
 74 {
 75     /* 根据APP传入的值来设置LED引脚 */
 76     unsigned char val;
 77     int pin = led_pin & 0xffff;
 78     
 79     copy_from_user(&val, buf, 1);
 80 
 81     if (val)
 82     {
 83         /* 点灯 */
 84         *gpio_dat &= ~(1<<pin);
 85     }
 86     else
 87     {
 88         /* 灭灯 */
 89         *gpio_dat |= (1<<pin);
 90     }
 91 
 92     return 1; /* 已写入1个数据 */
 93 }
 94 
 95 static int led_release (struct inode *node, struct file *filp)
 96 {
 97     printk("iounmap(0x%x)\n", gpio_con);
 98     iounmap(gpio_con);
 99     return 0;
100 }
101 
102 
103 static struct file_operations myled_oprs = {
104     .owner = THIS_MODULE,
105     .open  = led_open,
106     .write = led_write,
107     .release = led_release,
108 };
109 
110 
111 static int myled_init(void)
112 {
113     major = register_chrdev(0, "myled", &myled_oprs);
114 
115     led_class = class_create(THIS_MODULE, "myled");
116     device_create(led_class, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */
117 
118     return 0;
119 }
120 
121 static void myled_exit(void)
122 {
123     unregister_chrdev(major, "myled");
124     device_destroy(led_class,  MKDEV(major, 0));
125     class_destroy(led_class);
126 }
127 
128 module_init(myled_init);
129 module_exit(myled_exit);
130 
131 
132 MODULE_LICENSE("GPL");

2、测试程序

 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 
 6 /* ledtest on
 7   * ledtest off
 8   */
 9 int main(int argc, char **argv)
10 {
11     int fd;
12     unsigned char val = 1;
13     fd = open("/dev/led", O_RDWR);
14     if (fd < 0)
15     {
16         printf("can't open!\n");
17     }
18     if (argc != 2)
19     {
20         printf("Usage :\n");
21         printf("%s <on|off>\n", argv[0]);
22         return 0;
23     }
24 
25     if (strcmp(argv[1], "on") == 0)
26     {
27         val  = 1;
28     }
29     else
30     {
31         val = 0;
32     }
33     
34     write(fd, &val, 1);
35     return 0;
36 }

 

猜你喜欢

转载自www.cnblogs.com/-glb/p/11210461.html
今日推荐