LINUX.ORG.RU

Не могу запустить COM порт

 


1

2

Есть не вполне обычная коробченка Axiomtek eBOX730-860-FL (http://ipc2u.ru/news/new/eBOX730-860-FL/) с 8 изолированными COM портами. Ставлю на неё Windows - COM порты работают вполне ожидаемо, причём в диспетчере устройств никаких необычных контроллеров в части портов не наблюдаю. У коробченки есть набор из 16 светодиодов на корпусе, которые моргают, когда идет чтение/запись в COM порты. Замыкаю пины 2 и 3 на одном из портов, кидаю на него сообщение и ожидаемо принимаю на том же порту. В общем, на Windows, всё работает нормально. Ставлю на неё же линукс (пробовал ubuntu и astra), вижу в ls 8 uart портов типа /dev/ttyS0..7 и... Запускаю minicom, настраиваю аналогично тому, как оно есть в Windows, собственно и всё - никакие огоньки не мигают, данные не передаются и не принимаются. Причем сами порты открываются вполне себе нормально.

acs@acs-CEM860:~$ dmesg | grep ttyS
[    1.456871] 00:04: ttyS4 at I/O 0x240 (irq = 11, base_baud = 115200) is a 16550A
[    1.477404] 00:05: ttyS5 at I/O 0x248 (irq = 11, base_baud = 115200) is a 16550A
[    1.497913] 00:06: ttyS6 at I/O 0x250 (irq = 11, base_baud = 115200) is a 16550A
[    1.518463] 00:07: ttyS7 at I/O 0x258 (irq = 11, base_baud = 115200) is a 16550A
[    1.539043] 00:09: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    1.559597] 00:0a: ttyS1 at I/O 0x2f8 (irq = 4, base_baud = 115200) is a 16550A
[    1.580162] 00:0b: ttyS2 at I/O 0x3e8 (irq = 4, base_baud = 115200) is a 16550A
[    1.600717] 00:0c: ttyS3 at I/O 0x2e8 (irq = 4, base_baud = 115200) is a 16550A
Мало того, если я разворачиваю под этой виндой виртуалку с ubuntu, «пробрасываю» пару COM портов на гостевую ОС: всё тоже нормально без всяких танцев с бубном - minicom доволен, огоньки мигают, данные передаются/принимаются. Куда копать-то дальше?


Ответ на: комментарий от Dark_SavanT

В общем ситуация пока такая. Обновил ядро до 4.5.0rc2 - светодиод Rx загорается именно на том порту (и только на нём!), где установлена перемычка. Но передачи данных так и нет, да и Tx светодиод не загорается тоже.

Я бы посмотрел, нет ли вдруг GPIO который разрешает/запрещает передачу данных.

Как это сделать?

okos
() автор топика
Ответ на: комментарий от okos

Обновил ядро до 4.5.0rc2 - светодиод Rx загорается именно на том порту

Что это означает? Что он что-то прочел или что этот светодиод значит? Мигает в такт с данными?

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Что это означает? Что он что-то прочел или что этот светодиод значит?

ХЗ загорается что при echo «HELLO» > /dev/ttyS1, что при cat < /dev/ttyS1. При этом Tx так и не светится. При Ctrl+C не echo и cat - гаснет.

Мигает в такт с данными?

Да вроде просто горит.

okos
() автор топика
Ответ на: комментарий от Zubok

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

okos
() автор топика
Ответ на: комментарий от okos

При этом Tx так и не светится.

Ты попробуй что-нибудь по передавать echo и потом глянь /proc/tty/driver/serial, пытался ли он что-то передавать.

Вот, например, я передал короткое слово и он tx:6 отобразил.

0: uart:16550A port:000003F8 irq:4 tx:6 rx:0

В том выхлопе, что выше, вообще все по нулям.

Zubok ★★★★★
()
Ответ на: комментарий от okos

При этом

acs@acs-CEM860:~$ stty -F /dev/ttyS0
speed 9600 baud; line = 0;
-brkint -imaxbel
Похоже, действительно надо ещё RTS c DTR соединять.

