我正在编写示例设备驱动程序以使用循环缓冲区进行读写,这意味着最后一个节点指向第一个节点。我创建了 10 个 block 的链表,每个 block 缓冲区大小 = 5。
现在在我的写函数上,当我调用 write 方法时,它写入缓冲区,检查它是否已满,然后跳转到另一个,下一次写入将写入当前缓冲区 + lnod 中定义的偏移量结构
。阅读同样的事情。
当我运行两次 echo 命令时
echo 123456789 > /dev/driver
echo abcd > /dev/driver
根据下面的写入和读取函数,cat
命令将给出 123456789abcd
作为结果,因为第二次写入将继续偏移量,因此读取函数将读取所有size_to_read
,但是 cat
(调用 3 次)命令给了我这个:
cat /dev/driver
abcd
6789
abcd
一些有用的代码部分:
static int BlockNumber = 10;
static int BlockSize = 5;
static int size_to_read = 0;
数据缓冲区结构
typedef struct dnode
{
int bufSize;
char *buffer;
struct dnode *next;
} data_node;
列表结构
typedef struct lnode
{
data_node *head;
data_node *cur_write_node;
data_node *cur_read_node;
int cur_read_offset;
int cur_write_offset;
}liste;
static liste newListe;
在init函数中调用create liste方法
编写函数
static ssize_t sample_write_liste(struct file *f, const char *buf, size_t size, loff_t *offset)
{
if (*(offset) == 0)
{
size_to_read += size;
}
int size_to_copy;
size_to_copy = MIN (size, BlockSize - newListe.cur_write_offset);
copy_from_user(newListe.cur_write_node->buffer + newListe.cur_write_offset, buf, size_to_copy);
*(offset) += size_to_copy;
newListe.cur_write_offset += size_to_copy;
if (newListe.cur_write_offset == BlockSize)
{
newListe.cur_write_node = newListe.cur_write_node->next;
newListe.cur_write_offset = 0; // we erase previous things
}
return size_to_copy;
}
读取函数
static ssize_t sample_read_liste(struct file *f, char *buf, size_t size, loff_t *offset)
{
int size_to_copy;
size_to_copy = MIN (size_to_read - *(offset), BlockSize - newListe.cur_read_offset);
copy_to_user(buf, newListe.cur_read_node->buffer + newListe.cur_read_offset,size_to_copy);
newListe.cur_read_offset += size_to_copy;
(*offset)+=size_to_copy;
if (newListe.cur_read_offset == BlockSize)
{
newListe.cur_read_node = newListe.cur_read_node->next;
newListe.cur_read_offset = 0;
}
return size_to_copy;
}
创建链表函数
static void createlist (void) {
data_node *newNode, *previousNode, *headNode;
int i;
/* new node creation */
newNode = (data_node *)kmalloc(sizeof (data_node), GFP_KERNEL);
newNode->buffer = (char *)kmalloc(BlockSize*sizeof(char), GFP_KERNEL);
newNode->next = NULL;
newListe.head = newNode;
headNode = newNode;
previousNode = newNode;
for (i = 1; i < BlockNumber; i++)
{
newNode = (data_node *)kmalloc(sizeof (data_node), GFP_KERNEL);
newNode->buffer = (char *)kmalloc(BlockSize*sizeof(char), GFP_KERNEL);
newNode->next = NULL;
previousNode->next = newNode;
}
/* cyclic liste : we should tie the last element to the first one (head) */
newNode->next = headNode;
newListe.cur_read_node = headNode;
newListe.cur_write_node = headNode;
newListe.cur_read_offset = 0;
newListe.cur_write_offset = 0;
}
最佳答案
在 createlist() 例程中,在 for 循环中,您需要添加以下行来制作循环列表。 前一个节点 = 新节点; 您现有的创建列表将创建一个只有两个节点的循环列表。
for (i = 1; i < BlockNumber; i++)
{
newNode = (data_node *)kmalloc(sizeof (data_node), GFP_KERNEL);
newNode->buffer = (char *)kmalloc(BlockSize*sizeof(char), GFP_KERNEL);
newNode->next = NULL;
previousNode->next = newNode;
previousNode = newNode //Please add this line to make the list circular.
}
关于c - Linux 设备驱动读写函数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25547102/