Миллис против сентиса на платформе AVR

Я создаю устройство на платформе AVR. Устройству потребуется некоторая информация о времени, поэтому я подумал о повторной реализации millisфункциональности, подобной Arduino (хотя и не совсем такой ). Тем не менее, после выполнения некоторых расчетов обратного конверта (частично на основе этого поста ), мне стало казаться, что millisсъедает не менее 5% процессорного времени на 20-мегагерцовом процессоре и пропорционально больше, чем на 16-мегагерцовом:

  • Каждую миллисекунду таймер (timer0) переполняется, вызывает прерывание, которое увеличиваетmillis
  • ISR должен занять 26 тактов для процедуры до/после ISR (5 PUSH+ POPплюс CLR, IN, иRETI
  • Сам ISR должен занять около 21 такта (загрузить 32-битное значение, увеличить его и сохранить обратно в SRAM).
  • Это дает почти 50 тактов или 50 микросекунд каждую миллисекунду.
  • На самом деле, функция Arduino ISR работает медленнее (как показано в этом посте ), потому что она очень тщательно следит за тем, чтобы миллисекунды были максимально точными, что по-прежнему требует больше циклов ЦП.

Мне не нужна millisточность, поэтому я рассматриваю возможность реализации centisили даже decisсохранения циклов процессора для других вещей. Это неразумно? Мои расчеты неверны? Казалось бы, странный выбор дизайна, или я что-то упускаю?

Если вы не создаете его для программирования конечного пользователя, откажитесь от каких -либо функций для этого и просто делайте синхронизацию старомодным способом.
Разве вы не работаете на частоте 20 МГц? Тогда 50 тактовых циклов составляют около 3 мкс, а не 50. Кроме того, проверили ли вы сгенерированный машинный код, чтобы убедиться, что ваши числа верны - мне они кажутся немного завышенными.
@ТомЛ. Да, вы правы, забыл о 20 впереди, я считал скорость процессора 1 МГц. Я не декомпилировал код Arduino. Что кажется высоким?
@ IgnacioVazquez-Abrams Что такое «старомодный расчет времени»?
Выясните, сколько времени вам нужно, установите таймер и отпустите его.
Ну, мне нужно засечь несколько событий, которые имеют разные интервалы времени ожидания, следовательно, миллисекунды или эквивалент.
Что касается ваших расчетов: вы используете 8-битное или 32-битное устройство? Кроме того, оптимизатор сделает некоторые операции достаточно эффективными (возможно, некоторые операции загрузки/сохранения можно будет выполнить за один цикл). Это очень сильно зависит от вашей платформы, поэтому вы действительно можете проверить код, сгенерированный для этих оценок.
Я нахожу функцию «миллис» довольно хорошей идеей для простого планировщика, когда у вас есть несколько задач; Я использую почти идентичную реализацию в течение последних 10 лет.

Ответы (1)

50 тактов — это не 50 мкс при работе на частоте 16 МГц, это около 3 мкс. Так что 0,3% накладных расходов, а не 5%. Вы, конечно, можете это сделать, но у меня никогда раньше не было проблем с запуском небольшого ISR на частоте 1 кГц. Возможно, было бы неплохо повторно реализовать его, чтобы вы могли добавить больше вещей для запуска на каждом такте таймера или запланировать запуск вещей на будущие такты. Метод, который я использую довольно часто, заключается в том, чтобы запланировать выполнение чего-либо, например, с интервалом в 1 секунду, сохраняя текущее время + интервал в переменной, а затем, когда время превышает будущую временную метку, я увеличиваю временную метку на интервал, а затем запускаю код. Если тик пропускается, то текущий вызов просто задерживается на один тик. Было бы очень легко использовать этот метод для запуска вещей с интервалами в 10 мс или 100 мс.