平台:树莓派4B
编译工具:ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置。
步骤:在驱动初始化的代码里调用class_create(…)为该设备创建一个class,再为每个设备调用device_create(…)创建对应的设备。
驱动代码
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/err.h>
#include <linux/mm_types.h>
#include <asm/uaccess.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/kern_levels.h>
#include <linux/ioport.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/uaccess.h>
static struct class *test_class;
static struct device *test_class_dev;
static dev_t devno;
static int major = 231;
static int minor = 0;
static char *module_name = "test";
static ssize_t test_write(struct file* file, const char __user * buf, size_t size, loff_t* ppos)
{
printk("test_write\n");
return 0;
}
static ssize_t test_read(struct file* file, char __user * buf, size_t size, loff_t* ppos)
{
printk("test_read\n");
return 0;
}
static int test_open(struct inode* inode, struct file* filp)
{
printk("test_open\n");//内核的打印函数
return 0;
}
//在内核源码查找struct file_operations看结构体成员,添加用到的函数
static struct file_operations test_fops = {
.owner = THIS_MODULE,
.write = test_write,//函数指针
.open = test_open,
.read = test_read,
};
static int __init test_init(void)//驱动入口
{
int ret;
pr_info("test init");
devno = MKDEV(major,minor);//创建设备号
ret = register_chrdev(major,module_name,&test_fops);//注册驱动,把这个驱动加入到内核链表
test_class = class_create(THIS_MODULE,"myfirstdemo");//代码自动生成设备
test_class_dev = device_create(test_class,NULL,devno,NULL,module_name);//创建设备文件
return 0;
}
static void __exit test_exit(void)
{
pr_info("test exit");
device_destroy(test_class,devno);//销毁设备
class_destroy(test_class);//销毁类
unregister_chrdev(major,module_name);//卸载设备
}
module_init(test_init);//入口,是个宏
module_exit(test_exit);
MODULE_LICENSE("GPL v2");
用户程序:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("/dev/test",O_RDWR);
if(fd < 0){
printf("open failed\n");
}else{
printf("open success\n");
}
fd = write(fd,'1',1);
close(fd);
return 0;
}
编译
aarch64-linux-gnu-gcc test.c -o test
在/dev下生成设备节点:
/mnt # ls -l /dev/test
crw-rw---- 1 root 0 231, 0 Jan 1 04:07 /dev/test
运行:./text
查看内核打印:dmesg
删除驱动
列出驱动模块:lsmod
删除驱动模块:rmmod 驱动模块名(lsmod出来的模块名)