|
Драйвер для 6 UART на PCI шине, как быстрее поднять? |
|
|
|
Nov 21 2013, 21:43
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
Имеется плата PCI, где на ПЛИС сделаны 6 UART с драйверами RS-232. Написана PCI функция, которая управляет шестью UART 16550A, тоже самописными. Все это более менее проверялось раньше по отдельности, но теперь вот есть желание запустить порты из-под линукс. Особенность платы в том, что она позволяет делать резервирование RS-232, то есть кроме самого UART 16550 каждый порт имеет логику, которая управляет выключением микросхемы соответствующего драйвера RS-232. Эта логика имеет определенные настройки, которые определяют правила отключения драйвера в зависимости от состояния внешних сигналов.
Все UART представляют собой стандартные 8 регистров, которые расширены нулями до 32-битных слов и размещены в одном BAR по смежным адресам.
Собственно интересует наиболее простой путь подружить линукс со всеми 6 портами. Пока представляются следующие способы: 1) Писать с нуля PCI драйвер ос своими PID, VID. 2) Подсмотреть готовые конфигурации UART в исходниках драйверов линукс, и изменить PID, VID своего устройства в соответствии с подходящим профилем из поддержаных. 3) Написать свой минидрайвер, который будет находить устройство на шине PCI и регистрировать его UART'ы как serial8250 platfrom_device. После чего его и линукс сам подхватит.
Если делать свой драйвер (модуль), то можно в нем зарегистрировать атрибуты портов, чтобы можно было настраивать правила его резервирования. Не уверен, можно ли это сделать, если пытаться подстроиться под существующий драйвер для шины PCI.
|
|
|
|
|
Nov 22 2013, 06:55
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
Посмотрел. Пока ничего путного не вынес из документа. Пересобирать линукс не хотелось бы, так как у заказчика вообще что-то типа МСВС. И я не уверен, что он так просто сможет повторить его (пере)сборку. Зато есть свобода маневра с vendor id и device id. Можно на уровне устройства притвориться чем-то стандартным, для чего уже есть дескриптор в существующем драйвере PCI.
Кстати говоря, уже сейчас линукс пытается цапануть устройство как serial, видимо, на основе данных о классе устройства PCI. Но обламывается и выдает код -28 (ENOSPC?). Пока думаю, что причина в одном из: 1) Размер BAR не соответствует представлениям драйвера. 2) Размер регистра в PCI устройстве - 32 бита (сдвиг адреса 2), а по умолчанию драйвер ожидает 8 бит (сдвиг адреса 0).
Ну и собственно, остается открытым вопрос, как правильно сделать управление параметрами порта, не относящиеся непосредственно к UART? например, мне нужно для каждого порта делать некую настройку, какие внешние сигналы (из определенного набора) могут отключать сигнальный драйвер, чтобы резервный комплект не мешал основному. Явно надо какой-то модуль ядра писать. Например, был опыт с написанием мини-драйвера, который находил UART-ы на одной шине и регистрировал их на шине platform_bus. Вполне такая схема работает, и можно при регистрации определить заодно атрибуты устройства. В том проекте у меня были атрибуты для выбора дуплекса, и параметра управления передатчиком в RS-422/RS-485.
-- Да, так и есть, по умолчанию драйвер 8250_pci хочет регистрировать устройства с 8-битными регистрами. Отсюда и облом при регистрации устройства с 32-битными регистрами.
|
|
|
|
|
Nov 22 2013, 15:09
|
Участник

Группа: Участник
Сообщений: 74
Регистрация: 12-01-13
Из: Нижний Новгород
Пользователь №: 75 160

|
жаль мне заказчика
|
|
|
|
|
Nov 22 2013, 17:06
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
Да драйвер-то написать можно, есть и свои драйверы для PCI устройств с DSP, вполне пойдут в основу. Тем более что нужен то мини-драйвер, который выдернет из платы адреса и зарегистрирует стандартные порты 8250. Я надеялся, что линукс сам может определить мультипортовый контроллер на основе данных PCI BAR и т.п., но поглядев исходники 8250_pci.c понял, что особенных чудес ждать неоткуда. В той версии ядра, которая стоит на отладочном стенде, вообще нет 6-портовых конфигураций, только степени двойки.
|
|
|
|
|
Nov 24 2013, 07:36
|
Знающий
   
Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088

|
Цитата(Hoodwin @ Nov 22 2013, 22:07)  Дык на ПЛИС я как раз могу довольно просто переделать архитектуру, чтобы прикинуться "стандартным" устройством, только вот как изобразить 6 стандартных портов в одном устройстве? Ну хотя бы чтобы компорты проверить. Очень просто. Для этого Вам нужно, чтобы набор регистров каждого COM-порта вашей платы соответствовал набору стандартного 8250-контроллера, с байтовым смещением регистров. При этом не нужно "подделывать" VID/PID своей платы под другого производителя, достаточно вписать свои VID/PID в тот большой перечень PCI-UART плат, которые поддерживаются стандартным драйвером. Если правильно помню - этот список плат содержится в файле 8250_pci.c, там есть большой массив с описанием плат, для каждой платы задаётся VID/PID, номер BAR, адресный шаг между регистрами разных COM-портов, количество COM-портов, реализуемых PCI-платой.
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
|
Nov 24 2013, 19:47
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
Да, в итоге действительно потратил полтора часа времени на изучение 8250_pci.c и написал модуль по мотивам оного. К сожалению, сам 8250_pci не подошел, так как в нем нет есть всего одна шестипортовая комбинация, а эвристика мультипортового устройства не цепляла мое устройство. Править стандартный 8250_pci не стал, так как 1) для этого потребуется все ядро пересобирать, что нежелательно; 2) требуется зарегистрировать дополнительные атрибуты устройства, позволяющие управлять внешним драйвером сигналов. В итоге устройство поднялось и даже вчерне работает. Есть вопрос по поводу количества uart в драйвере 8250. Мой модуль регистрирует 6 портов, но регистрируются только первые два. В принципе это ожидаемо, если в ядре CONFIG_SERIAL_8250_RUNTIME_UARTS и CONFIG_SERIAL_8250_NR_UARTS слишком малы. Так вот: 1) можно ли как-то подсмотреть, с какими настройками собрано текущее ядро? 2) Можно ли как-то увеличить количество уартов без пересборки ядра? Нашел в сети, что можно в комстроке ядра писать 8250.nr_uarts=8, но вот тут http://forums.opensuse.org/english/get-tec...4-detected.html пишут, что это не помогло, и в итоге люди уродовались с пересборкой модуля UART.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|