使用独立的 c++ 程序处理用 C 编写的字符设备驱动程序

Handling character device drivers written in c using standalone c++ programs

本文关键字:字符 设备驱动程序 程序 独立 c++ 处理      更新时间:2023-10-16

我正在开发一个基于 Linux 字符设备驱动程序的项目,我是实现设备驱动程序的新手。我已经使用了文件file_operations结构并在其上定义了自己的函数,如下所述。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define  DEVICE_NAME "char_Driver"
#define  CLASS_NAME  "chrDev"
MODULE_LICENSE("GPL");
static int    majorNumber;
static char   message[128] = {0};
static int    numberOpens = 0;
static struct class*  charClass  = NULL;
static struct device* charDevice = NULL;
static int     dev_open(struct inode *, struct file *);
static int     dev_release(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *, size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release,
};
static int __init char_init(void){
printk(KERN_INFO "Char_Driver: Initializing the CharDriver LKMn");
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
printk(KERN_INFO "char_Driver: registered correctly with major number %dn", majorNumber);
charClass = class_create(THIS_MODULE, CLASS_NAME);
charDevice = device_create(charClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
return 0;
}
static void __exit char_exit(void){
device_destroy(charClass, MKDEV(majorNumber, 0));
class_unregister(charClass);
class_destroy(charClass);
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_INFO "Char_Driver: LKM Unloaded!n");
}
static int dev_open(struct inode *inodep, struct file *filep){
numberOpens++;
printk(KERN_INFO "Char_Driver: Device has been opened %d timesn", numberOpens);
return 0;
}
ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset){
size_t ret = copy_to_user(buffer, message, len);
printk(KERN_INFO "Char_Driver: Sent %zu characters to the usern", len);
return ret;
}
ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
size_t ret = copy_from_user(message,buffer,len);
printk(KERN_INFO "Char_Driver: Received %zu characters from the usern", len);
return ret;
}
static int dev_release(struct inode *inodep, struct file *filep){
printk(KERN_INFO "Char_Driver: Device successfully closedn");
return 0;
}
module_init(char_init);
module_exit(char_exit);

并且我在内核模块加载时自动在/dev 目录中创建一个名为"char_driver"的字符设备文件。

我的问题是当我使用 c 程序从设备文件中写入和读取时,它工作正常。但是当我使用以下程序访问该设备驱动程序时C++也会发生同样的事情。内核无限记录"Char_Driver:从用户那里收到 5 个字符"消息。

#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
using namespace std;
static fstream dev_file;
#define BUFFER_LENGTH 128
static char receive[BUFFER_LENGTH];
int main(){
int ret;
char stringToSend[BUFFER_LENGTH];
cout << "Starting device test code example...n";
dev_file.open("/dev/char_Driver", ios::out);
if (!dev_file){
cout << "Failed to open the device...n";
return -1;
}
cout << "Type in a short string to send to the kernel module:n";
cin >> stringToSend;
cout << "Writing message to the device [" << stringToSend << "]n";
dev_file.write(stringToSend, strlen(stringToSend));
dev_file.close();
cout << "Press ENTER to read back from the device...n";
getchar();

cout << "file closed successfully..n";
dev_file.open("/dev/char_Driver", ios::in);
cout << "Reading from the device...n";
dev_file.read(receive, BUFFER_LENGTH);
if (ret < 0){
cout << "Failed to read the message from the device.n";
return -1;
}
printf("The received message is: [%s]n", receive);
printf("End of the programn");
dev_file.close();
return 0;
}

下面提到了我对上述c ++程序的预期输出,它非常适合普通文件(* .txt,*.sh等(。

Starting device test code example...
Type in a short string to send to the kernel module:
test
Writing message to the device [test]
Press ENTER to read back from the device...
file closed successfully..
Reading from the device...
The received message is: [test]
End of the program

但目前的输出是,

Starting device test code example...
Type in a short string to send to the kernel module:
test
Writing message to the device [test]

和无限的内核日志。 还有一件事,当我使用时,

echo 'test' >> /dev/char_Driver "

命令内核也无限记录"Char_Driver:从用户收到 5 个字符"。 您的帮助非常可观。

从这个copy_from_user参考:

返回无法复制的字节数。成功时,这将为零

[强调我的]

dev_write函数应返回它"接受"的字节数(或负错误代码(,而不是零。

换句话说,它应该返回len而不是ret