2014-08-28 4 views
1

Я пишу пример драйвера устройства для чтения и записи с использованием циклического буфера, это означает, что последний узел указывает на первый. Я создал связанный список из 10 блоков, каждый размер блока буфера = 5.Проблема с драйверами чтения Linux-устройств

теперь на моей функции записи, когда я вызываю метод записи, он записывает в буфер, проверяет, заполнен ли он, а затем перескакивает другой, следующая запись будет записываться в текущем буфере + смещение, определенном в lnod struct. такой же предмет для читать.

при запуске эха команды дважды

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; 

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; 

создавание метод 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; 
} 

ответ

1

В подпрограмме createlist(), в течение цикла, то нужно добавить происходит некорректно линию, чтобы сделать циклический список. 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. 
} 
+0

это очень помогает, но почему оно возвращается обратно в линию? когда я запускаю 'echo gggg>/dev/driver' и' echo 444>/dev/driver', он отображает 'gggg' и новую строку и' 444' – 2014-08-28 12:05:31

+1

. echo добавляет новую строку в конец вашего ввода. Это может быть подтверждено следующими шагами. echo gggg> some_txt_file. Если вы проверите размер файла some_txt_file, это будет 5 байтов, а не 4 байта. – toyoubala

Смежные вопросы