Shortcut & Brickgeek
Shortcut Shortcut
Ну что, ты же годами занимаешься изготовлением прецизионных шестеренок – давай вместе разработаем самый быстрый и эффективный таймер для спидраннинга? Я помешан на том, чтобы срезать каждую миллисекунду.
Brickgeek Brickgeek
Отлично, договорились. Я принесу плату, ты – генератор тактовых импульсов. Постараемся удержать джиттер меньше микросекунды, уберем лишние светодиоды и используем кварц на 32 мегагерца с фазовым локом, чтобы счетчик работал безошибочно. Я могу еще и реальный kernel поднять, чтобы обновление экрана происходило менее чем за 5 миллисекунд. Сначала проверим все на макетной плате, а потом зальём всё в эпоксидку. Сколько циклов ты планируешь срезать?
Shortcut Shortcut
Давай сократим цикл обновления экрана до 150 миллисекунд, а потом ещё постараемся убрать 30–40 миллисекунд с основного цикла. Тогда общее время работы будет в рекорды. Понял, цель – 150 миллисекунд на цикл обновления экрана и снижение основного цикла ещё на 30–40 миллисекунд. Это то, что нужно для рекорда.
Brickgeek Brickgeek
Отлично. Я возьму Cortex‑M4 с частотой 168 мегагерц, отключу все прерывания, кроме таймера, и оставлю основной цикл максимально быстрым – просто перебор светодиодной матрицы. Использую DMA для подкачки драйвера дисплея, чтобы процессор мог простаивать во время обновления. В пределах 150 миллисекунд сможем выводить изображение с частотой 200 герц, то есть 5 миллисекунд на кадр – значительно меньше вашего целевого значения. Остальные 30–40 миллисекунд высвободим, сократив опрос датчиков только до критически важных проверок. Нарисую схему таймингов, и посмотрим, где теряются микросекунды.
Shortcut Shortcut
Звучит неплохо – Cortex‑M4 на 168 мегагерц, только прерывания по таймеру, плотный цикл для работы с матрицей, DMA для дисплея. Частота обновления 200 герц даёт нам 5 миллисекунд на кадр, а если сократить опросы датчиков до самого необходимого, то ещё 30-40 миллисекунд можно выжать. Давай глянем на временную диаграмму и посчитаем все цифры. Мы выжмем из нее максимум.
Brickgeek Brickgeek
Вот набросок: • Тактовый генератор – 168 МГц, предделитель 1 → ядро работает на полную. • Таймер 1 работает на 1 кГц (период 1 мс), чтобы обновлять дисплей. • DMA передает 32-байтовую строку драйверу светодиодов за один раз, всего 20 мкс. • Главный цикл: чтение кнопки, обновление состояния, счетчик цикла; примерно 35 мкс. • Чтение датчика: всего два пина, по 1 мкс каждый. Итого за цикл: 5 мс DMA + 35 мкс цикл + 2 мкс датчик = примерно 5.04 мс. При частоте 200 Гц получаем 150 мс на кадр. Это наша цель. Теперь просто подкрути длительность DMA-пакетов и посмотри, как себя ведет кэш процессора. Сэкономим последние микросекунды, встроив автомат состояний непосредственно в код. Давай соберем прототип и запустим логирование времени. Таймер 1 выставлен на 1 кГц, DMA тянет строку размером 32 байта за 20 мкс, цикл работает не больше 35 мкс, чтение датчика – два запроса по 1 мкс. Получается, один цикл занимает около 5.04 мс. При 200 Гц получаем 150 мс на кадр. Теперь нужно подправить размер DMA-пакетов и встроить автомат состояний – и мы точно уложимся в нужное время. Давай соберем прототип и логируем количество циклов.