zoukankan      html  css  js  c++  java
  • 字符设备驱动程序的传统写法

    以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
    ", 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)
    ", 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!
    ");
    17     }
    18     if (argc != 2)
    19     {
    20         printf("Usage :
    ");
    21         printf("%s <on|off>
    ", 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 }

     

  • 相关阅读:
    HTML连载10-details标签&summary标签&marquee标签
    [刷题] 7-14 然后是几点
    [刷题] 7-18 出租车计价 (15 分)
    [刷题] PTA 7-20 简单计算器
    [刷题] PTA 7-22 用天平找小球
    [刷题] PTA 7-24 猜数字游戏
    [刷题] PTA 7-28 求整数的位数及各位数字之和
    [刷题] PTA 7-30 念数字
    [刷题] PTA 7-37 输出整数各位数字
    [刷题] PTA 7-35 猴子吃桃问题
  • 原文地址:https://www.cnblogs.com/-glb/p/11210461.html
Copyright © 2011-2022 走看看