Проблема с записью из ядра в пользовательское пространство - драйвер устройства linux - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь написать простой драйвер Raspberry Pi GPIO с четырьмя коммутаторами, подключенными к четырем контактам GPIO, который считывает каждое состояние коммутатора.Проблема в том, что я не уверен, как писать из ядра в пространство пользователя, я ничего не получаю, когда вставляю модуль ядра своего устройства и пытаюсь прочитать файл устройства с помощью команды cat.Функция device_read выглядит следующим образом:

static ssize_t gpio_driver_read(struct file *filp, char *buf, size_t len, loff_t *f_pos)
{
    /* Size of valid data in gpio_driver - data to send in user space. */
    int data_size = 0;

    /* Counter for 'for' loop. */
    int i;

    /* Print to kernel space. */
    printk(KERN_INFO "Reading active Switch state...\n");

    for (i = 0; i < 4; i = i+1)
    {
        printk(KERN_INFO "Loop number %d...\n", i);
        /* TODO: fill gpio_driver_buffer here. */
        if (i == 0 && mySwitches[0])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio12 value: %d\n", GetGpioPinValue(GPIO_12));
        else if (i == 1 && mySwitches[1])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio16 value: %d\n", GetGpioPinValue(GPIO_16));
        else if (i == 2 && mySwitches[2])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio20 value: %d\n", GetGpioPinValue(GPIO_20));
        else if (i == 3 && mySwitches[3])
            sprintf(gpio_driver_buffer, "gpio_driver: gpio21 value: %d\n", GetGpioPinValue(GPIO_21));

        printk(KERN_INFO "%s\n", gpio_driver_buffer);

        /* Get size of valid data. */
        data_size = strlen(gpio_driver_buffer);

        printk(KERN_INFO "%d\n", data_size);


        /* Send data to user space. */
        if (copy_to_user(buf, gpio_driver_buffer, data_size) != 0)
        {
            return -EFAULT;
        }
    }

    return 0;
}

gpio_driver_buffer - это массив некоторого размера по умолчанию (я установил его равным 80).
mySwitches - это массив из 4 элементов, каждый из которых имеетзначение 0 или 1 (я передаю это в качестве аргумента при вставке модуля ядра, 1 означает, что я хочу наблюдать за состоянием переключателя, а 0 означает, что я не наблюдаю за переключателем).
GetGpioPinValue - этофункция, которая возвращает состояние переключателя.

Проблема в том, что когда я пытаюсь прочитать файл устройства с помощью команды cat, я ничего не получаю.Однако, как вы можете видеть, я отладил программу с помощью команд printk, и все правильно написано в пространстве ядра.Где может быть проблема?

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Посмотрите пример кода здесь .

0 голосов
/ 18 декабря 2018

Не похоже, что вы когда-либо записываете в настоящий файл.Поскольку вы не упоминаете, как вы генерируете файл, я предполагаю, что вы пишете в произвольный файл, а не тот, который создан драйвером для / proc или чем-то еще.

Просмотрите сообщение здесь: Чтение / запись файлов в модуле ядра Linux

Вы можете попробовать это:

int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_write(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}

Затем вызовите его вместо «copy_to_user»:

/* Send data to user space. */
        if (file_write(filep, 0, gpio_driver_buffer, data_size) != 0)
        {
            return -EFAULT;
        }
...