Linux创建字符设备的过程可以为以下:Linux系统下如何完整地创建一个字符设备文件?
摘要:Linux创建字符设备 驱动程序主要包括以下几个关键部分: 注册设备号和 cdev 实现 file_operations 结构体(包含 readwrite 等操作) 创建设备类和设备节点 资源释放和模块卸载 file_operatio
Linux创建字符设备
驱动程序主要包括以下几个关键部分:
注册设备号和 cdev
实现 file_operations 结构体(包含 read/write 等操作)
创建设备类和设备节点
资源释放和模块卸载
file_operations 结构体模板:
static struct file_operations mydev_fops = {
.owner = THIS_MODULE, // 模块所有者(必须填写)
.open = mydev_open, // 打开操作(自己实现的函数)
.release = mydev_release, // 关闭/释放
.read = mydev_read, // 读操作
.write = mydev_write, // 写操作
// 可以根据需要实现ioctl、poll等
};
程序实践
Makefile
export ARCH=arm64
#需要先设置交叉编译器环境变量(可以参考我另一篇博客https://www.cnblogs.com/tianwuyvlianshui/p/19571779)
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += mychardev.o
KDIR := $(HOME)/Desktop/SDK/kernel
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) \
ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
make -C $(KDIR) M=$(PWD) clean
mychardev.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>
// 设备名和类名的宏定义
#define DEV_NAME "device_test" // 设备节点名称
#define CLASS_NAME "class_test" // 设备类名称
static dev_t dev_num; // 保存设备号
static struct cdev cdev_test; // 字符设备结构体
static struct class *class_test; // 设备类指针
// 打开设备时调用的函数
// inode: 指向文件的 inode 结构体指针
// file: 文件结构体指针
static int chrdev_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "mychardev: chrdev_open called\n"); // 打印打开信息到内核日志
return 0; // 返回0表示成功
}
// 读设备时调用的函数
// file: 文件结构体指针
// buf: 用户空间的缓冲区指针
// size: 期望读取的字节数
// off: 偏移量指针
static ssize_t chrdev_read(struct file *file, char __user *buf, size_t size, loff_t *off)
{
printk(KERN_INFO "mychardev: chrdev_read called\n"); // 打印读操作信息
return 0; // 返回0表示没有数据可读
}
// 写设备时调用的函数
// file: 文件结构体指针
// buf: 用户空间的缓冲区指针
// size: 要写入的字节数
// off: 偏移量指针
static ssize_t chrdev_write(struct file *file, const char __user *buf, size_t size, loff_t *off)
{
printk(KERN_INFO "mycharde
