Miosix in emulation

From Miosix Wiki
Revision as of 20:08, 11 June 2023 by Daniele.cattaneo (talk | contribs) (Create the page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

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.

Supported boards

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_DMA define:

/// 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.

Launching emulation

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 -s -S 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

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
  • Olimexino_STM32
  • STM32F103C8_BLUEPILL

The last one of these boards is supported in Miosix with the name stm32f103c8_breakout.

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 git://git.qemu-project.org and git://github.com/rth7680 with https://gitlab.com/qemu-project.

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

The setting -serial stdio allows to use the standard input/output devices for sending/receiving USART data.

Renode

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:

  1. 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.repl file, 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.

  2. Modify the GPIO pin associated to the UserLED because Miosix uses a different one. This could be done by modifying the renode/platforms/boards/stm32f4_discovery.repl file and substituting pin12 with pin14:
    gpioPortD:
        14 -> UserLED@0
    

Launching emulation

To launch an instance of Miosix, built for the stm32f407vg_stm32f4discovery target, launch Renode and write the following commands on the Renode console:

  1. Create a Machine, load the board and load the kernel:
    mach create
    machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl
    sysbus LoadELF @main.elf
    
  2. Open the serial monitor on USART3:
    showAnalyzer sysbus.usart3
    
  3. Start the GDB server (if needed):
    machine StartGdbServer 3333
    

    3333 is the remote port to specify in GDB to connect to the emulated machine.

  4. Start the machine:
    start
    

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.

Acknowledgments

Most of the contents of this page were contributed by Francesco Lenzi and Donato Carlo Giorgio. Thanks!