Я являюсь членом исследовательской группы, работающей над проектом, который включает в себя ASIC, передающую RF, и его беспроводной приемник, который должен в конечном итоге отправлять данные на ПК.
Приемник выводит быстрый , непрерывный, асинхронный, нестандартный последовательный сигнал (т. Е. Не SPI, I2C, UART и т. Д.), Поэтому моя работа заключается в написании программного обеспечения микроконтроллера для сопряжения приемника с компьютером. В настоящее время мой подход заключается в использовании инициируемых фронтом прерываний для помещения данных в кольцевой буфер и выполнения всего процесса побитового декодирования в основном цикле. Микроконтроллер должен одновременно выводить эти данные через USB (виртуальный com-порт) на компьютер.
Вот проблема, которую я имею, и одна, которую я ожидаю:
Я не могу обработать буферизованные данные достаточно быстро даже с моим довольно мощным процессором ARM Cortex M3 72 МГц. Скорость передачи составляет 400 кбит / с (2,5 мкс / бит). Для справки, это оставляет только 180 циклов на бит (включая декодирование И ISR, которое имеет ~ 30 циклов служебных данных!). MCU также должен выполнять множество других задач, которые он запрашивает в основном цикле.
Драйвер виртуального USB-порта USB также основан на прерываниях. Это делает меня почти уверенным, что драйвер в конечном итоге будет прерывать процессор так долго, что он пропускает окно 2,5 микросекунды (180 циклов), в котором может передаваться бит. Я не уверен, как обычно разрешаются конфликты / гонки прерываний.
Таким образом, вопрос заключается в том, что можно сделать, чтобы решить эти проблемы, или это неправильный подход вообще? Я готов рассмотреть и менее программно-ориентированные подходы. Например, использование выделенного USB-чипа с каким-то аппаратным конечным автоматом для декодирования, но это незнакомая территория.
Ответы:
Другой ответ: прекратите использовать прерывания.
Люди прыгают, чтобы использовать прерывания слишком легко. Лично я редко использую их, потому что они действительно тратят много времени, как вы обнаруживаете.
Часто можно написать основной цикл, который опрашивает все так быстро, что его задержка находится в пределах спецификации, и очень мало времени тратится впустую.
В цикле могут быть некоторые вещи, которые происходят гораздо чаще, чем другие. Возможно, например, входящие биты, и в этом случае добавьте больше этих тестов, чтобы больше процессора было выделено для этой задачи.
Могут быть некоторые события, для которых задержка этого подхода слишком высока. Например, вам может понадобиться очень точно синхронизированное событие. В этом случае имейте это событие на прерывании, и все остальное в цикле.
источник
Вы можете использовать FPGA вместо микроконтроллера для декодирования и буферизации беспроводного потока данных. Затем используйте процессор ARM для очистки буферов FPGA (например, с помощью интерфейса SPI) и отправьте содержимое через порт USB Comm. Это работает, но FPGA должна быть в состоянии легко поддерживать, пока вы можете обслуживать его достаточно часто, чтобы гарантировать, что его аппаратные буферы не переполняются (или если вы можете иметь дело с отброшенными данными на более высоком уровне протокола ).
источник
Легко: использовать микроконтроллер PSoC5 .
Вы имеете простоту использования микроконтроллера, плюс он содержит CPLD, так что вы можете создавать свои собственные аппаратные периферийные устройства в Verilog. Просто напишите свой декодер последовательных данных в verilog и используйте DMA для потоковой передачи на порт USB.
Между тем, мощное 32-разрядное ядро ARM может сбивать с толку инструкции Thumb.
источник
Я думаю, у вас есть классический выбор инженеров: быстро, дешево, работает: выберите два.
Решение @ vicatcu, безусловно, хорошее, но если вы не можете или не хотите добавлять к нему больше оборудования (включая более быстрый процессор), вам придется сделать выбор. Если это последовательное соединение является наиболее важным, чем вы должны сидеть в ISR, пока все биты не будут собраны. 180 инструкций на бит на самом деле совсем неплохо, но не пытайтесь делать все. Когда вы обнаружите начало передачи, вращайте, пока передача не будет завершена. Заполните результат в FIFO и затем возобновите нормальную обработку.
Вы не говорите, какова длительность каждой передачи, но если они короткие и бурные, это будет жизнеспособным решением. Я готов поспорить, что ваша виртуальная реализация COM-порта также имеет некоторую аппаратную буферизацию, поэтому «медленная» служба прерываний для нее не должна представлять особых проблем. Что касается остальной части того, что нужно сделать MCU ... у вас есть несколько проектных решений, которые необходимо принять.
источник
Прежде всего, мне уже нравятся некоторые ответы здесь, и некоторые получили мой голос.
Но просто для того, чтобы добавить другое возможное решение: учитывая ограничения вашего проекта, будет ли плохо добавлять второй микроконтроллер (будет ли это включать в себя еще одну работу платы)? Может быть, простой 8-битный микроконтроллер, который подключается к вашему Cortex-M3 через быструю периферию, такую как SPI. Выбранный вами 8-битный контроллер будет запрашивать биты и байты формы так же, как в выбранном ответе, но когда у него есть байт, он может вывести его в регистр данных SPI для передачи.
Сторона Cortex-M3 будет просто прерывать полученные данные SPI. Это сокращает ваше предыдущее внешнее прерывание, инициируемое по фронту 400 кГц, до 50 кГц.
Я полагаю, что это объясняется двумя причинами того, что некоторые другие методы (PSoC или добавленная FPGA) немного дороги (хотя это, вероятно, не имеет значения для академического проекта с небольшим объемом), и потому что это может позволить вам сохранить некоторые из структура вашего текущего кода.
Кроме этого, я думаю, что идея PSoC удивительна, если вы используете собственную периферийную периферию, которая передает данные через DMA на USB.
источник
Если ваш формат данных аналогичен формату UART, но с непредсказуемой, но согласованной скоростью передачи данных, я бы хотел использовать CPLD для преобразования каждого слова входящих данных в формат SPI или стандартную асинхронность. Я не думаю, что есть необходимость продвигаться полностью в сферу CPLD. На самом деле, даже дискретная логика может быть почти работоспособной. Если бы вы могли сгенерировать тактовую частоту, более чем в 5 раз превышающую желаемую скорость передачи данных, вы могли бы использовать счетчик деления на пять и деления на 16 с несколькими входами. Расположите счетчик деления на пять так, чтобы он удерживался в режиме сброса всякий раз, когда вход простаивает, а счетчик деления на 16 равен нулю. В противном случае генерируйте тактовый импульс SPI и увеличивайте счетчик деления на 16 каждый раз, когда счетчик деления на пять достигает 2.
Учитывая 5-кратную тактовую частоту, можно генерировать тактовую частоту SPI, используя 16V8 (наименьшее и самое дешевое в настоящее время доступное программируемое логическое устройство). Второй 16V8 или 22V10 может быть использован в качестве делителя дробной частоты для генерации тактовой частоты 5x, или можно использовать немного больший чип (CPLD) и делать все в одном.
Редактировать / Добавление
При дальнейшем рассмотрении, если кто-то собирается использовать CPLD, можно легко добавить несколько дополнительных улучшений в схему. Например, можно довольно легко добавить логику, чтобы схема остановилась до тех пор, пока она не получит как минимум 1,5-битные времена стопового бита, а затем 3,5-битные времена стартового бита; если он получает слишком короткий стартовый бит, он должен вернуться к поиску стопового бита. Кроме того, если используется SPI, можно использовать сигнал / CS, чтобы гарантировать, что принимающее устройство увидит данные в правильном кадре. Если устройство, принимающее данные SPI, может обрабатывать 10-битные кадры, можно отправлять такие кадры напрямую. В противном случае каждый десятибитный кадр может быть отправлен как 8-битный кадр с набором LSB (7 битов данных) и кадр со всеми свободными LSB (3 бита данных); тактовый сигнал SPI будет ускоряться во время стоп-битов, поэтому все данные будут отправлены.
Некоторые микроконтроллеры имеют довольно универсальные модули генерации ШИМ, которые включают в себя такие вещи, как возможность удерживать в сбросе внешним сигналом и синхронизировать их синхронизацию с выпуском такого сигнала. Если ваш микроконтроллер может сделать это, в зависимости от его точных функций, это может значительно упростить схемы CPLD или синхронизации.
Другой подход, который несколько коснулся Rocketmagnet, заключался бы в том, чтобы иметь небольшой микроэлемент, единственная цель которого - декодировать последовательные данные и преобразовывать их в формат, используемый основным микро. Ваша скорость передачи данных 400 кГц довольно высока для программного декодирования, но что-то вроде PIC могло бы справиться с этим, если бы не нужно было ничего делать одновременно. В зависимости от того, с какими устройствами вы знакомы, это может быть проще или сложнее, чем с использованием CPLD.
источник