Можно ли использовать Arduino, чтобы «шпионить» за UART-соединением между двумя устройствами?

11

У меня есть необходимость установить Arduino (фактически только IC) в существующее оборудование для улучшения функциональности.

Я хотел бы подключить Arduino так, чтобы он «шпионил» за линии ввода / вывода между двумя чипами на плате. Если Arduino подберет определенное ключевое слово для этого соединения UART, он выполнит определенное действие на отдельном наборе выходных контактов.

В чем я не уверен, так это в том, как подключить Arduino таким образом, чтобы он мог декодировать существующее соединение UART без участия? Если это невозможно, меня интересуют теории, идеи и т. Д.

Брэд Хейн
источник

Ответы:

17

Если я правильно понимаю, у вас есть 2 устройства, подключенных через UART. Я полагаю, только линии TX, RX и GND подключены между устройствами? (т.е. не используются линии управления DTS / CTS / DTR / RTS - это типично).

В этом сценарии TX (передача) устройства 1 подключается к RX (прием) устройства 2, и наоборот. Их основания связаны друг с другом. Таким образом, каждое устройство может передавать и принимать одновременно (каждое передает по отдельному проводу, связь дуплексная).

Причина, по которой я упоминаю все это, состоит в том, что становится ясно, что для «прослушивания» или «прослушивания» вам на самом деле понадобятся 2 UART для прослушивания обеих сторон разговора.

По сути, все, что вам нужно сделать, это убедиться, что UART GND всех 3 устройств закорочены, и подключить (на самом деле, «тройник», как в Т-образном фитинге, например, к трубопроводу) линии TX устройства 1 и устройства 2 к 2 линиям RX. на 2 UART. Убедитесь, что все скорости передачи настроены одинаково.

Существует много плат / дизайнов Arduino. Наиболее распространенный в настоящее время, Duemilanove, использует ATMega328P, который, я думаю, имеет только 1 UART (ну, USART). Таким образом, вам придется либо подключить 2-ю микросхему UART, либо прибегнуть к «битам» на втором приемнике.

Асинхронная связь UART четко определена, с битами запуска и останова (и иногда битами четности), поэтому, если ваш процессор достаточно быстр, вы можете просто подключить одну из линий UART TX устройства к GPIO, настроенному как вход, и опросить линию достаточно быстро с передискретизацией, чтобы обнаружить START & STOP и выборочные биты. Статья Джека Гэнсла "Удар по битам" даст вам много возможностей для пережевывания.

Достойное описание формы сигнала RS232 можно найти на BeyondLogic .

Обратите внимание, что есть другие проблемы, такие как уровни напряжения (0 / + 5, -10 В / + 10 В и т. Д.), Которые вам необходимо принять во внимание (см. Раздел «Вне логики» в разделе «Преобразователи уровня RS232»). У меня недостаточно информации о вашей системе, чтобы обсудить аппаратное взаимодействие, кроме подхода «соединить линии», который обсуждался выше. Предполагая, что уровни напряжения совпадают, как правило, не проблема «подать» линию TX во второй приемник (сниффер), но если TX не хватает диска, вам может понадобиться вставить буфер / драйвер, чтобы предотвратить сигнал от унизительного.

радиан
источник
Красивый! Мне понадобятся только данные, движущиеся в одном направлении, поэтому достаточно одного UART на чипе ATMega! Две микросхемы взаимодействуют с +/- 5 В UART, который, как я думаю, такой же, как и ATMega. Вау, так и должно быть! Спасибо!
Брэд Хейн
@BradHein, то, что вы называете «+/- 5 В», обычно называют «уровнем TTL» - см. En.wikipedia.org/wiki/Logic_level .
Мэлс
3
@Mels +/- 5 В НЕ ТТЛ, ТТЛ НЕ опускается ниже уровня земли. Это RS-232.
nmz787
9

Есть изящный прием, который вы можете сделать, если связь осуществляется только в одном направлении за раз (то есть полудуплексная связь). Это не сработает, если обе стороны будут разговаривать друг с другом одновременно (полный дуплекс), но если это ваш типичный «сделай это», «хорошо, вот ответ», «теперь сделай это», «хорошо, вот новый ответ». это работает довольно хорошо.

