内核文件virtual_traffic_light.c:
// virtual_traffic_light.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define DEVICE_NAME "traffic_light"
static int light_status = 0; // 0: 红灯亮,1: 绿灯亮
static int device_open(struct inode *inode, struct file *file) {
return 0;
}
static int device_release(struct inode *inode, struct file *file) {
return 0;
}
static ssize_t device_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) {
// 读取灯的状态并传递到用户空间
if (copy_to_user(buffer, &light_status, sizeof(light_status)) != 0) {
return -EFAULT; // 复制失败
}
return sizeof(light_status);
}
static ssize_t device_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) {
// 从用户空间获取灯的状态
if (copy_from_user(&light_status, buffer, sizeof(light_status)) != 0) {
return -EFAULT; // 复制失败
}
return sizeof(light_status);
}
static struct file_operations fops = {
.open = device_open,
.release = device_release,
.read = device_read,
.write = device_write,
};
static int __init traffic_light_init(void) {
// 注册字符设备驱动程序
register_chrdev(0, DEVICE_NAME, &fops);
printk(KERN_INFO "Traffic Light module loaded.\n");
return 0;
}
static void __exit traffic_light_exit(void) {
// 注销字符设备驱动程序
unregister_chrdev(0, DEVICE_NAME);
printk(KERN_INFO "Traffic Light module unloaded.\n");
}
module_init(traffic_light_init);
module_exit(traffic_light_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Linux device driver for controlling a virtual traffic light.");
qt文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QMessageBox>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 打开设备文件
fd = ::open("/dev/traffic_light",O_RDWR);
if(fd < 0)
{
QMessageBox::critical(this, "Error", "Unable to open device file.");
qDebug()<<"open /dev/traffic_light failed";
qApp->exit(-1);
}
}
MainWindow::~MainWindow()
{
delete ui;
// 关闭设备文件
::close(fd);
}
void MainWindow::on_pushButton_clicked()
{
// 控制红灯亮
int lightStatus = 0;
}
void MainWindow::on_pushButton_2_clicked()
{
// 控制绿灯亮
int lightStatus = 1;
}
首先make后加载内核:insmod traffic_light.ko;添加设备:sudo mknod /dev/traffic_light c 240 0
问题描述都加载成功:
但qt运行时无法打开设备:
解决办法:把设备节点权限改成777
crw-r--r-- 1 root root 240, 0 1月 24 11:00 /dev/traffic_light
root@szdjg-virtual-machine:~# chmod 777 /dev//traffic_light