okos
() автор топика
Ответ на: комментарий от okos

Похоже, действительно надо ещё RTS c DTR соединять.

Не-не-не. Надо пробовать либо RTS с CTS, либо DTR с DSR. Но никак RTS с DTR! Вроде как выше у тебя выключено аппаратное управление потоком -crtscts. Но вот мало ли что. А что про этот порт говорит полный вывод параметров stty?

stty --all -F /dev/ttyS0
Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 5)
Ответ на: комментарий от Zubok
acs@acs-CEM860:~$ stty --all -F /dev/ttyS0
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc
-ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
okos
() автор топика
Ответ на: комментарий от okos

Но вот у тебя -crtscts выключена. Вообще, у этой команды есть еще -cdtrdsr, но это не POSIX и на Linux она отказывает принимать этот параметр. И вот теоретически может быть, что железка ждет DTR-DSR, тупо залипла в этом состоянии (драйвер такой или железка), а выключить это нельзя никак. Поэтому, если он этого хочет, то ему надо дать, что он просит.

      Optional - before SETTING indicates negation.   An  *  marks  non-POSIX
       settings.  The underlying system defines which settings are available.


       * [-]crtscts
              enable RTS/CTS handshaking

       * [-]cdtrdsr
              enable DTR/DSR handshaking

-crtscts работает, а -cdtrdsr говорит: stty: неверный аргумент «-cdtrdsr»

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от okos

Дать программно или аппаратно?

Аппаратно. Сделать вон как на картинке и проверить гипотезу на разных ядрах на всякий случай.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от okos

Там, как видишь, достаточно двух джамперов 2-3, 7-8. Да и проводок DTR-DSR не нужен особо. Можно тоже джамперы на 4-6 поставить и какой-нить скрепкой соединить. Это на скорую руку проверяется.

Zubok ★★★★★
()

okos, так чем дело закончилось? Порт заработал? У меня аналогичная проблема, только на другом компе. Всё, что здесь предлагалось, я проверил - не помогает. Под WinXP и даже msdos работает, а под линуксами - нет Железо на базе nct6106d

VyacheslavK
()
Ответ на: комментарий от VyacheslavK

Итак, решение проблемы найдено.

В нашем компьютере, как уже говорилось, порты реализованы на базе superio микросхемы NCT6106D. После некоторых ковыряний подозрение пало на то, что не срабатывают прерывания (товарищь определил, что в буфере приёмника данные обновляются).

