zoukankan      html  css  js  c++  java
  • 总线设备驱动模型法

    led_dev.c

     1 #include <linux/module.h>
     2 #include <linux/version.h>
     3 
     4 #include <linux/init.h>
     5 
     6 #include <linux/kernel.h>
     7 #include <linux/types.h>
     8 #include <linux/interrupt.h>
     9 #include <linux/list.h>
    10 #include <linux/timer.h>
    11 #include <linux/init.h>
    12 #include <linux/serial_core.h>
    13 #include <linux/platform_device.h>
    14 
    15 #define S3C2440_GPA(n)  (0<<16 | n)
    16 #define S3C2440_GPB(n)  (1<<16 | n)
    17 #define S3C2440_GPC(n)  (2<<16 | n)
    18 #define S3C2440_GPD(n)  (3<<16 | n)
    19 #define S3C2440_GPE(n)  (4<<16 | n)
    20 #define S3C2440_GPF(n)  (5<<16 | n)
    21 #define S3C2440_GPG(n)  (6<<16 | n)
    22 #define S3C2440_GPH(n)  (7<<16 | n)
    23 #define S3C2440_GPI(n)  (8<<16 | n)
    24 #define S3C2440_GPJ(n)  (9<<16 | n)
    25 
    26 
    27 /* 分配/设置/注册一个platform_device */
    28 
    29 static struct resource led_resource[] = {
    30     [0] = {
    31         .start = S3C2440_GPF(5),
    32         .end   = S3C2440_GPF(5),
    33         .flags = IORESOURCE_MEM,
    34     },
    35 };
    36 
    37 static void led_release(struct device * dev)
    38 {
    39 }
    40 
    41 
    42 static struct platform_device led_dev = {
    43     .name         = "myled",
    44     .id       = -1,
    45     .num_resources    = ARRAY_SIZE(led_resource),
    46     .resource     = led_resource,
    47     .dev = { 
    48         .release = led_release, 
    49     },
    50 };
    51 
    52 static int led_dev_init(void)
    53 {
    54     platform_device_register(&led_dev);
    55     return 0;
    56 }
    57 
    58 static void led_dev_exit(void)
    59 {
    60     platform_device_unregister(&led_dev);
    61 }
    62 
    63 module_init(led_dev_init);
    64 module_exit(led_dev_exit);
    65 
    66 MODULE_LICENSE("GPL");

    led_drv.c

      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 #include <linux/platform_device.h>
     13 
     14 #define S3C2440_GPA(n)  (0<<16 | n)
     15 #define S3C2440_GPB(n)  (1<<16 | n)
     16 #define S3C2440_GPC(n)  (2<<16 | n)
     17 #define S3C2440_GPD(n)  (3<<16 | n)
     18 #define S3C2440_GPE(n)  (4<<16 | n)
     19 #define S3C2440_GPF(n)  (5<<16 | n)
     20 #define S3C2440_GPG(n)  (6<<16 | n)
     21 #define S3C2440_GPH(n)  (7<<16 | n)
     22 #define S3C2440_GPI(n)  (8<<16 | n)
     23 #define S3C2440_GPJ(n)  (9<<16 | n)
     24 
     25 static int led_pin;
     26 static volatile unsigned int *gpio_con;
     27 static volatile unsigned int *gpio_dat;
     28 
     29 /* 123. 分配/设置/注册file_operations 
     30  * 4. 入口
     31  * 5. 出口
     32  */
     33 
     34 static int major;
     35 static struct class *led_class;
     36 
     37 static unsigned int gpio_base[] = {
     38     0x56000000, /* GPACON */
     39     0x56000010, /* GPBCON */
     40     0x56000020, /* GPCCON */
     41     0x56000030, /* GPDCON */
     42     0x56000040, /* GPECON */
     43     0x56000050, /* GPFCON */
     44     0x56000060, /* GPGCON */
     45     0x56000070, /* GPHCON */
     46     0,          /* GPICON */
     47     0x560000D0, /* GPJCON */
     48 };
     49 
     50 static int led_open (struct inode *node, struct file *filp)
     51 {
     52     /* 把LED引脚配置为输出引脚 */
     53     /* GPF5 - 0x56000050 */
     54     int bank = led_pin >> 16;
     55     int base = gpio_base[bank];
     56 
     57     int pin = led_pin & 0xffff;
     58     gpio_con = ioremap(base, 8);
     59     if (gpio_con) {
     60         printk("ioremap(0x%x) = 0x%x
    ", base, gpio_con);
     61     }
     62     else {
     63         return -EINVAL;
     64     }
     65     
     66     gpio_dat = gpio_con + 1;
     67 
     68     *gpio_con &= ~(3<<(pin * 2));
     69     *gpio_con |= (1<<(pin * 2));  
     70 
     71     return 0;
     72 }
     73 
     74 static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)
     75 {
     76     /* 根据APP传入的值来设置LED引脚 */
     77     unsigned char val;
     78     int pin = led_pin & 0xffff;
     79     
     80     copy_from_user(&val, buf, 1);
     81 
     82     if (val)
     83     {
     84         /* 点灯 */
     85         *gpio_dat &= ~(1<<pin);
     86     }
     87     else
     88     {
     89         /* 灭灯 */
     90         *gpio_dat |= (1<<pin);
     91     }
     92 
     93     return 1; /* 已写入1个数据 */
     94 }
     95 
     96 static int led_release (struct inode *node, struct file *filp)
     97 {
     98     printk("iounmap(0x%x)
    ", gpio_con);
     99     iounmap(gpio_con);
    100     return 0;
    101 }
    102 
    103 
    104 static struct file_operations myled_oprs = {
    105     .owner = THIS_MODULE,
    106     .open  = led_open,
    107     .write = led_write,
    108     .release = led_release,
    109 };
    110 
    111 
    112 static int led_probe(struct platform_device *pdev)
    113 {
    114     struct resource        *res;
    115 
    116     /* 根据platform_device的资源进行ioremap */
    117     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    118     led_pin = res->start;
    119 
    120     major = register_chrdev(0, "myled", &myled_oprs);
    121 
    122     led_class = class_create(THIS_MODULE, "myled");
    123     device_create(led_class, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */
    124     
    125     return 0;
    126 }
    127 
    128 static int led_remove(struct platform_device *pdev)
    129 {
    130     unregister_chrdev(major, "myled");
    131     device_destroy(led_class,  MKDEV(major, 0));
    132     class_destroy(led_class);
    133     
    134     return 0;
    135 }
    136 
    137 
    138 struct platform_driver led_drv = {
    139     .probe        = led_probe,
    140     .remove        = led_remove,
    141     .driver        = {
    142         .name    = "myled",
    143     }
    144 };
    145 
    146 
    147 static int myled_init(void)
    148 {
    149     platform_driver_register(&led_drv);
    150     return 0;
    151 }
    152 
    153 static void myled_exit(void)
    154 {
    155     platform_driver_unregister(&led_drv);
    156 }
    157 
    158 
    159 
    160 module_init(myled_init);
    161 module_exit(myled_exit);
    162 
    163 
    164 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 }
  • 相关阅读:
    SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问
    谷歌浏览器扩展程序manifest.json参数详解
    获取天气api
    UVA 10385 Duathlon
    UVA 10668 Expanding Rods
    UVALIVE 3891 The Teacher's Side of Math
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 11210 Chinese Mahjong
    UVA 11384 Help is needed for Dexter
  • 原文地址:https://www.cnblogs.com/-glb/p/11210512.html
Copyright © 2011-2022 走看看