Эмуляция 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. Может быть я что-то упускаю?

, 👍1

Обсуждение

[Документация qemu-system-avr](https://qemu-project.gitlab.io/qemu/system/target-avr.html) говорит: «_[...] Контроллер ATmega, модель которого ограничена USART и 16-битными таймерными устройствами_». Не уверен, что понял это предложение. Это может означать, что эмулятор не поддерживает 8-битный таймер 0, который используется функциями синхронизации Arduino, такими как millis()., @Edgar Bonet

Вы пришли к правильному выводу, @jsotola


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