После дальнейших ковыряний и считывания конфигурации NCT6106D выяснилось, что BIOS неправильно конфигурирует эту микросхему. Ошибка в регистрах CR13 и CR14 - Device IRQ polarity (http://v-comp.kiev.ua/download/NCT6102D_NCT6106D.pdf). BIOS задаёт полярность прерывания Active-Low, а должна быть Active-HIGH.

После того, как я вручную задал полярность Active-High (значения соответствующих битов = 0), все порты сразу заработали.

VyacheslavK
()
Ответ на: комментарий от VyacheslavK

Код для работы с микросхемой основан на исходниках https://github.com/wt/coreboot/tree/master/util/superiotool

Код изменения конфигурации регистров CR13, CR14

NCT_PORT может быть либо 0x2E, либо 0x4E - на разных компах может быть по разному

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <sys/io.h>

#define OUTB outb
#define OUTW outw
#define OUTL outl
#define INB  inb
#define INW  inw
#define INL  inl


#define NCT_PORT 0x2E
#define DEVICE_ID_REG 0x20
#define LDN_SEL	0x07

uint8_t regval(uint16_t port, uint8_t reg)
{
    OUTB(reg, port);
    return INB(port + 1);
}

void regwrite(uint16_t port, uint8_t reg, uint8_t val)
{
    OUTB(reg, port);
    OUTB(val, port + 1);
}

void enter_conf_mode(uint16_t port)
{
    OUTB(0x87, port);
    OUTB(0x87, port);
}

void exit_conf_mode(uint16_t port)
{
    OUTB(0xaa, port);		/* Fintek, Winbond */
}

int main(int argc, char *argv[])
{
    printf("Nuvoton set irq level HIGH\n");

    //Доступ к IO
    if (iopl(3) < 0)
    {
        perror("iopl");
        printf("Superiotool must be run as root.\n");
        exit(1);
    }

    //Открываем режим конфигурирования
    enter_conf_mode(NCT_PORT);

    //Считываем CHIP ID
    uint16_t chip_id = (regval(NCT_PORT, DEVICE_ID_REG) << 8) |
            regval(NCT_PORT, DEVICE_ID_REG + 1);

    //Печатаем
    printf("ChipID = 0x%X\n", chip_id);

    uint16_t val;
    uint16_t port = NCT_PORT;

    //разрешаем доступ к регистрам 0x10-0x14
    val = regval(port, 0x26);
    val |= 0x10;
    regwrite(port, 0x26, val);

    //Задаём нужный уровень прерываний
    val = regval(port, 0x13);
    val &= 0xF3;
    regwrite(port, 0x13, val);

    val = regval(port, 0x14);
    val &= 0xE7;
    regwrite(port, 0x14, val);

    //запрещаем доступ к регистрам 0x10-0x14
    val = regval(port, 0x26);
    val &= (~0x10);
    regwrite(port, 0x26, val);

    //Закрываем режим конфигурирования
    exit_conf_mode(NCT_PORT);

    return 0;
}

VyacheslavK
()
Ответ на: комментарий от VyacheslavK

При компиляции надо подключить библиотеку libz

Текст CMakeLists.txt для компиляции через cmake

cmake_minimum_required(VERSION 2.8)

project( nuvoton_read )

set(LIBS z)

add_executable( nuvoton_read nuvoton_read.cpp )

target_link_libraries( nuvoton_read  ${LIBS})
VyacheslavK
()
Ответ на: комментарий от VyacheslavK

А точно BIOS, а не драйвер? Надо сделать доброе дело и внести изменения в драйвер nct6775 (он уже в ядре). Утилятка для user-space - не шибко хорошее решение.

Note
====

This driver supercedes the NCT6775F and NCT6776F support in the W83627EHF
driver. It supports NCT6106D, NCT6775F, NCT6776F, NCT6779D, NCT6791D, and
NCT6792D.
Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Ай, нет. По-моему, он только температуру обслуживает. Мимо.

Zubok ★★★★★
()
Ответ на: комментарий от VyacheslavK

После дальнейших ковыряний и считывания конфигурации NCT6106D выяснилось, что BIOS неправильно конфигурирует эту микросхему.

Все верно. Нашел пост с похожей проблемой, где вылечилось обновлением BIOS. Единственное место, где можно было бы исправить - это стандартный драйвер 8250, так как этот NCT6106D не использует никаких специфичных для него драйверов для tty. А вот есть ли смысл делать какие-то специальные действия в драйверах 8250 для исправления ситуации конкретно с BIOS и этим чипом - это большой вопрос. Пока user-space утилита выглядит нормальным решением.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Сначала тоже пошёл по пути проверки драйвера nct6775. Тем более, что dmesg выдавал какие-то ошибки на этапе его загрузки. Но после знакомства с исходниками, выяснилось, что этот драйвер, как указал Zubok, отвечает за расширенную информацию с сенсоров.

Я отправил сообщение в службу поддержки Axiomtek (мой компьютер tBOX312-870-FL-i7) с описанием проблемы, её решением и просьбой предоставить скорректированную прошивку BIOS. Будем ждать. А пока так. Можно скрипт на автозапуск написать

VyacheslavK
()
Ответ на: комментарий от VyacheslavK

Axiomtek выслала мне прошивку, достаточно оперативно. Возможно, имело смысл сразу к ним обращаться. А я сначала к продавцам написал.

Обновлять буду позже, пока работу так поделаем.

VyacheslavK
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.