Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Много виртуальных UART
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
toweroff
Добрый день

Ну не то, чтоб я ноль прям в Linux sm.gif около того

Но надо - значит надо.
Есть задача такая: некий драйвер реализует в системе несколько виртуальных UART. Внешняя связь у него через один существующий - ttyS0
Драйвер от каждого виртуального UART собирает данные, заворачивает в обертку и отправляет в ttyS0
Оттуда же принимает завернутые данные и "рассовывает" по буферам соответствующих виртуальных UART

Я так понимаю, мне не хватает знаний для:

1. Зарегистрировать имя в дереве устройств
2. Интерфейс драйвера UART для системы
3. Таймер для сбора данных из виртуальных портов

Поможите примерами, люди добрые
nill
Цитата(toweroff @ Apr 12 2017, 23:28) *
Поможите примерами, люди добрые

Давайте, я Вам лучше удочку дам. Драйверы tty описаны в LDD, глава 18. В главе 7 есть про ядерные таймеры. Но если очень хочется примеров, то что-то дожно быть в дереве исходников в /drivers/tty.
Olej
Цитата(toweroff @ Apr 12 2017, 19:28) *
Есть задача такая: некий драйвер реализует в системе несколько виртуальных UART. Внешняя связь у него через один существующий - ttyS0
...
1. Зарегистрировать имя в дереве устройств
2. Интерфейс драйвера UART для системы
3. Таймер для сбора данных из виртуальных портов

Если вы заворачиваете все потоки в /dev/ttyS0, то вам сам интерфейс UART в ядре и не нужен... (это что-то типа самопального MODBUS?)
Цитата(toweroff @ Apr 12 2017, 19:28) *
Поможите примерами, люди добрые

Я здесь рядом давал уже ссылку: Практикум по Linux Kernel.
Там полно примеров и др. вещей вам нужных для этой затеи.
toweroff
Проясните, пожалуйста, такой момент. Нашел я на просторах tiny_serial, взял за основу
Компилируется, после пересборки ядра даже не ругается и загружается. Появляется новое tty-устройство так, как я его и обозвал
Но! Понатыканные мной сообщения printk в dmesg не вижу.
В частности, вот такая структура:
Код
static struct uart_ops tiny_ops = {
    .tx_empty    = tiny_tx_empty,
    .set_mctrl    = tiny_set_mctrl,
    .get_mctrl    = tiny_get_mctrl,
    .stop_tx    = tiny_stop_tx,
    .start_tx    = tiny_start_tx,
    .stop_rx    = tiny_stop_rx,
    .enable_ms    = tiny_enable_ms,
    .break_ctl    = tiny_break_ctl,
    .startup    = tiny_startup,
    .shutdown    = tiny_shutdown,
    .set_termios    = tiny_set_termios,
    .type        = tiny_type,
    .release_port    = tiny_release_port,
    .request_port    = tiny_request_port,
    .config_port    = tiny_config_port,
    .verify_port    = tiny_verify_port,
};

в .startup занесен правильный адрес, но функция не вызывается. Наткнулся на упоминание
http://stackoverflow.com/questions/3705814...-being-executed

поправил .type, но все равно ноль реакции
minicom запускается, но пишет offline

Куда еще можно копнуть?
gerber
Цитата(toweroff @ Apr 18 2017, 14:47) *
Куда еще можно копнуть?

В направлении udev rules.
Вкратце - в современных линуксах сам по себе модуль ядра, загруженный в память, ещё ни к чему систему не обязывает (вызывать все его функции) - ОС должна "понять", что устройство, для которого загружен модуль ядра, есть (появилось) в системе.
Вторая возможная причина, по которой может не работать ваш драйвер - для устройства уже есть драйвер в составе ядра или среди загруженных модулей.
Olej
Цитата(gerber @ Apr 18 2017, 16:58) *
Вкратце - в современных линуксах сам по себе модуль ядра, загруженный в память, ещё ни к чему систему не обязывает (вызывать все его функции) - ОС должна "понять", что устройство, для которого загружен модуль ядра, есть (появилось) в системе.

Совершенно не обязательно - это всё зависит от того, как написан код самого модуля.
udev/sysfs используется достаточно многими модулями ядра, но далеко не всеми, и это совсем не обязательно.


Цитата(toweroff @ Apr 18 2017, 14:47) *
Нашел я на просторах tiny_serial, взял за основу
Компилируется, после пересборки ядра даже не ругается и загружается. Появляется новое tty-устройство так, как я его и обозвал
Но! Понатыканные мной сообщения printk в dmesg не вижу.

Какой уровень диагностики у вас указан в printk()?
(нужно не на пальцах рассказывать, а хотя бы 2-3-5 строчек с этим свои printf() показывать)
Вы выполняет загрузку в графическом терминале? - выполните её в текстовой консоли.
krux
не надо никаких самописных модулей ядра.
гуглите "socat virtual serial port"
toweroff
Значится так... Я тут нагуглил tty0tty - виртуальные порты, "соединенные" между собой. Вот уже и становится понятно, почему у меня "нихт"
Нужно и управляющие сигналы нормально обрабатывать (похоже, не стоит надеяться на то, будут там всякие RTS/CTS, DSR/DTR использоваться или нет, программно лучше сделать)
да и сам TTY драйвер явно приводится к TTY_DRIVER_TYPE_SERIAL и SERIAL_TYPE_NORMAL
В общем пример абсолютно рабочий, буду путем выбрасывания лишнего вкорячивать свой функционал sm.gif


Цитата(krux @ Apr 18 2017, 17:36) *
не надо никаких самописных модулей ядра.
гуглите "socat virtual serial port"

