Может ли Raspberry Pi надежно поразить серийный номер 9600 бод и есть ли пример кода?


29

Мне интересно, насколько возможно использовать бит-бэнгинг для управления последовательностью 9600 бод через контакты GPIO на Raspberry Pi.

Очевидно, что Linux не очень хорошая платформа для бит-бенга, поскольку существует большое количество драйверов и других прерываний, которые могут блокировать процессор на длительные периоды времени (1-10 мс). Однако в последнее время ситуация значительно улучшилась, и теперь в ядрах регулярно включаются некоторые упреждения. Я также подозреваю, что на Raspberry Pi можно легко использовать исправленное ядро ​​в режиме реального времени, а также тщательно выбирать подключенное оборудование и драйверы.

Моим стандартом надежности является то, что большую часть времени он должен оставаться в пределах нормальных допусков 9600 бод. В настоящее время я не уверен, сколько ошибок допустимо на практике, но в протоколе есть повторные передачи и подтверждения, поэтому он по крайней мере несколько терпим.

Итак, мои вопросы:

  • Может ли программное обеспечение пользователя надежно работать на скорости 9600 бод?
  • Нужно ли для этого исправленное ядро ​​в реальном времени?
  • Сколько ошибок мне следует ожидать в целом?

Кроме того, есть ли какой-нибудь пример кода, выполняющего последовательное соединение по битам GPIO? Я знаю об Arduino SoftSerial, но это все.

На всякий случай, чтобы ограничить вопрос: это не стандартный последовательный интерфейс, а UART Raspberry Pi уже используется для другого последовательного соединения. Я не желаю ответов, которые предлагают внешнее оборудование (например, Gertboard или Arduino), а также ответы, которые зависят от UART.


1
+1 Хороший вопрос. Я также был бы заинтересован в ответе на это. Однако вопрос reliabilityможет зависеть от действий и ожиданий.
Jivings

2
RS-232 требует отрицательного напряжения, но этот последовательный канал не использует напряжения RS-232. Я не знаю, но я полагаю, что RPi требует стандартного конвертера TTL в RS-232, такого как MAX232 или любого из десятков вариантов. Однако, чтобы было ясно, это не относится к моему вопросу, я просто хотел ответить.
Nakedible

4
Также есть второй UART на выводах GPIO 14 и 15. Это не так полно, как основной, хотя
Джон Ла Руи


1
@Nakedible не могли бы вы поделиться своей работой? У меня похожая проблема, и я хотел бы увидеть, как вы сделали второй сериал через spi. спасибо MSP

Ответы:


15

Я наконец решил это, но довольно неортодоксальным способом. Я отказался от бит-бенга как слишком ненадежного и попытался найти другие решения, которые позволили бы мне то же самое, не добавляя больше оборудования. Я собирался написать драйвер ядра, который бы вызывал прерывание на GPIO, а затем перенастраивал вывод на SPI и использовал SPI для чтения всего байта данных - но потом я получил более удачную идею.

Я использую SPI для выборки линий со скоростью 20x. Я полностью игнорирую выводы SCLK и SS, подключаю линию RX к MISO и линию TX к MOSI. Это дает мне (1-битное) осциллографическое представление в линии RX и ясно видеть биты, передаваемые в последовательной линии:

00 00 00 00 00 00 
00 00 00 00 01 FF 
FF FF FF FF 00 00 
01 FF FF FF FF FF 
FF FF E0 00 00 00 
00 00 07 FF FF FF 
FF FF 

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

Причина, по которой это работает лучше, чем синхронизация по битам, заключается в том, что SPI имеет свои собственные часы, которые не зависают с ядром, а строки приема и передачи SPI имеют 16-байтовый FIFO для передачи, который также не зависит от зависаний ядра. Для 9600 бод я использую тактовую частоту SPI 250 кГц, и это означает, что я могу спать даже миллисекунду между заполнением и опустошением FIFO без каких-либо ошибок передачи. Однако, чтобы ошибиться, я использую 300 мкс сна. Я кратко проверил, насколько далеко я могу продвинуться, и, по крайней мере, тактовая частота SPI 2 МГц все еще использовалась, поэтому это решение также масштабируется до более высоких скоростей передачи.

