Доступ к последовательному порту из модуля ядра Linux

Здравствуйте, Linux Guern Driver!

Я пишу драйвер v4l2 для камеры, которая использует последовательный интерфейс для настройки. Я бы хотел, чтобы драйвер настраивал камеру, так как он поддерживал клиентский код в моделях камер. Вопрос в следующем: какой лучший способ получить доступ к последовательному интерфейсу камеры из модуля драйвера?

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

oldfs = get_fs();
set_fs(KERNEL_DS);

fd->f_pos=0;
fd->f_op->write(fd, data, data_len, &fd->f_pos);

set_fs(oldfs);

Мой вопрос действительно: какой правильный способ сделать это?

Ответ 1

Я предполагаю, что, поскольку задействован последовательный порт, это должна быть какая-то встроенная система. В конце концов, не так много компьютеров даже имеют последовательные порты. Я также предполагаю, что последовательный порт можно считать постоянным подключением, по крайней мере, с точки зрения пользователя. Если это все так, то вы действительно не хотите устройство TTY. Вы хотите получить доступ к устройству как к частному UART.

Если вы посмотрите на аудиокодеки Wolfson (sound/soc/wm *.c), вы увидите пример устройств, которые в основном обмениваются данными через I2S, но имеют вспомогательный интерфейс I2C для конфигурации. По-моему, это концептуально то, что вы хотите. Драйвер представляет собой унифицированный интерфейс для программного обеспечения и выдает команды на любое оборудование. Очевидно, что это намного чище, чем подвергать детали реализации оборудования пользователям.

Я не мог найти хороший пример драйвера UART в ядре, который работает таким образом, но, надеюсь, я описал, что искать. С точки зрения практической, а не технической чистоты, лучше всего было бы делать ввод/вывод файлов из ядра.

Ответ 2

Сначала я бы посоветовал вам найти способ сделать это из пользовательского пространства, если это возможно: то, что вы пытаетесь достичь здесь, - это код пользовательского кода в коде ядра.

Но если вы не нашли способ сделать это, эта статья показывает вам, как делать вызовы пользовательского пространства в kernelspace.

Поскольку вы хотите получить доступ к последовательному порту, вы должны иметь вызовы, ориентированные на tty, например, для open:

serial_fd = sys_open("/dev/ttyS0",  O_RDWR | O_NOCTTY | O_NONBLOCK))