c++ - 使用独立的 c++ 程序处理用 c 编写的字符设备驱动程序
问题描述
我正在开发一个基于 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 LKM\n");
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
printk(KERN_INFO "char_Driver: registered correctly with major number %d\n", 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 times\n", 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 user\n", 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 user\n", len);
return ret;
}
static int dev_release(struct inode *inodep, struct file *filep){
printk(KERN_INFO "Char_Driver: Device successfully closed\n");
return 0;
}
module_init(char_init);
module_exit(char_exit);
当内核模块加载时,我会自动在 /dev 目录中创建一个名为“char_driver”的字符设备文件。
我的问题是当我使用 ac 程序从设备文件中写入和读取时,它工作得很好。但是当我使用以下 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 program\n");
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 个字符”。您的帮助非常可观。
解决方案
返回无法复制的字节数。成功后,这将为零。
[强调我的]
该dev_write
函数应返回它“接受”的字节数(或负错误代码),而不是零。
换句话说,它应该返回len
而不是ret
。
推荐阅读
- c++ - 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- php - 如何在 PHP 中发送此 CURL
- python - 如何以特殊方式对熊猫数据框进行排序
- java - 如何将文本文件转换为小写并找到字母的频率?
- c++ - 2d 向量 c++、OOP 的迭代器设计模式
- java - 特殊字符“”在Linux中不起作用,转换为“?”
- c# - ASP.NET Core -- 上传 .json 文件并转换为 List
- python - 如何使用 Python 比较两个矩阵的相似性?
- python - Python:按多列熊猫分组
- ios - “使用未解析的标识符” 无法为我的生活弄清楚发生了什么。(Xcode,斯威夫特)