Linux设备驱动程序读写函数问题

时间:2022-08-02 14:36:07

I'm writing sample device driver to read and write using cyclic buffer, it means the last node point to the first one. I created the linked list of 10 block, each block buffer size = 5.

我正在编写样本设备驱动程序以使用循环缓冲区进行读写,这意味着最后一个节点指向第一个节点。我创建了10个块的链表,每个块缓冲区大小= 5。

now on my write function, when I call write method, it write in the buffer, check if it's filled, then jump the the other one, the next write will write in the current buffer + offset defined in lnod struct . same thing for read.

现在在我的写入函数上,当我调用write方法时,它在缓冲区中写入,检查它是否已填充,然后跳转另一个,下一次写入将写入当前缓冲区+ lnod struct中定义的偏移量。阅读同样的事情。

when I run the echo command twice

当我运行echo命令两次

echo 123456789 > /dev/driver
echo abcd > /dev/driver

according to the write and read function below the cat command will give123456789abcd as result since the second write will continue on the offset, so the read function will read all the size_to_read, but the cat (called 3 times)command gave me this :

根据cat命令下面的write和read函数将给出123456789abcd作为结果,因为第二次写入将继续对偏移量进行处理,因此read函数将读取所有size_to_read,但是cat(称为3次)命令给了我这样的信息:

cat /dev/driver 
abcd
6789
abcd

some usefull code parts:

一些有用的代码部分:

static int BlockNumber = 10;
static int BlockSize = 5;

static int size_to_read = 0;

data buffer structure

数据缓冲结构

 typedef struct dnode
 {
     int bufSize;
     char *buffer;
     struct dnode *next;
 } data_node;

liste stucture

 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;

the create liste method is called in init function

在init函数中调用create liste方法

write function

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;
}

the read function

读取功能

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;  
}

create linked list function

创建链表功能

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;
}

1 个解决方案

#1


1  

In the createlist() routine , in the for loop, you need to add the follwoing line to make a circular list. previousNode = newNode; Your existing createlist would create a circular list with just two nodes.

在createlist()例程中,在for循环中,您需要添加以下行以创建循环列表。 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;
    previousNode = newNode  //Please add this line to make the list circular.
}

#1


1  

In the createlist() routine , in the for loop, you need to add the follwoing line to make a circular list. previousNode = newNode; Your existing createlist would create a circular list with just two nodes.

在createlist()例程中,在for循环中,您需要添加以下行以创建循环列表。 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;
    previousNode = newNode  //Please add this line to make the list circular.
}