c - Linux 设备驱动读写函数问题

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

我正在编写示例设备驱动程序以使用循环缓冲区进行读写,这意味着最后一个节点指向第一个节点。我创建了 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/

相关文章:

javascript - "condition"(? :) operator work in JavaScript as in C?

c - 如何在 c 文件之间共享全局变量?

c - 如何与 NT 安装管理器交互以分配驱动器号?

python - How to grab string(ip) from netstat pipe the string(ip) to whois command, grab a string(country) 从 whois 输出。并使用 iptables 禁止 ip

linux - 基本的 if else 脚本

c - 如何以网络字节顺序从二进制文件读取并在C中创建struct sockaddr_in

linux - 从 linux 命令行搜索我保存的命令(不是 bash 历史)的工具/脚本

linux - 用户线程到内核线程的多对一映射

multithreading - Linux 内核等待队列和列表之间的正确交互

c - 互斥锁内的信号量等待