Miosix in emulation
This page attempts to provide enough instructions to try out Miosix under the most common system emulators. Running Miosix under an emulator could be useful to try it out or debug it if you don't have (or if you don't want to buy) the required hardware.
Important: At the moment none of the emulators we have attempted to use have managed to properly boot a fully-functioning instance of Miosix which passes all self-tests. Some of them might work well enough for simple applications, but with gross inaccuracies. Hardware timers not running at the correct rate or at all is a common issue, also USART input appears to not work on any emulator. Therefore, do not base your opinion on Miosix on what you are going to see when following these instructions.
Miosix versions before 2.5, which are not tickless kernels, are known to work better under emulation.
QEMU is an open-source virtual machine monitor and emulator software capable to emulate a wide range of hardware, including CPUs, graphics adapters, network cards, and storage devices. It is commonly used by software, firmware and hardware engineers for testing, debugging, and virtualization purposes. Furthermore, QEMU is easy to set-up from the command line.
The QEMU Documentation mentions a few supported STM32 boards. Among those, the STM32VLDISCOVERY board is supported by Miosix as well. However, at the moment we are writing, the latest version of QEMU (8.0.2) lacks support for many STM32 devices, and therefore a non-negligible amount of peripherals and interfaces are not available for emulation. Additionally, even the existing implementation of supported devices appears to be incomplete.
To show the boards supported by the QEMU version installed on the system, type the following command:
qemu-system-arm -machine help
Configuration of Miosix
To make the Miosix kernel work on QEMU it is important to disable the DMA since it is unimplemented and will cause emulation to hang as soon as it is accessed.
To disable the DMA, it is sufficient to open the board settings file in the configuration architecture directory (
/miosix/config/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/board_settings.h) and comment out the
/// Serial port const unsigned int defaultSerial=1; const unsigned int defaultSerialSpeed=19200; const bool defaultSerialFlowctrl=false; //#define SERIAL_1_DMA <----- //#define SERIAL_2_DMA //Serial 1 is not used, so not enabling DMA //#define SERIAL_3_DMA //Serial 1 is not used, so not enabling DMA
It is also important to avoid the usage of unimplemented devices, such as GPIOs, therefore LEDs and buttons don't work.
To emulate the board and launch the freshly compiled Miosix kernel you can use the following command:
qemu-system-arm -M stm32vldiscovery -kernel main.bin
For debug purposes, it is possible to obtain a list of all the unimplemented devices used by Miosix by adding the
-d unimp argument to the command line.
Now, in the QEMU Monitor, it is possible to check the data transferred through the USART interface by opening the "View" pop-up menu on top and selecting "serial0".
Debugging the emulated machine with GDB
To use GDB to monitor the loaded kernel, it is important to open a localhost tcp communication port for it and to start the emulated board in frozen mode (freeze at program\_counter=1). This is done by adding the arguments
in the previously mentioned QEMU start emulation command. The first argument is the shorthand for
-gdb tcp:1234, while the second one is needed to start in frozen mode.
Now GDB can be started with the command:
arm-miosix-eabi-gdb main.elf -ex "target remote localhost:1234"
QEMU-STM32 is a QEMU fork which extends version 2.1.3 of the well-known emulator to the STM32 board family. In particular, the newly-supported boards are:
- Olimex STM32P103
The last one of these boards is supported in Miosix with the name
QEMU-STM32 predates the current support for STM32 microcontrollers available in mainline QEMU, however its support is more complete. On the other hand, the development of QEMU-STM32 appears to not be active anymore in 2023, therefore building it requires to install several legacy dependencies. Additionally, the repository appears to reference several now inaccessible submodules. Therefore, to build QEMU-STM32 it is necessary to manually edit the submodule configuration to replace
Once you have built QEMU-STM32, using it is no different than a more recent version of QEMU. The command line to use for launching a build of Miosix for the BluePill board is the following:
qemu-system-arm -machine stm32-f103c8 -kernel main.bin -serial stdio
-serial stdio allows to use the standard input/output devices for sending/receiving USART data.
Renode is an open-source simulation framework for hardware and software development. Its advertisements say it provides "a virtual environment where developers can simulate the behaviour of their devices and test their software on a virtual platform before deploying it on physical hardware".
Renode supports the STM32F4_DISCOVERY board, which is a popular and well-tested target for Miosix as well. Renode supports the DMA and GPIO peripherals of the STM32, therefore no specific modifications of the Miosix code are required.
Configuration of Renode
Before using the STM32F4_DISCOVERY on Renode, it is necessary to:
Add the CCM ('Core Coupled Memory') in the memory map of Renode because it is not implemented by default. The easiest way to solve this problem is to modify the
renode/platforms/cpus/stm32f4.replfile, where all MCU registers are mapped. The following lines need to be added at the end of the file:
ccm: Memory.MappedMemory @ sysbus 0x10000000 size: 0x10000
Note! Make sure the code has the same indentation shown above, because it is significant for the compilation of the Platform Descriptor file.
GPIOpin associated to the
UserLEDbecause Miosix uses a different one. This could be done by modifying the
renode/platforms/boards/stm32f4_discovery.replfile and substituting
gpioPortD: 14 -> UserLED@0
To launch an instance of Miosix, built for the
stm32f407vg_stm32f4discovery target, launch Renode and write the following commands on the Renode console:
Create a Machine, load the board and load the kernel:
mach create machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl sysbus LoadELF @main.elf
Open the serial monitor on USART3:
Start the GDB server (if needed):
machine StartGdbServer 3333
3333is the remote port to specify in GDB to connect to the emulated machine.
Start the machine:
Renode provides very useful debugging commands, mainly to monitor the status of devices, such as
sysbus.gpioPortD.UserLED State, or
sysbus.gpioPortD GetGPIOs which prints the status of all the GPIO portD pins. To enable logs type the command
sysbus LogPeripheralAccess sysbus.gpioPortD True.
Most of the contents of this page were contributed by Francesco Lenzi and Donato Carlo Giorgio. Thanks!