Поскольку канал UART использует состояние простоя передатчика на высоком логическом уровне (1), вы должны использовать логический вентиль AND с двумя входами и подключать TX с каждой стороны ко входу AND. Выход логического элемента AND является вашим входом в UART вашего сниффера (это RX-вывод). Теперь возьмите линию TX устройства B и также перенесите ее в порт ввода-вывода на анализаторе. Вы сконфигурируете сниффер для генерации прерывания, когда этот вывод переходит от высокого к низкому.

Подведем итоги: устройство A UART TX -> вход Gate. Устройство B UART TX -> другой вход И вход шлюза И сниффер GPIO контакт. Вывод логического элемента И -> анализатор UART RX.

Связь UART состоит из начального бита, некоторого количества битов данных, необязательного бита четности и одного или нескольких стоповых битов. Поскольку состояние ожидания имеет высокий логический уровень (1), начало КАЖДОГО байта будет низким логическим значением (0), и прерывание на анализаторе сработает. Пока ваш анализатор выполняет прерывание ввода / вывода, оборудование UART будет собирать биты из логического элемента AND. К тому времени, когда UART получит стоп-бит, прерывание ввода-вывода будет долгим, и прерывание UART RX сработает.

Процедура прерывания при изменении ввода-вывода установит переменную «direction», чтобы указать, что обмен данными осуществляется в направлении «B-> A». Приемное прерывание UART сниффера будет смотреть на эту переменную «direction» и записывать только что полученный байт в соответствующий буфер. Затем прерывание UART RX вернет переменную direction в состояние по умолчанию «A-> B»:

volatile int direction = 0;           /* 0 = A -> B */

void io_interrupt(void)
{
    direction = 1;                    /* switch direction, now B -> A */
}

void uart_interrupt(void)
{
    unsigned char b;

    b = UART_RX_REG;
    if(direction) {
        store_byte_to_device_b_sniff_buffer(b);
    } else {
        store_byte_to_device_a_sniff_buffer(b);
    }

    direction = 0;                   /* reset direction to default A -> B */
}

Этот код написан для ясности и не обязательно того, что вы написали бы в реальной ситуации. Лично я бы сделал «направление» указателем на соответствующую структуру FIFO, но это совсем другое упражнение. :-)

Когда устройство A говорит, линия ввода-вывода не перемещается (она остается на логической «1», поскольку передатчик UART устройства B находится в режиме ожидания), и прерывание UART RX получит байт, смотрите, что направление A-> B и сохранить данные в этот буфер. Когда устройство B разговаривает, линия ввода-вывода понижается, как только устройство B начинает выводить данные, а процедура прерывания ввода-вывода устанавливает направление, указывающее, что устройство B разговаривает. Прерывание UART RX в конечном итоге сработает после того, как будут собраны все биты, и, поскольку прерывание ввода / вывода позаботилось о правильной настройке регистра направления, полученный байт будет сохранен в правильном буфере.

Presto: полудуплексная связь между двумя устройствами, захваченная с помощью одной линии UART и линии ввода / вывода на анализаторе, без обмена битами по UART.

akohlsmith
источник
Интригующим. Это расширяет границы моего понимания, но это здорово! Одна часть, которую я не понимаю, это то, как UART анализатора связан с целью, чтобы он мог перехватывать оба направления коммуникации? У меня есть несколько доступных выводов ввода / вывода, поэтому могу ли я использовать два вывода ввода / вывода, используя этот метод, и эффективно собирать оба направления трафика?
Брэд Хейн
Линия анализатора UART RX подключена к выходу логического элемента AND. UART TX устройства A подключен к одному входу вентиля AND, а UART TX устройства B подключен к другому входу вентиля AND. Поскольку состояние бездействия (без трафика) UART является логическим «1», логический элемент И эффективно объединяет оба передаваемых сигнала в один. Линия ввода / вывода на анализаторе используется для обнаружения начального бита устройства B, чтобы он мог взять байт, который он получает на своем UART, и поместить его в соответствующий буфер (трафик устройства A или трафик устройства B).
akohlsmith
Фрагмент кода и разводка логического элемента AND позволяют анализатору регистрировать оба направления трафика с помощью одного UART. Это ТОЛЬКО работает, если трафик полудуплексный. Это означает, что когда одно устройство говорит, другое слушает. Если оба говорят одновременно (полный дуплекс), это не будет работать вообще.
akohlsmith
5

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

JustJeff
источник