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

时间:2014-08-28 10:55:50

标签: c linux linux-kernel linux-device-driver

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

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

当我运行echo命令两次

lnod struct

根据echo 123456789 > /dev/driver echo abcd > /dev/driver 命令下面的写入和读取函数,将给出cat作为结果,因为第二次写入将继续在偏移量上,因此读取函数将读取所有123456789abcd ,但size_to_read(称为3次)命令给了我这个:

cat

一些有用的代码部分:

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;

在init函数中调用create liste方法

写函数

 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;

读取功能

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

1 个答案:

答案 0 :(得分:1)

在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.
}