手把手教你学linux驱动开发”OK6410系列之02---虚拟字符设备


上一篇文章我们介绍了如何在linux下编写一个模块,并加载到内核空间。通过实验我们了解了大体的流程以及模块的工作原理。本篇文章我们将介绍如何编写一个虚拟的字符设备驱动程序。

        之所以称之为虚拟字符设备驱动程序,主要原因是该驱动程序并没有真正操作外部设备,只是一个字符设备驱动程序框架,这为后面我们开发正是设备的驱动程序(LED、蜂鸣器等)奠定了基础。

       作者:沧海猎人   出处:http://blog.csdn.net/embedded_hunter   转载请注明出处   嵌入式技术交流QQ群:179012822

 

 一、实验环境 

开发机环境

          操作系统:ubuntu 9.10

          交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/arm/4.3.2/

          6410板子内核源码路径:/work/linux-2.6.36.2-v1.05/      

目标板环境:OK6410-A     linux2.6.36

 

二、实验原理

          在linux系统中,我们经常听到说“一切都是文件”。我们对设备操作就转换为对文件的操作。那么我们在用户空间对文件的操作包括open、read、write、close等。那么在驱动程序中如何响应用户发出来的文件操作请求呢?

        通过本实验先了解一下大体的过程,之后我会渐渐向大家介绍具体的细节。

 

三、实验步骤

1、编写驱动程序

driver_char.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h> /* copy_to_user,copy_from_user */
#define MY_MAJOR 240
  
int  my_open ( struct  inode *inode, struct  file *filp)
{
     printk( "#########open######\n" );
     return  0;
}
  
ssize_t my_read ( struct  file *filp,  char  __user *buf,  size_t  count,loff_t *f_pos)
{
     printk( "#########read######\n" );
     return  count;
}
  
ssize_t my_write ( struct  file *filp,  const  char  __user *buf,  size_t  count,loff_t *f_pos)
{
     printk( "#########write######\n" );
     return  count;
}
  
int  my_release ( struct  inode *inode,  struct  file *filp)
{
     printk( "#########release######\n" );
     return  0;
}
  
struct  file_operations my_fops ={
     .owner = THIS_MODULE,
     .open = my_open,
     .read = my_read,
     .write = my_write,
     .release = my_release,
};
  
int  __init my_init ( void )
{
     int  rc;
     printk ( "Test char dev\n" );
     rc = register_chrdev(MY_MAJOR, "my" ,&my_fops);
     if  (rc <0)
     {
         printk ( "register %s char dev error\n" , "my" );
         return  -1;
     }
  
     printk ( "ok!\n" );
     return  0;
}
  
void  __exit my_exit ( void )
{
     unregister_chrdev(MY_MAJOR, "my" );
     printk ( "module exit\n" );
}
  
MODULE_LICENSE( "GPL" );
module_init(my_init);
module_exit(my_exit);

Makefile文件

1
2
3
4
5
6
7
8
obj-m := driver_char.o
KDIR :=/work/linux-2.6.36.2-v1.05/
all:
     make -C $(KDIR) M=$(shell pwd) modules
install:
     cp driver_char.ko /tftpboot/
clean:
     make -C $(KDIR) M=$(shell pwd) clean

2、编写测试程序

test.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int  main ( void )
{
     int  fd;
     char  buf[10]={0,1};
     char  buf2[10];
     fd = open( "/dev/my_char" ,O_RDWR);
     if  (fd < 0)
     {
         printf  ( "Open /dev/my_char" );
         return  -1;
     }
     write(fd,buf,2);
     read(fd,buf2,2);
     close (fd);
     return  0;
}

3、编译驱动程序与测试程序

      编译驱动程序

      #make

      将驱动程序放到tftp的工作目录 /tftpboot

      #make install

      编译测试程序

      #arm-linux-gcc  test.c  -o  test

      将测试程序放到tftp的工作目录 /tftpboot

       #cp  test  /tftpboot

 

4、将程序下载到开发板

        将开发板的IP地址修改,与主机在同一个网段。确保PC的tftp服务开启。

     下载程序到开发板

        SMDK6410#   tftp -l /lib/modules/2.6.36.2/driver_char.ko -r  driver_char.ko  -g  192.168.1.111        192.168.1.111为服务器IP

        SMDK6410#   tftp -l test  -r test  -g  192.168.1.111         

 

5、测试

        加载驱动   #insmod  /lib/modules/2.6.36.2/driver_char.ko

        创建设备文件   #mknod  /dev/my_char  c   240  0

        测试  ./test

        [root@FORLINX6410]# ./test
        #########open######
         #########write######
        #########read######
         #########release######

    

       卸载驱动  #rmmod   driver_char

       从上面的结果我们可以看到,当用户调用相应的文件操作函数时,驱动程序中的相应的函数也会被调用。

        大家可以修改相应程序,测试一下其他的情况。

 

作者:沧海猎人   出处:http://blog.csdn.net/embedded_hunter   转载请注明出处   嵌入式技术交流QQ群:179012822

 

备注: 本驱动使用了最基本的内核函数,可能操作方法与你看过的其他驱动程序不太一样,尤其注册字符设备的函数。   没关系,我们会一步一步介绍相关的其他函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值