linux下字符驱动示例helloworld
程序员文章站
2022-07-14 09:46:18
...
1:最简单的驱动框架
hello.c
/*************************************************************************
> File Name: hello.c
> Author: kayshi
> Mail: aaa@qq.com
> Created Time: Thu 24 Sep 2020 11:25:50 AM CST
************************************************************************/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
static int hello_init(void)
{
printk("this is hello\n");
return 0;
}
static void hello_exit(void)
{
printk("this is end\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
Makefile
ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
$(info "2nd")
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
all:
$(info "1st")
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.symvers *.mod.c *.mode.o *.order
endif
加载:
sudo insmod hello.ko
查看:
lsmod
删除:
sudo rmmod hello
查看打印信息:
demsg
2:进行字符设备注册
补全代码hello.c
/*************************************************************************
> File Name: hello.c
> Author: kayshi
> Mail: aaa@qq.com
> Created Time: Thu 24 Sep 2020 11:25:50 AM CST
************************************************************************/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
static int major = 300;
static int minor = 0;
static dev_t devno;
static struct cdev cdev;
static int hello_open(struct inode *inode, struct file *filep)
{
printk("hello open\n");
return 0;
}
static struct file_operations hello_ops=
{
.open = hello_open,
};
static int hello_init(void)
{
int ret;
printk("hello_init\n");
devno = MKDEV(major, minor);
ret = register_chrdev_region(devno, 1, "hello");
if(ret < 0)
{
printk("register_chrdev_region faile\n");
return ret;
}
cdev_init(&cdev, &hello_ops);
ret = cdev_add(&cdev, devno, 1);
if(ret < 0)
{
printk("cdev_add faile \n");
return ret;
}
return 0;
}
static void hello_exit(void)
{
cdev_del(&cdev);
unregister_chrdev_region(devno, 1);
printk("hello_exit\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
编译执行后
查看信息
cat /proc/devices
如果再insmod时出现了下面的情况
这是因为代码中的主设备号已经被使用了。把设备号改大一点就行
此时/dev/没有出现设备
需要通过命令
sudo mknod /dev/hello c 300 0
来创建设备,再查看
测试代码
/*************************************************************************
> File Name: test.c
> Author: kayshi
> Mail: aaa@qq.com
> Created Time: Thu 24 Sep 2020 02:47:37 PM CST
************************************************************************/
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
void main()
{
int fd;
fd = open("/dev/hello", O_RDWR);
if(fd < 0)
{
perror("open faile \n");
return ;
}
close(fd);
}
执行测试代码后
再用dmesg查看log信息
hello open被打印,说明hello_open这个函数被调用了
3 添加读写操作
在驱动中添加读写函数。重新生成并insmod
/*************************************************************************
> File Name: hello.c
> Author: kayshi
> Mail: aaa@qq.com
> Created Time: Thu 24 Sep 2020 11:25:50 AM CST
************************************************************************/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
static int major = 300;
static int minor = 0;
static dev_t devno;
static struct cdev cdev;
static ssize_t hello_write(struct file *f, const char __user *u, size_t s, loff_t *l)
{
printk("hello write");
return 0;
}
static ssize_t hello_read(struct file *f, char __user *u, size_t s, loff_t *l)
{
printk("hello read");
return 0;
}
static int hello_open(struct inode *inode, struct file *filep)
{
printk("hello open\n");
return 0;
}
static struct file_operations hello_ops=
{
.open = hello_open,
.write = hello_write
.read = hello_read,
};
static int hello_init(void)
{
int ret;
printk("hello_init\n");
devno = MKDEV(major, minor);
ret = register_chrdev_region(devno, 1, "hello");
if(ret < 0)
{
printk("register_chrdev_region faile\n");
return ret;
}
cdev_init(&cdev, &hello_ops);
ret = cdev_add(&cdev, devno, 1);
if(ret < 0)
{
printk("cdev_add faile \n");
return ret;
}
return 0;
}
static void hello_exit(void)
{
cdev_del(&cdev);
unregister_chrdev_region(devno, 1);
printk("hello_exit\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit)
在测试代码中添加读写测试
/*************************************************************************
> File Name: test.c
> Author: kayshi
> Mail: aaa@qq.com
> Created Time: Thu 24 Sep 2020 02:47:37 PM CST
************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
void main()
{
int fd;
char buf[8] = {0};
fd = open("/dev/hello", O_RDWR);
if(fd < 0)
{
perror("open faile \n");
return ;
}
write(fd, buf, sizeof(buf));
read(fd, buf, sizeof(buf));
close(fd);
}
dmesg查看信息
读写函数的打印信息都出现了