Skip to content

Instantly share code, notes, and snippets.

@franzflasch
Last active December 4, 2024 11:41
Show Gist options
  • Save franzflasch/6c52f28eb1327213d5e83e299bd775eb to your computer and use it in GitHub Desktop.
Save franzflasch/6c52f28eb1327213d5e83e299bd775eb to your computer and use it in GitHub Desktop.
qemu-cortex-m-stm32

OPTION 1: Howto qemu cortex-m (stm32) 'vanilla' qemu

Install prerequisites

Note: This was tested with QEMU emulator version 8.2.2

sudo apt install qemu-system-arm

Build an stm32f1 example that uses the usart as printf like this:


#include <stdint.h>
#include <stdio.h>
#include <errno.h>

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/usart.h>


static void usart_setup(void)
{
        rcc_periph_clock_enable(RCC_USART1);

        /* Setup UART parameters. */
        usart_set_baudrate(USART1, 115200);
        usart_set_databits(USART1, 8);
        usart_set_stopbits(USART1, USART_STOPBITS_1);
        usart_set_mode(USART1, USART_MODE_TX);
        usart_set_parity(USART1, USART_PARITY_NONE);
        usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);

        /* Finally enable the USART. */
        usart_enable(USART1);
}

int _write(int file, char *ptr, int len)
{
        int i;

        if (file == 1) {
                for (i = 0; i < len; i++)
                        usart_send_blocking(USART1, ptr[i]);
                return i;
        }

        errno = EIO;
        return -1;
}

int main (void)
{
    usart_setup();
    
    printf("Hello to qemu from stm32f1\r\n");

    while (1)
    {
    ;
    }
}

At the time of writing initializing the HSE or HSI did not work, qemu was stuck in the initialization. For qemu it is not needed it seems.

Start qemu

qemu can be started like this:

qemu-system-arm -M stm32vldiscovery -kernel rem_workdir/arm_stm32f1/deploy/test_project_nohash/test_project.bin -nographic

The output should be printed directly to console.

Multiple serials

Multiple serials can be started like this:

qemu-system-arm -M stm32vldiscovery -kernel rem_workdir/arm_stm32f1/deploy/test_project_nohash/test_project.bin -nographic -serial tcp::45457,server,nowait -serial tcp::45458,server,nowait

It seems qemu will map one USART after the other to telnet as it is specified here: https://github.com/qemu/qemu/blob/master/hw/arm/stm32f100_soc.c#L39C54-L39C64

The serial output will then be redirected to (USART1)

telnet 127.0.0.1 45457

and (USART2)

telnet 127.0.0.1 45458

Note: Multiple serials were not tested, but from what I read it should work:
https://lists.nongnu.org/archive/html/qemu-discuss/2024-02/msg00032.html

OPTION 2: Howto qemu cortex-m (stm32) 'gnu-mcu-eclipse' qemu

Install prerequisites for qemu, some of them are:

apt-get install build-essential libglib2.0-dev zlib1g-dev libpixman-1-dev
apt-get install libsdl2*

Get qemu for cortex-m microcontrollers

git clone https://github.com/gnu-mcu-eclipse/qemu.git
cd qemu
git submodule update --init dtc

Build qemu from source

mkdir build
cd build
../configure --target-list="gnuarmeclipse-softmmu" --prefix=<qemu_build_dir>/_installed --disable-werror --with-sdlabi="2.0"
make && make install

Prepare some files

The qemu needs some jpg files and json configs prepared in the work directory (where qemu is started) so you need to copy the files (from the qemu bin dir, we use the olimex STM32-H103 board):

cd <qemu_build_dir>/_installed/bin
cp ../../../gnu-mcu-eclipse/devices/STM32F103xx-qemu.json .
cp ../../../gnu-mcu-eclipse/graphics/STM32-H103.jpg .

Start qemu (from qemu install bin dir)

./qemu-system-gnuarmeclipse --verbose --board STM32-H103 --image <image_deploy_dir>/test_project.elf

OPTIONAL: using qemu and gdb

1. start qemu session with:

qemu-system-gnuarmeclipse -s --verbose --board STM32-H103 --image <image_deploy_dir>/test_project.elf

2. start arm debugger

arm-none-eabi-gdb <image_deploy_dir>/test_project.elf

3. within gdb connect to the target:

target remote 172.17.0.1:1234

You can now set breakpoints etc. - do some default gdb to debug your program!

Have a nice day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment