没有开发板在Ubuntu下体验Linux驱动开发之字符设备框架实验

在之前的实验中我们在没有开发板的情况下,实现了在Ubuntu虚拟机中进行基本驱动开发。具体可以参考《没有开发板如何在Ubuntu中体验Linux驱动开发》。在此基础上,我们就可以来进行字符设备框架的验证实验。

第一步,驱动程序编写

在test文件夹下创建app子目录,用于存放测试 app,创建驱动程序文件及Makefile。编写字符设备驱动,实现字符设备的注册,设备节点的创建以及文件操作集等。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>

static int chrdev_open(struct inode *inode, struct file *file)
{
    printk("char device open success!!! \n");
    return 0;
}
static ssize_t chrdev_read(struct file *file,char __user *buf, size_t size, loff_t *off)
{
    printk("char device read success!!! \n");
    return 0;
}
static ssize_t chrdev_write(struct file *file,const char __user *buf,size_t size,loff_t *off)
{
    printk("char device write success!!! \n");
    return 0;
}
static int chrdev_release(struct inode *inode, struct file *file)
{
    printk("char device release success!!! \n");
    return 0;
}

static dev_t dev_num; //定义 dev_t 类型变量 dev_num 来表示设备号
static struct cdev cdev_test; //定义名为 cdev_test 的字符设备
static struct file_operations cdev_fops_test = {
    .owner = THIS_MODULE,
    .open = chrdev_open,
    .read = chrdev_read,
    .write = chrdev_write,
    .release = chrdev_release,
}; //填充file_operations 
static struct class *class_test;
static int __init chrdev_fops_init(void) //驱动入口函数
{
    int ret;
    int major,minor;//定义主设备号和次设备号 
    ret = alloc_chrdev_region(&dev_num,0,1,"device_test");
    if (ret < 0)
   {
        printk("alloc_chrdev_region is error \n");
    }
    printk("alloc_chrdev_region success!!! \n");
    major = MAJOR(dev_num);
    minor = MINOR(dev_num);
    printk("major is %d\n minor is %d \n",major,minor);
    cdev_init(&cdev_test,&cdev_fops_test); //初始化字符设备 
    cdev_test.owner = THIS_MODULE;
    ret = cdev_add(&cdev_test,dev_num,1); //进行字符设备的添加
    if (ret < 0)
   {
        printk("cdev_add is error \n");
    }
    printk("cdev_add success!!! \n");
    class_test = class_create(THIS_MODULE,"class_test");
    device_create(class_test,NULL,dev_num,NULL,"cdev_test");//进行设备的创建,设备名称为 cdev_test
    return 0;
}
static void __exit chrdev_fops_exit(void) //驱动出口函数
{
    device_destroy(class_test,dev_num); 
    class_destroy(class_test);
    cdev_del(&cdev_test); //删除添加的字符设备 cdev_test
    unregister_chrdev_region(dev_num,1); //释放字符设备所申请的设备号
    printk("module exit \n");
}

module_init(chrdev_fops_init);//注册入口函数
module_exit(chrdev_fops_exit);//注册出口函数
MODULE_LICENSE("GPL v2");//同意 GPL 开源协议
MODULE_AUTHOR("tester");//作者信息

修改Makefile中的文件名,obj-m += cdev_test.o,其余不变。编译通过结果如下

第二步,编写测试app

Linux下一切皆文件,在app目录下创建app.c文件,此为应用层测试程序,实现对文件操作集函数功能,通过调用文件操作函数实现对字符设备的操作。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>


int main(int argc,char *argv[])
{
    int fd; //定义文件描述符
    char buf[32];
    fd=open(argv[1],O_RDWR,0666);//调用 open 函数打开文件,权限为可读可写
    if(fd<0){
        printf("open is error\n");
        return -1;
    }
    printf("open is ok\n");
    if(!strcmp(argv[2], "read")){
    read(fd,buf,32);
    }
    else if(!strcmp(argv[2], "write")){
    write(fd,"hello\n",6);
    }
    close(fd); //调用 close 函数,取消文件的映射
    return 0;
}

在app目录下使用 gcc -o app app.c 命令编译生成名为app的可执行文件。

第三步,驱动加载测试

加载驱动模块,可以看出成功打印出系统分配的主设备号及次设备号。

运行测试app,并传入read及write进行测试,结果如下

总结:可以看出,在Ubuntu虚拟机上成功完成了字符设备的基本框架实验,这里在文件操作集中只是简单打印了一些提示信息,后续可以配合硬件加入不同的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值