歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> Linux字符設備驅動——初體驗

Linux字符設備驅動——初體驗

日期:2017/3/3 12:38:30   编辑:Linux技術

以下是一個非常簡單的Linux字符設備驅動  *^_^*

【驅動程序myChrDrv.c】

[code]#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>

static int myChrDrv_open(struct inode *inod, struct file *fp)
{
    printk(KERN_INFO "myChrDrv_open()\n");
    return 0;
}

static int myChrDrv_close(struct inode *inod, struct file *fp)
{
    printk(KERN_INFO "myChrDrv_close()\n");
    return 0;
}

static struct file_operations fops = {
    .open = myChrDrv_open,
    .release = myChrDrv_close,
};

static int __init myChrDrv_init(void)
{
    printk(KERN_INFO "myChrDrv_init()\n");
    int ret;
    // 創建並向內核注冊字符設備simple_chrdev
    ret = register_chrdev(250, "simple_chrdev", &fops);
    return 0;
}

static void __exit myChrDrv_exit(void)
{
    printk(KERN_INFO "myChrDrv_exit()\n");
    unregister_chrdev(250, "simple_chrdev");
}

module_init(myChrDrv_init);
module_exit(myChrDrv_exit);

MODULE_LICENSE("Dual BSD/GPL");
【驅動程序Makefile】

[code]obj-m += myChrDrv.o

#CROSS_COMPILE = /usr/local/arm/arm-2010.09/bin/arm-none-linux-gnueabi-
#CC = $(CROSS_COMPILE)gcc
#KDIR   := /home/walle/arm/arm_os/kernel/linux-3.10.10

KDIR := /lib/modules/`uname -r`/build

default:
    $(MAKE) -C $(KDIR) M=`pwd` modules

clean:
    $(MAKE) -C $(KDIR) M=`pwd` modules clean
【應用程序app.c】

[code]#include <stdio.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd;
    fd = open("/dev/simple_chrdev", O_RDWR);

    if(fd < 0){
        printf("open /dev/simple_chrdev failed.\n");
        return -1;
    }
    printf("open /dev/simple_chrdev successed.\n");

    close(fd);
    return 0;
}
執行命令 make,編譯生成驅動模塊 myChrDrv.ko。

執行命令 insmod myChrDrv.ko,加載驅動模塊。 執行命令 lsmod,確認模塊加載成功,輸出如下:

[code]Module                  Size  Used by
myChrDrv               12478  0
或執行命令 cat /proc/modules | grep myChrDrv,輸出如下:

[code]myChrDrv 12478 0 - Live 0xf8d28000 (O)
執行命令 dmesg | tail,查看模塊初始化打印信息,輸出如下:

[code][850978.514035] myChrDrv_init()
執行命令 gcc app.c -o app,編譯生成應用程序 app。

執行命令 ./app,運行 app,出錯:

[code]open /dev/simple_chrdev failed.

雖然驅動程序初始化函數中有“register_chrdev(250, “simple_chrdev”, &fops);”,函數 register_chrdev 的作用是申請主設備號250、綁定操作相關函數 fops、向內核注冊設備名為 simple_chrdev 的設備。顯然此時系統中並不存在 /dev/simple_chrdev,因此需要執行命令“mknod /dev/simple_chrdev c 250 0”手動創建該設備節點。

mknod 的格式是:mknod [OPTION]… NAME TYPE [MAJOR MINOR]。命令中的“c”表示字符設備;“250”是主設備號,與驅動程序中手動申請的主設備號一致;“0”是次設備號,這裡也可以不設為0,只需要主設備號對應得上就行,因為主設備號指定的是驅動,次設備號指定的是具體設備。

另外文件“/dev/simple_chrdev”要與 app.c 中 open 函數打開的文件一致,所以如果 open 指定的文件是“hello”,mknod 命令創建“hello”即可。這裡之所以用“/dev/simple_chrdev”主要是為了讓它看起來像一個設備。

OK,我們執行命令 ls -l /dev/simple_chrdev,確認設備節點創建成功,輸出如下:

[code]crw-r--r-- 1 root root 250, 0  5月 18 22:34 /dev/simple_chrdev

再次執行命令 ./app,運行 app,成功:

[code]open /dev/simple_chrdev successed.

執行命令 dmesg | tail,查看驅動程序打印信息,輸出如下:

[code][854089.294682] myChrDrv_open()
[854089.294855] myChrDrv_close()

可以看到,應用程序 app 的 open 和 close 函數最終調用了驅動程序 myChrDrv 的 open 和 release 函數。

執行命令 rmmod myChrDrv,卸載 myChrDrv 驅動。 執行命令 dmesg | tail,查看驅動程序打印信息,輸出如下:

[code][854555.685634] myChrDrv_exit()
執行命令 rm /dev/simple_chrdev,移除設備節點。

Linux字符設備驅動的初體驗完畢  *>_<*

Copyright © Linux教程網 All Rights Reserved