видел
и как мне со всем этим городить обертки для работающего железа за малиной?
toweroff
UPD
Товарищи, вот какой вопрос возник. Правильно ли будет забирать из драйвера данные физического порта, обрабатывать и рассовывать по виртуальным системным таймером?
Или для подобных действий нужен специальный механизм (драйвер-то сам по себе не дергается, по сути, его "теребят" пользовательские приложения, а забирать данные нужно)
gerber
Цитата(toweroff @ Apr 18 2017, 20:19) *
Товарищи, вот какой вопрос возник. Правильно ли будет забирать из драйвера данные физического порта, обрабатывать и рассовывать по виртуальным системным таймером?

ИМХО, это неправильно, будить систему по каждому тику таймера, а не по приходу данных.
Вообще, драйвер на уровне ядра тут лишний (как уже указывалось выше). Задача решается в userspace обычным демоном, который создает нужное вам количество char devices, после чего блокируется на read() из физического порта. Все пришедшие из "виртуальных" портов данные он пишет в физический порт, и наоборот, пришедшие из физического порта парсит, и рассовывает по "виртуальным".
toweroff
Цитата(gerber @ Apr 19 2017, 13:31) *
ИМХО, это неправильно, будить систему по каждому тику таймера, а не по приходу данных.
Вообще, драйвер на уровне ядра тут лишний (как уже указывалось выше). Задача решается в userspace обычным демоном, который создает нужное вам количество char devices, после чего блокируется на read() из физического порта. Все пришедшие из "виртуальных" портов данные он пишет в физический порт, и наоборот, пришедшие из физического порта парсит, и рассовывает по "виртуальным".

не нашел, все примеры в kernel space sad.gif
или мой гугель сломался
с другой стороны, если драйвер будет совершать по таймеру очень короткое действие раз эдак в 10мс, что с того?
у меня ж еще вот какая загвоздка - создаваемые порты должны быть вполне себе полноценными, со всякими ioctl(), ибо на них будет садиться и звонилка модемная и еще вещи
Olej
Цитата(toweroff @ Apr 19 2017, 16:04) *
с другой стороны, если драйвер будет совершать по таймеру очень короткое действие раз эдак в 10мс, что с того?
у меня ж еще вот какая загвоздка - создаваемые порты должны быть вполне себе полноценными, со всякими ioctl(), ибо на них будет садиться и звонилка модемная и еще вещи

Как-то мне всё это видится: самомнения - полные штаны, а умений - кот наплакал 1111493779.gif
toweroff
Цитата(Olej @ Apr 19 2017, 18:59) *
Как-то мне всё это видится: самомнения - полные штаны, а умений - кот наплакал 1111493779.gif

В первом посте я обрисовал ситуацию. А самомнение у Вас, похоже
Olej
Цитата(toweroff @ Apr 19 2017, 22:14) *
я обрисовал

Нужно больше читать, и меньше писать херни.
toweroff
Цитата(Olej @ Apr 20 2017, 00:58) *
Нужно больше читать, и меньше писать херни.

Подсказать советом религия не позволяет? Такое ощущение, что Вы со всеми знаниями родились сразу, вся нужная литература была при рождении сразу привязана к заднице и помощь и советы вообще не требовались, так?
И речь была одномоментно поставлена правильно?
Olej
Цитата(toweroff @ Apr 20 2017, 07:52) *
Подсказать советом религия не позволяет?

А поднять глаза и прочитать 2-мя сообщениями выше, что уже подсказывал, религия не позволяет?
Цитата(Olej @ Apr 13 2017, 11:17) *
Я здесь рядом давал уже ссылку: Практикум по Linux Kernel.
Там полно примеров и др. вещей вам нужных для этой затеи.
toweroff
Цитата(Olej @ Apr 20 2017, 12:21) *
А поднять глаза

ну едрен-батон, так от тех двух ссылок и отталкивался
да и примеры найденные оттуда же как под копирку
не, извиняюсь. Это из Ch.18 TTY Drivers
toweroff
В общем всем спасибо, все работает
toweroff
Поторопился... sad.gif
похоже, не устанавливаются как нужно настройки реального порта sad.gif пока тестировал, так все красиво было

итак.
нужно настроить реальный порт на 115200, без CTS/RTS
Код
static struct file* open_port (void)
{
struct file* port;
struct tty_struct *tty;
mm_segment_t oldfs;

        oldfs=get_fs();
        set_fs(KERNEL_DS);

        port = filp_open(PHY_TTY, O_RDWR | O_NONBLOCK, 0666);
        if (port == NULL)
        {
                printk(KERN_ERR "PORT: can't open PHY port '%s'\n", PHY_TTY);
                goto exit;
        }


        tty=(struct tty_struct*)port->private_data;

        tty->termios.c_cc[VTIME] = 20;
        tty->termios.c_cc[VMIN] = 0;
        tty->termios.c_cflag &= ~PARENB;
        tty->termios.c_cflag &= ~CSTOPB;
        tty->termios.c_cflag &= ~CSIZE;  
        tty->termios.c_cflag |= CS8;  
        tty->termios.c_cflag |= B115200;

        tty->termios.c_lflag = 0;
        tty->termios.c_oflag &= ~OPOST;

        tty->termios.c_iflag = 0;
        tty->termios.c_iflag &= ~ (INLCR | IGNCR | ICRNL);


exit:
        set_fs(oldfs);
        return port;
}


что не так?
сам порт открывается, даже потом что-то из него вижу, но явно не на той скорости
Tarbal
Цитата(toweroff @ Apr 19 2017, 23:14) *
В первом посте я обрисовал ситуацию. А самомнение у Вас, похоже


Вы бы послушали действительно знающего человека. Не спорьте, а ловите каждое слово.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.