Chinaunix首页 | 论坛 | 博客
  • 博客访问: 208535
  • 博文数量: 32
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 850
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-22 15:50
文章存档

2014年(16)

2013年(16)

分类: 嵌入式

2013-12-01 19:36:47

            初试s3c2440驱动程序
开发环境
    
                SYSTEM       :  Ubuntu-12.04

                Board        :  Mini2440-t35
                Bootloader   :  u-boot-1.1.6
                Kernel       :  Linux-2.6.22.6
                CROSS_COMPILE: arm-linux-gcc v3.4.5
一、搭建程序框架

点击(此处)折叠或打开

  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/init.h>
  4. #include <linux/fs.h>

  5. #define    DEVICE_NAME        "hello_drv"

  6. static struct file_operations hello_drv_fops = {
  7.     .owner = THIS_MODULE,
  8. };
  9. static int hello_drv_init(void)
  10. {
  11.     //int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)
  12.     register_chrdev(111,DEVICE_NAME,&hello_drv_fops);    //使用register_chrdev注册字符设备
  13.     return 0;
  14. }

  15. static int hello_drv_exit(void)
  16. {
  17.     unregister_chrdev(111, DEVICE_NAME);
  18. }

  19. module_init(hello_drv_init);
  20. module_exit(hello_drv_exit);
  21. MODULE_LICENSE("GPL");
Makefile内容:

点击(此处)折叠或打开

  1. KERN_DIR = /home/wangtisheng/work/kernel/linux-2.6.22.6-mini2440
  2. all:
  3. make -C $(KERN_DIR) M=`pwd` modules
  4. clean:
  5. make -C $(KERN_DIR) M=`pwd` modules clean
  6. rm -rf modules.order
  7. obj-m    += hello_drv.o
二、编译测试

    
执行make即可得到hello_drv.ko模块
        将模块拷贝至根文件系统根目录,我的开发板mini2440采用NFS方式挂载根文件系统。
        在mini2440执行insmod命令加载驱动模块
            # insmod hello_drv.ko
       查看模块式否加载           
            # lsmod  
       执行如下命令即可看到设备号为111的驱动模块hello_drv  
            # cat /proc/devices

三、构造file_operations结构体hello_drv_fops中的各函数,本实例只是构造了open、write函数,在file_operations hello_drv_fops添加open、write函数。

点击(此处)折叠或打开

  1. static int hello_drv_open(struct inode *inode, struct file *file)
  2. {    
  3.     printk("Hello_Drv_Open!\n");
  4.     return 0;
  5. }
  6. static ssize_t hello_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
  7. {
  8.     printk("Hello_Drv_Write!\n");
  9.     return 0;
  10. }
  11. static struct file_operations hello_drv_fops = {
  12.     .owner = THIS_MODULE,
  13.     .open = hello_drv_open,
  14.     .write = hello_drv_write,
  15. };
    驱动程序编译:
    执行make可得到驱动程序模块hello_drv.ko

四、
测试驱动程序hello_drv_test.c

点击(此处)折叠或打开

  1. #include <fcntl.h>
  2. #include <stdio.h>
  3. int main()
  4. {
  5.     int fd;
  6.     int val = 1;
  7.     fd = open("dev/hello_drv",O_RDWR);
  8.     if(fd < 0)
  9.         printf("Can't Open!\n");
  10.     write(fd,&val,4);
  11.     return 0;
  12. }
        执行如下命令即可得到测试程序的可执行文件:
                arm-linux-gcc -o hello_drv_test hello_drv_test.c
五、驱动加载、测试
        将模块hello_drv.ko和测试程序hello_drv_test拷贝至根文件系统根目录,我的开发板mini2440采用NFS方式挂载根文件系统。
        挂载模块
            # insmod hello_drv.ko
            # cat /proc/devices
        至此即可看到驱动程序已挂载如下:
            111 hello_drv
        创建该设备节点
           mknod /dev/hello_drv c 111 0
        执行测试程序hello_drv_test
            ./hello_drv_test
        结果如下:
             Hello_Drv_Open!
             Hello_Drv_Write!

六、总结
    来自《嵌入式Linux应用开发完全手册》。
编写字符驱动程序的过程大概如下:
    1.    编写驱动程序初始化函数。
           进行必要的初始化、包括硬件初始化、向内核注册驱动程序等。
    2.    构造file_operations结构中要用到的各个成员函数。   
一般来说,编写一个Linux设备驱动程序的大致流程如下。
    (1)   查看原理图、数据手册,了解设备的操作方法。
    (2)   在内核中找到相近的驱动程序,以它为模板进行开发,有时候需要从零开始。
    (3)   实现驱动程序的初始化:比如向内核注册这个驱动程序,这样应用程序传入文件名时,内核才能找到相应的驱动程序。
    (4)   设计所要实现的操作,比如open、close、read、write等函数。
    (5)   实现终端服务(中断并不是每个设备驱动所必须)。
    (6)   编译驱动到内核中,或者用insmod命令加载。
    (7)   测试驱动程序。
阅读(1578) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~