Я пишу пример драйвера устройства для чтения и записи с использованием циклического буфера, это означает, что последний узел указывает на первый. Я создал связанный список из 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;
}
это очень помогает, но почему оно возвращается обратно в линию? когда я запускаю 'echo gggg>/dev/driver' и' echo 444>/dev/driver', он отображает 'gggg' и новую строку и' 444' – 2014-08-28 12:05:31
. echo добавляет новую строку в конец вашего ввода. Это может быть подтверждено следующими шагами. echo gggg> some_txt_file. Если вы проверите размер файла some_txt_file, это будет 5 байтов, а не 4 байта. – toyoubala