Одна неприятная часть этого решения состоит в том, что драйвер SPI ядра не поддерживает такую ​​потоковую передачу битов. Это означает, что я не могу сделать это, написав свой собственный модуль ядра, используя драйвер SPI ядра, и я также не могу сделать это, используя /dev/sdidev0.0 из пользовательского пространства. Однако на Raspberry Pi SPI и другие периферийные устройства доступны непосредственно из пользовательского пространства с помощью mmap (): n / dev / mem, полностью минуя управление ядром. Я не очень доволен этим, но он работает отлично, и это дает дополнительное преимущество, что ошибки сегментации в пользовательском пространстве не могут привести к сбою ядра (если только случайно не возиться с другими периферийными устройствами). Что касается использования ЦП, 300 мкс-снов, кажется, дают мне около 7% использования ЦП постоянно, но мой код очень неоптимальный. Увеличение продолжительности сна, очевидно, снижает загрузку процессора напрямую.

Изменить: Забыл упомянуть, я использовал хорошую библиотеку bcm2835 для управления SPI из пользовательского пространства, расширяя его при необходимости.

Итак, подведем итог: я могу надежно передавать и получать по 9600 бод последовательному каналу полностью из пользовательского пространства, напрямую используя чип SPI через / dev / mem при 250 кГц на Raspberry Pi.


@ Nakedible - Можете немного рассказать или предоставить ссылки на часть mmap (). Я работаю над тем же.
Джей К

Используете ли вы оборудование SPI для передачи?
Гепард

Да, передача работает также.
Nakedible

3
Можете ли вы дать пошаговые инструкции о том, как вы можете отправлять и получать код, и делиться любыми модифицированными пакетами, если вы используете что-то, что вы исправили сами ... TIA!
Валентин

10

Казалось бы, по крайней мере без исправлений в реальном времени (CONFIG_PREEMPT_RT), Raspberry Pi не может надежно побить 9600 бод последовательный.

Я использовал простой тестер задержки, который оптимально настроил все стороны Linux (sched_fifo, priority 99, cpu_dma_latench 0us, mlockall). Я пробовал спать в течение 100 мкс (примерно 9600 бод) и проверять превышение задержки в тихой системе в течение 2 минут. Результаты были:

Мин .: 12 мкс. Средняя: 24 мкс. Макс .: 282 мкс.

Это казалось общим результатом. Максимум варьировался при более медленных измерениях от 100 мкс до 300 мкс. Я также проверил распределение, и кажется, что подавляющее большинство находится в диапазоне 24 мкс. Есть только несколько, которые превышают 50 мкс, но есть почти всегда некоторые. Иногда бывают и огромные задержки, например 4000 мкс, но они достаточно редки, чтобы их игнорировать, по крайней мере, пока.

Я полагаю, что максимальные задержки должны быть ниже 50 мкс для 9600 бод, чтобы не возникали ошибки, и любая задержка свыше 100 мкс приводит к тому, что при передаче или приеме полностью пропускается бит.

Это все, даже не касаясь контактов GPIO еще. Так как я не смог получить пробный запуск даже с двумя секундами, можно с уверенностью сказать, что без исправлений в реальном времени Raspberry Pi не сможет выполнить битовую передачу последовательного канала 9600 бод без генерации ошибок в течение какого-либо серьезного времени.

Я буду тестировать патчи в реальном времени позже, если у меня будет время.

(Используемый инструмент: http://git.kernel.org/?p=linux/kernel/git/clrkwllms/rt-tests.git;a=summary )

Обновление: ядро ​​RPi зависает при загрузке без обнаружения SD-карты, если оно скомпилировано с набором патчей CONFIG_PREEMPT_RT. Это может быть легко исправить, но, глядя на грязные различия в исходниках RPi, я думаю, что я хочу подождать, пока их больше не будет в основном ядре.

Итак, тестирование это слишком сложно, и я отказываюсь от него.


0

Вам не нужно кусать удар. Вы можете настроить пользовательское прерывание земли в rx gpio, чтобы обнаружить падение начального бита. затем установите прерывание по времени для выборки в середине битов. Модуль ядра делает это выполнимым.


Но это все еще немного стучит. На самом деле, это то, как вы обычно делаете удары.
Филиппос
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.