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 }
  • 相关阅读:
    归并排序
    堆排序
    数组数据生成器
    冒泡排序
    快速排序
    希尔排序
    排序接口与抽象类(java)
    Pycharm下HTMLTestRunner不生成测试报告
    抓包工具使用记录
    接口学习笔记
  • 原文地址:https://www.cnblogs.com/-glb/p/11210512.html
Copyright © 2011-2022 走看看