arm 驱动进阶:驱动程序总线设备驱动模型

总线设备驱动模型关系图:

arm 驱动进阶:驱动程序总线设备驱动模型

 

 

驱动程序总线设备驱动模型代码编写步骤:

arm 驱动进阶:驱动程序总线设备驱动模型

 

  

device、driver、app led驱动实例:

device代码实现:

led_drv.c
#include <linux/module.h>

#include <linux/version.h>



#include <linux/init.h>



#include <linux/kernel.h>

#include <linux/types.h>

#include <linux/interrupt.h>

#include <linux/list.h>

#include <linux/timer.h>

#include <linux/init.h>

#include <linux/serial_core.h>

#include <linux/platform_device.h>





/* 分配/设置/注册一个platform_device */



static struct resource led_resource[] = {

    [0] = {

        .start = 0x56000050,

        .end   = 0x56000050 + 8 - 1,

        .flags = IORESOURCE_MEM,

    },

    [1] = {

        .start = 5,

        .end   = 5,

        .flags = IORESOURCE_IRQ,

    }



};



static void led_release(struct device * dev)

{

}





static struct platform_device led_dev = {

    .name         = "myled",

    .id       = -1,

    .num_resources    = ARRAY_SIZE(led_resource),

    .resource     = led_resource,

    .dev = { 

        .release = led_release, 

    },

};



static int led_dev_init(void)

{

    platform_device_register(&led_dev);

    return 0;

}



static void led_dev_exit(void)

{

    platform_device_unregister(&led_dev);

}



module_init(led_dev_init);

module_exit(led_dev_exit);



MODULE_LICENSE("GPL");

 

driver代码实现:

led_drv.c
/* 分配/设置/注册一个platform_driver */



#include <linux/module.h>

#include <linux/version.h>



#include <linux/init.h>

#include <linux/fs.h>

#include <linux/interrupt.h>

#include <linux/irq.h>

#include <linux/sched.h>

#include <linux/pm.h>

#include <linux/sysctl.h>

#include <linux/proc_fs.h>

#include <linux/delay.h>

#include <linux/platform_device.h>

#include <linux/input.h>

#include <linux/irq.h>

#include <asm/uaccess.h>

#include <asm/io.h>



static int major;





static struct class *cls;

static volatile unsigned long *gpio_con;

static volatile unsigned long *gpio_dat;

static int pin;



static int led_open(struct inode *inode, struct file *file)

{

    //printk("first_drv_open\n");

    /* 配置为输出 */

    *gpio_con &= ~(0x3<<(pin*2));

    *gpio_con |= (0x1<<(pin*2));

    return 0;    

}



static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

{

    int val;



    //printk("first_drv_write\n");



    copy_from_user(&val, buf, count); //    copy_to_user();



    if (val == 1)

    {

        // 点灯

        *gpio_dat &= ~(1<<pin);

    }

    else

    {

        // 灭灯

        *gpio_dat |= (1<<pin);

    }

    

    return 0;

}





static struct file_operations led_fops = {

    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

    .open   =   led_open,     

    .write    =    led_write,       

};



static int led_probe(struct platform_device *pdev)

{

    struct resource        *res;



    /* 根据platform_device的资源进行ioremap */

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    gpio_con = ioremap(res->start, res->end - res->start + 1);

    gpio_dat = gpio_con + 1;



    res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

    pin = res->start;



    /* 注册字符设备驱动程序 */



    printk("led_probe, found led\n");



    major = register_chrdev(0, "myled", &led_fops);



    cls = class_create(THIS_MODULE, "myled");



    class_device_create(cls, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */

    

    return 0;

}



static int led_remove(struct platform_device *pdev)

{

    /* 卸载字符设备驱动程序 */

    /* iounmap */

    printk("led_remove, remove led\n");



    class_device_destroy(cls, MKDEV(major, 0));

    class_destroy(cls);

    unregister_chrdev(major, "myled");

    iounmap(gpio_con);

    

    return 0;

}





struct platform_driver led_drv = {

    .probe        = led_probe,

    .remove        = led_remove,

    .driver        = {

        .name    = "myled",

    }

};





static int led_drv_init(void)

{

    platform_driver_register(&led_drv);

    return 0;

}



static void led_drv_exit(void)

{

    platform_driver_unregister(&led_drv);

}



module_init(led_drv_init);

module_exit(led_drv_exit);



MODULE_LICENSE("GPL");

 

app代码实现:

led_test.c
#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>



/* led_test on

 * led_test off

 */

int main(int argc, char **argv)

{

    int fd;

    int val = 1;

    fd = open("/dev/led", O_RDWR);

    if (fd < 0)

    {

        printf("can't open!\n");

    }

    if (argc != 2)

    {

        printf("Usage :\n");

        printf("%s <on|off>\n", argv[0]);

        return 0;

    }



    if (strcmp(argv[1], "on") == 0)

    {

        val  = 1;

    }

    else

    {

        val = 0;

    }

    

    write(fd, &val, 4);

    return 0;

}

 

 

 

你可能感兴趣的:(ARM)