我一直在为简单的角色设备和测试脚本编写代码。一切都妥善编译。字符设备有一个设备文件,make命令,insmod和rmmod命令等都可以正常工作,并且在检查/ var / log / syslog时有预期的输出。此外,测试脚本编译并运行而不返回被杀死或任何东西 - 除了以下问题之外,它具有预期的行为。
组装模块的任何内容似乎都没有任何问题。但是,当我运行我的测试脚本来评估我的设备/它的功能时,不会返回任何内容。例如,当我运行write并输入“hello world”时,它不会返回任何类型的错误。但是,如果我运行seek并将whence和offset设置为0,然后使用read,则它不会输出任何内容。但是,我在代码中找不到任何可以解释此行为的问题。 已编辑(此外,如果我检查日志,init和exit函数的kern警报会起作用,但其他任何kern警报都不会返回任何内容,这让我相信也许它们永远不会被输入,尽管我无法想象为什么会出现这种情况。)任何见解都会受到赞赏。我的角色设备如下所示:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h> //gets the functions for device driver coding
#include <linux/slab.h>
#include <asm/uaccess.h> //move data b/t userspace and kernel
#define BUFFER_SIZE 1024
#define MAJOR_NUMBER 240
#define DEVICE_NAME "simple_character_device"
char device_buffer[BUFFER_SIZE];
int openNum = 0;
int closeNum = 0;
char* buffer;
ssize_t simple_char_driver_read (struct file *pfile, char __user *buffer, size_t length, loff_t *offset){
int bytesRead = 0;
if (*offset >=BUFFER_SIZE){
bytesRead = 0;
return bytesRead;
}
if (*offset + length > BUFFER_SIZE){
length = BUFFER_SIZE - *offset;
}
printk(KERN_INFO "Reading from device\n");
if (copy_to_user(buffer, device_buffer + *offset, length) != 0){
return -EFAULT;
}
copy_to_user(buffer, device_buffer + *offset, length);
*offset += length;
printk(KERN_ALERT "Read: %s", buffer);
printk(KERN_ALERT "%d bytes read\n", bytesRead);
return 0;
}
ssize_t simple_char_driver_write (struct file *pfile, const char __user *buffer, size_t length, loff_t *offset){
printk(KERN_INFO "Writing to device\n");
copy_from_user(device_buffer + *offset, buffer, length);
*offset = strlen(device_buffer);
printk(KERN_ALERT "%zu bytes written\n", strlen(buffer));
printk(KERN_ALERT "%s", device_buffer);
return length;
}
int simple_char_driver_open (struct inode *pinode, struct file *pfile){
openNum++;
printk(KERN_ALERT "Device opened %d times\n", openNum);
return 0;
}
int simple_char_driver_close (struct inode *pinode, struct file *pfile){
closeNum++;
printk(KERN_ALERT "Device closed %d times\n", closeNum);
return 0;
}
loff_t simple_char_driver_seek (struct file *pfile, loff_t position, int whence){
printk(KERN_ALERT "!!!!!!!!%llx", position);
switch (whence) {
case SEEK_SET:
if (position < 0 || position >= BUFFER_SIZE){
return -1;
}
pfile->f_pos = position;
break;
case SEEK_CUR:
pfile->f_pos += position;
break;
case SEEK_END:
pfile->f_pos = BUFFER_SIZE - position;
break;
}
return 0;
}
struct file_operations simple_char_driver_file_operations = {
.owner = THIS_MODULE,
.read = simple_char_driver_read,
.write = simple_char_driver_write,
.open = (*simple_char_driver_open),
.release = simple_char_driver_close,
.llseek = simple_char_driver_seek,
};
static int simple_char_driver_init(void){
printk(KERN_INFO "initializing/registering device\n");
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
register_chrdev(MAJOR_NUMBER, DEVICE_NAME, &simple_char_driver_file_operations);
return 0;
}
static void simple_char_driver_exit(void){
printk(KERN_INFO "denitializing/unregistering device\n");
if (buffer)
kfree(buffer);
unregister_chrdev(MAJOR_NUMBER, DEVICE_NAME);
}
module_init(simple_char_driver_init);
module_exit(simple_char_driver_exit);
如上所示,我有初始化和退出方法,从设备文件读取的方法,写入它的方法,以及寻找文件中特定位置的搜索方法。 在下面的测试文件中,read方法采用您想要读取的字节数的参数。搜索方法需要一个和一个偏移量。 write方法接受你想要写的字符串。
我的测试文件如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define DEVICE "/dev/simple_character_device"
#define BUFFER_SIZE 1024
int main () {
char command;
char buffer[BUFFER_SIZE];
int length, offsetVal, whence;
int file = open(DEVICE, O_RDWR);
while (1) {
printf("\nr) Read from device\nw) Write to device\ns) Seek\ne) Exit device\nAnything else to continue reading and writing\n\nEnter command: ");
scanf("%c", &command);
switch (command) {
case 'w':
case 'W':
printf("Enter data you want to write to the device: ");
scanf("%s", buffer);
write(file, buffer, BUFFER_SIZE);
while (getchar() != '\n');
break;
case 'r':
case 'R':
printf("Enter the number of bytes you want to read: ");
scanf("%d", &length);
char* buffer = (char*)malloc(sizeof(char) *length);
read(file, buffer, length);
printf("Device output: %s\n", buffer);
while (getchar() != '\n');
break;
case 's':
printf("Enter an offset value: ");
scanf("%d", &offsetVal);
printf("Enter a value for whence (third parameter): ");
scanf("%d", &whence);
lseek(file, offsetVal, whence);
while (getchar() != '\n');
break;
case 'e':
case 'E':
return 0;
default:
while (getchar() != '\n');
}
}
close(file);
return 0;
}
如果您对代码无法正常运行的原因有任何了解,请告诉我们。我对这个问题非常困惑。谢谢你的时间和帮助!
编辑:此外,如果我检查日志,init和exit函数的kern警报会起作用,但其他任何kern警报都不会返回任何内容,这让我相信也许它们永远不会被输入,尽管我无法弄清楚为什么会这样。此外,由于这个问题,我的问题不是建议的帖子链接的重复。该解决方案已经实施,但问题仍然存在。