还没有学驱动时,大部分对驱动的言论,包括老师的介绍都说做驱动是嵌入式里最难的部分,涉及到底层硬件和内核的知识,心里因此增加了不少畏惧。自己开始学习的时候便开始看些驱动方面的书,希望能有个比较好的认识,可慢慢的发现几乎看不懂,看了韦东山老师的部分视频后果然豁然开朗,发现做LED驱动以及其它驱动时,最主要的是要明白应用程序、库、内核、驱动程序之间的关系,在视频里韦东山老师首先为我们一步一步构造出它们之间的关系,驱动属于底层硬件和上层应用程序之间的中间层,看完这部分视频后你会很清楚的知道驱动、应用程序的那些函数是如何工作的。
    接下来就是编写驱动程序了,首先构造了open、read、write等函数,而这些只是一些简单的函数而已,如何发挥作用是通过一个结构体来定义,视频里给出的结构体如下:
static struct file_operations first_drv_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open    =   first_drv_open,     
    .read     =     first_drv _read,       
    .write    =     first_drv _write,       
};

然后再定义first_drv_init函数用来初始化设备等,实现方法如下:
static int first_drv_init(void)  
{
    printk("MY DRIVER MODULE INIT\n");
    first_drv_major = register_chrdev(0,DEVICE_NAME, &first_drv_fops);  /*注册一设备*/
    if (first_drv_major < 0)
    {
        printk(DEVICE_NAME " can't register major number\n");
        return first_drv_major;
    }
    printk("register first_drv OK! Major = %d\n", first_drv_major);
    firstdrv_class = class_create(THIS_MODULE, DEVICE_NAME);   /*创建一个类*/
    if(IS_ERR(firstdrv_class))
    {
            printk("Err: failed in firstdrv_class. \n");
            return -1 ;
    }
    /*通过创建的类来创建一设备节点*/
firstdrv_class_dev=device_create(firstdrv_class, NULL, MKDEV(first_drv_major, 0), NULL, DEVICE_NAME);
       if(unlikely(IS_ERR(firstdrv_class_dev)))
            return PTR_ERR(firstdrv_class_dev);
       printk(DEVICE_NAME " initialized\n");
    gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); /*把寄存器的地址映射成虚拟地址*/
    gpfdat = gpfcon + 1;
          return 0;
}

创建了设备,在退出时就必须注销相关的设备和节点,实现函数如下:
static void first_drv_exit(void)
{
    printk("FIRST_DRV MODULE EXIT\n");
    unregister_chrdev(first_drv_major, DEVICE_NAME);    /*注销该设备*/
    device_destroy(firstdrv_class, MKDEV(first_drv_major, 0));  /*注销类创建的设备节点*/
    class_destroy(firstdrv_class);   /*注销类*/
    iounmap(gpfcon);  //取消地址映射
    iounmap(gpfdat);
}

    编写完代码后再编写测试程序和makefile文件,拷贝相关文件到虚拟机下,执行make指令生成.ko文件,再编译测试程序,生成可执行程序,最后把.ko文件和测试程序的可执行文件拷到开发板的根文件系统下通过命令:insmod first_drv.ko动态加载驱动,再执行:./first_drv_test 0可以看到开发板上的灯全亮了,执行./first_drv_test 1时,灯全灭,说明驱动程序编写成功了。
    在看到自己跟着视频里写好的代码烧到开发板上能正常运行时,心里是说不出的高兴,由于视频里的代码都是一条一条当场写出来的,讲解也非常清晰、易懂,让自己对驱动的编写有了更深入的了解,同时非常期望韦大神能尽早推出自己的后期3G无线上网,wifi等驱动视频!!!