免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1327 | 回复: 0
打印 上一主题 下一主题

Linux设备驱动程序的使用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-20 12:42 |只看该作者 |倒序浏览

Linux 2.4的内核下驱动编译出来的名字通常是*.o的文件,而在Linux 2.6的内核下编译出来的文件是*.ko的文件。在编译驱动的时候,注意要在编译的时候加__DKERNEL__和_DMODULE参数。还要注意在 makefile 文件里面正确地指定 KERNELDIR 和INCLUDEDIR。驱动程序有两种加载方式,内核自动加载和手动加载。通常的做法是在调试过程中采用手动加载的方式,等调试好了之后,就可以编译到内核里面采用自动加载的方式。驱动相对于内核来说就是内核的模块。
内核驱动模块的加载命令用insmod,如insmod mydriver.o。这个命令其实就是调用驱动里面的mydriver_init()函数。用insmod命令将编译好的模块调入内存时,就是向系统的字符设备表登记了一个字符设备。如果登记成功,返回设备的主设备号,不成功,返回一个负值。那么内核驱动模块的卸载就是调用rmmod mydriver,这是调用驱动里面的mydriver_exit()函数,它释放字符设备test在系统字符设备表中占有的表项。当然,上层如果要访问内核的驱动模块,还需要在dev目录下添加设备访问节点,在dev目录下执行mknod c主设备号从设备号:
mknod mydriver c 10 174
从设备号可以从0-254,主设备号在include/linux/major.h文件里可以看到具体的定义,在include/linux/miscdevices.h文件里可以看到从设备号的一些定义,在定义自己的设备号的时候注意不要和系统内核中原有的设备号冲突。
另外一点需要注意如果使用了devfs文件系统的话,设备节点的目录是不同的。设备的访问节点要改成/dev/misc/mydriver。可以通过查看编译出来的 system.map 文件或 cat /proc/ksyms查看底层驱动导出的函数。
当内核加载了驱动之后,上层就可以通过驱动对底层设备进行操作了。如下所示的代码是一个简单的对mydriver进行读写和ioctl的例子。
test.c
#include
#include
#include
#include
#include
#include
#if 0
#define DEV_MYDRIVER    "/dev/misc/mydriver"
#else
#define DEV_MYDRIVER     "/dev/mydriver"
#endif
#define MYDRIVER_IOC_RESET   
_IO(MYDRIVER_IOC_MAGIC, MYDRIVER_IOC_BASE + 5)
int dev_cmd(const char * dev, int cmd, unsigned long arg)
{
    int  fd;
    fd = open(dev, O_RDWR);
    if ( fd     {
        perror(dev);
        return -1;
    }
    ioctl(fd, cmd, arg);
    close(fd);
    return 0;
}
void test_ioctl(void)
{
   dev_cmd(DEV_MYDRIVER,MYDRIVER_IOC_RESET,0);
}
void test_mydriver(void)
{
    int   i, j;
    int   fd;
    char  buf[34];
    i = 0;
    while ( 1 )
    {
        i++;
        printf("\n***** count: %d *****\n", i);
        fd = open(DEV_MYDRIVER, O_RDWR);
        for ( j = 0; j         {
            read(fd, buf, sizeof(buf));
            write(fd, buf, sizeof(buf));
        }
        close(fd);
    }
}
int main(int argc, char * argv[])
{
    if ( argc     {
        printf("test \n");
        return 1;
    }
    switch ( argv[1][0] )
    {
        case 'a':
            test_mydriver();
            break;
        case 'c':
            test_ioctl ();
            break;
    }
    return  0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/110576/showart_2182782.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP