Прекратить чтение байтов из последовательного порта (Python/RPi/UART)

Эта проблема довольно сложная. Кажется, у меня есть простая двусторонняя связь между двумя устройствами, где сторона чтения - Raspberry pi 3. Я пытаюсь передать файл. Я отправляю его по частям (5kb часть). Это выглядит как:

1) Отправляющая сторона отправляет первые 5 Кбайт (ровно 5136 байт, где первые 16 байт являются ID / SIZE / ADD_INFO / CRC)

2) RPi3 считывает 5136 байтов и вычисляет CRC для порции.

3) RPi3 сравнить CRC, полученный от отправляющей стороны и рассчитанный по RPi

4a) Если CRC не совпадает, я переключаю линии с линии RX на линию TX с помощью буфера с двойной шиной с выходами с 3 состояниями и устанавливаю High State на линию TX (я сохраняю это в течение 30 мс).

4b) Если CRC совпадает, я просто жду следующего фрагмента файла

5) Команды переключателя отправляющей стороны тоже и считывают мое состояние TX, если состояние HIGH/1 (когда CRC не совпадает), он отправляет тот же блок (повторную передачу), если состояние LOW/0 отправляет другой блок. (изменение состояния занимает 10 мс)

На осциллографе это выглядит так (4а):

4а

и это (4b):

4b

У блока 5136 есть свободное время для вычисления CRC, тогда у нас есть изменение состояния на стороне RPi3, если нужно, потому что CRC не совпадает (красные линии на 4a) и чтение стороны TX со стороны отправки.

Хорошо, теперь немного упрощенного кода из RPi:

def recv():
    while True:
        #Set line to low because I want to read data
        GPIO.output(16, GPIO.LOW)
        ID = ser.read(4)
        SIZE = ser.read(4)
        ADD_INFO = ser.read(4)
        CRC = ser.read(4)
        #get crc from sending side
        crc_chunk = int.from_bytes(CRC, byteorder='little')
        data = ser.read(5120)
        #calculating CRC from chunk
        rpiCRC = crcSTM(data)

        while True:
             <--- here I wait about 20ms to calculate CRC
            if rpiCRC != crc_chunk:
                #Crc doesn't match I want retransmission
                GPIO.output(16, GPIO.HIGH)
                <--- keep it HIGH for about 30ms
                break

            else:
                #keep it low because crc match and we are waiting for next chunk
                GPIO.output(16, GPIO.HIGH)
                break

Все это выглядит законным, но по существу. Я всегда получаю только первый кусок после того, как RPi просто перестает читать байты. Это происходит только в том случае, если в "4b" я получаю первый кусок правильно и жду следующего, а затем RPi просто прекращает читать байты или время от времени дает мне лишь некоторые царапины. Я проверяю, что если я правильно получу первый блок и настроил ретрансляцию, но все выглядит великолепно, и я получаю все время повторную передачу первого блока и получаю все время. Я пришел к этому, что изменение строки на отправляющей стороне, когда у меня есть состояние LOW/1, влияет на RPi и просто перестает правильно читать байты. Не знаю, почему это портит, и не знаю, как с этим бороться. Я попытался очистить буфер, закрыв порт перед отправкой боковой строки изменения и открыв ее после повторного изменения строки, но все это просто ничего не делает, что я могу сделать еще?

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

1 ответ

Решение

Хорошо, я борюсь с этим. Я включил опцию "Хотите ли вы, чтобы оболочка входа была доступна через последовательный порт" в sudo raspi-congif, Не знаю, почему это все портит, но отключить это исправить. Это довольно странно, потому что я некоторое время играю с Raspberry и Serial, и не было никаких проблем, если RPi3 отправлял что-то через uart или когда он просто читал без изменения строк и т. Д.:)

Другие вопросы по тегам