Эмуляция Arduino Uno с помощью QEMU: прерывания не работают
Итак, я написал этот код для Arduino Uno:
// file qemu.ino
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(millis());
}
А затем скомпилировал и загрузил его в настоящий микроконтроллер. Все работает как надо, печать миллисекунд прошла. Значение millis()
обновляется регулярно.
Затем я попытался выполнить тот же код в QEMU, используя эти команды:
arduino-cli compile -b arduino:avr:uno -e .
qemu-system-avr -M uno -nographic -bios build/arduino.avr.uno/qemu.ino.with_bootloader.bin
Последовательная печать работает, но millis()
все время остается на 0. Так что печатается просто куча нулей.
Дальнейшее исследование исходного кода Arduino выявило проблему: millis()
считывает переменную timer0_millis
, которая обновляется в ISR(TIMER0_OVF_vect)
, то есть в 16-м векторе прерывания. Функция init()
также обеспечивает включение этого прерывания.
Кроме того, поскольку millis()
никогда не обновляется, delay()
и Serial.read()
зависают навсегда.
Итак, вывод такой: прерывания работают на реальном устройстве, но по какой-то причине не работают на QEMU. Может быть я что-то упускаю?
@lch361, 👍1
Обсуждение1 ответ
В документации qemu-system-avr говорится:
[...] Контроллер ATmega, модель которого ограничена устройствами USART и 16-битного таймера, достаточными для запуска приложений на базе FreeRTOS [...]
Это означает, что эмулятор не поддерживает 8-битный таймер 0, который используется функциями синхронизации Arduino, такими как millis()
.
Это странно, поскольку Arduino практически невозможно использовать без timer0
., @Alexander Perechnev
@AlexanderPerechnev Вы не читали документацию по ссылке, не так ли? :-D Там четко указано, что этого достаточно для запуска FreeRTOS (добавлено в ответ сейчас). Некоторые Arduino, по-видимому, используются вне среды прошивки Arduino. Не все довольны ее ограничениями., @the busybee
Нет, не я. Я открыл эту тему просто потому, что интересно, что Qemu может эмулировать и устройства на базе AVR., @Alexander Perechnev
- ATmega328P - проблема с использованием таймера 2 для генерации тона
- Точность синхронизации Arduino nano
- Интервальный таймер на Arduino: Сомнения по поводу библиотеки TimerOne
- Можно ли отсоединить прерывание на определенное время
- Заставить TCNT оставаться ниже OCRxA на ATmega328P
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Генерация стабильной частоты
- 4-битный счетчик вверх и вниз
[Документация qemu-system-avr](https://qemu-project.gitlab.io/qemu/system/target-avr.html) говорит: «_[...] Контроллер ATmega, модель которого ограничена USART и 16-битными таймерными устройствами_». Не уверен, что понял это предложение. Это может означать, что эмулятор не поддерживает 8-битный таймер 0, который используется функциями синхронизации Arduino, такими как
millis()
., @Edgar BonetВы пришли к правильному выводу, @jsotola