beckus / qemu_stm32 Goto Github PK
View Code? Open in Web Editor NEWThis project forked from qemu/qemu
QEMU with an STM32 microcontroller implementation
Home Page: http://beckus.github.io/qemu_stm32/
License: Other
This project forked from qemu/qemu
QEMU with an STM32 microcontroller implementation
Home Page: http://beckus.github.io/qemu_stm32/
License: Other
QEMU with STM32 Microcontroller Implementation Official Homepage: http://beckus.github.io/qemu_stm32/ OVERVIEW This is a copy of QEMU that has been modified to include an implementation of the STM32 microcontroller. It also implements an Olimex STM32_P103 developmentvboard. This project runs the demos located in the stm32_p103_demos project located at: https://github.com/beckus/stm32_p103_demos . Prerequisites - On a fresh install of Ubuntu 20.04, the following command will install dependencies: sudo apt-get install build-essential python zlib1g-dev libglib2.0-dev libpixman-1-dev libtool libfdt-dev Commands for a typical build: ./configure --enable-debug --disable-xen --disable-werror --target-list="arm-softmmu" make Useful make commands when rebuilding: make defconfig make clean Notes: * We pass the following option to the "configure" command to ignore warnings (otherwise warnings will cause the build to fail): --disable-werror * We disable xen support according to issue #42: #42 The generated executable is arm-softmmu/qemu-system-arm . Other configure options which control the STM32 implementation: --extra-cflags=-DDEBUG_CLKTREE Print out clock tree debug statements. --extra-cflags=-DDEBUG_STM32_RCC --extra-cflags=-DDEBUG_STM32_UART --extra-cflags=-DDEBUG_STM32_TIMER Print debug statements for specific peripherals. --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY Disable the BAUD rate timing simulation (i.e. the UART will transmit or receive as fast as possible, rather than using a realistic delay). --extra-cflags=-DSTM32_UART_ENABLE_OVERRUN Enable setting of the overrun flag if a character is received before the last one is processed. If this is not set, the UART will not receive the next character until the previous one is read by software. Although less realisitic, this is safer in case the VM is running slow. Other QEMU configure options which are useful for troubleshooting: --extra-cflags=-DDEBUG_GIC qemu-system-arm options which are useful for trobuleshooting: -d ? To see available log levels -d unimp,guest Enable logging to view warnings when an unimplemented register is accessed or when an invalid register access is attempted. This is especially useful since many registers are not implemented. -d cpu,in_asm Enable logging to view the CPU state during execution and the ARM instructions which are being executed. I believe --enable-debug must be used for this to work. By default, you can find the output in /tmp/qemu.log: UNIT TESTING Unit test scripts are included for the STM32 implementation. These test will be executed when running "make" with the standard check targets (see tests/Makefile for documentation of QEMU's unit testing features): make check make check-qtest-arm DOCKER CONTAINER A Docker container containing qemu_stm32 can be built from the Dockerfile: docker build . -t qemu_stm32 It can run the examples in stm32_p103_demos: docker run --rm qemu_stm32 /usr/local/bin/qemu-system-arm -M stm32-p103 -kernel /stm32_p103_demos/demos/freertos_singlethread/main.bin The original QEMU README follows: Read the documentation in qemu-doc.html or on http://wiki.qemu-project.org - QEMU team
qemu depends on glib, which has some deprecated function like g_mem_set_vtable
. These deprecated function produce error while compile.
The bugs is fixed in master branch at commit 98cf48, however the patch doesn't apply to stm32 branch yet.
Can somebody help me compiling the source code?
Hello
I have tried to use the machine stm32-f103c8
without success. I am stucked in the following error:
$ <path_to>/qemu_stm32/arm-softmmu/qemu-system-arm -machine stm32-p103 \
-semihosting -monitor stdio -kernel demo_vector.elf
(process:3764): GLib-WARNING **: 08:55:51.177: ../../../../glib/gmem.c:489: custom memory allocation vtable not supported
QEMU 2.1.3 monitor - type 'help' for more information
(qemu) VNC server running on `127.0.0.1:5900'
rom: requested regions overlap (rom phdr #2: demo_vector.elf. free=0x0000000008000304, addr=0x0000000008000280)
rom loading failed
I am using an standard linker file already used in non-simulated projects:
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20005000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
}
/* ... */
Looking in the file stm32_f103c8.c
I saw that 132kb is used instead of 64kb and I tried to use a linker file with 132kb of flash as well but the error remains. Similar targets generates the same problem (stm32-maple, stm32-p103).
The startup.s file came from a real project as well (provided by ST) and I compiled qemu from sources ( 2.1.3), branch stm32 (https://github.com/beckus/qemu_stm32).
Could anyone point me some directions ?
Thanks in advance.
Hi,
First thanks for this project, pretty happy it exists :)
I've been trying to run some code dumped from a running system and encoutering some issues. First one is linked to timers and IRQ.
First thing is definitely a bug in stm32.c there is
stm32_create_timer_dev(stm32_container, STM32_TIM1, 1, rcc_dev, gpio_dev, afio_dev, 0x40012C00, tim1_irqs, 5);
But that last '5' should be '4' because tim1_irqs is an array with 4 entries only.
Second thing is that I'm not even sure what this tries to accomplish. Because those 4 irqs, will end up calling sysbus_connect_irq multiple times, but it will just overwrite the previous value so in the end only the last value written will be "connected" AFAICT.
Cheers,
Sylvain
How to increase the flash limit? Qemu can't load bin file larger than 128k
qemu-system-arm: Could not load kernel 'demo.bin'
Hey, I want to develop a mechanical keyboard controller based on BluePill, but I want to develop on Qemu STM32. The question is how do I emulate contact on pins that will be connected to actual keyboard switches on the hardware? I already figured, thanks to someone on Stack Overflow I can do send-keys { b }
to emulate the onboard button. But pins are probably GPIO but I am still learning this.
This is what I've been able to do so far with QMP:
sleep 0.1s
echo '{ "execute": "qmp_capabilities" }'
sleep 0.1s
echo '{"execute":"send-key","arguments":{"hold-time": 1000, "keys":[{ "type": "qcode", "data": "b" }]}}'
echo '{"execute":"qom-list","arguments":{"path":"/machine/stm32/gpio[c]"}}'
sleep 0.1s
echo '{"execute":"qom-get","arguments":{"path":"/machine/stm32/gpio[c]","property":"gpio[0]"}}'
sleep 0.1s
echo '{"execute":"qom-get","arguments":{"path":"/machine/stm32/gpio[c]","property":"periph"}}'
sleep 0.1s
echo '{"execute":"qom-get","arguments":{"path":"/machine/stm32/gpio[c]","property":"legacy-stm32_rcc"}}'
sleep 0.1s
echo '{"execute":"quit","arguments":{}}'
sleep 0.1s
Hi Andre,
Thanks a lot for adding stm32 support to qemu!
I'm having some troubles with the USART though, maybe you can help me out. If data is received too fast from the host to the stm32 uart, I get a sort of overrun on the emulated receive path, both when polling USART_SR_RXNE and when using interrupts.
Let me describe the symptom with an example:
after this, nothing happens, the remaining 3 chars do not arrive. But then:
etc.
So it seems that the received bytes are queued somewhere within qemu, but the stm32 is not informed of waiting bytes by the RXNE flag.
Am I doing something wrong with wrong assumptions, or could this be a bug in the stm32 usart code?
Thanks!
I am testing some firmware using qemu_stm32, but now it is growing and gaining state stored in flash and I would like to make sure this is preserved and handled properly across reboots. But the only way I know to reboot qemu_stm32 is to stop it and restart it -- which of course wipes out state.
I tried added -monitor stdio
to the command line and then using system_reset
but it just gives an error that is out of my depth and my firmware stops responding and further resets don't work.
$ qemu-system-arm -nographic -M stm32-f103c8 -serial null -serial unix:./serial.sock -m 1 -kernel firmware.bin -s -monitor stdio
(process:11825): GLib-WARNING **: 15:42:04.853: ../glib/gmem.c:490: custom memory allocation vtable not supported
QEMU 2.1.3 monitor - type 'help' for more information
(qemu) LED Off
system_reset
(qemu) LED Off
qemu stm32: hardware warning: PLL cannot be disabled while it is selected as the system clock.
R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=00000000 R14=00000000 R15=00000000
PSR=40000153 -Z-- A svc32
qemu stm32: hardware warning: HSE oscillator cannot be disabled while it is driving the system clock.
R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=00000000 R14=00000000 R15=00000000
PSR=40000153 -Z-- A svc32
system_reset
(qemu) LED Off
system_reset
(qemu) LED Off
system_reset
(qemu) LED Off
If I trace what is going on with (qemu) gdbserver
+ arm-none-eabi-gdb -ex "target remote :1234"
then I see that the reset is triggering something, my firmware is jumping into one of its reset routines, but then it crashes before getting to main(). So I guess my firmware has a bug and cannot handle the system_reset
reset, though it works fine from a cold boot.
I found https://wiki.qemu.org/Features/ResetAPI from upstream qemu (so maybe it's inaccurate) which looks like it's talking about how resets are handled in QEMU...or maybe how resets should but are not yet handled. It says
reset
Bring the state of hardware state to consistent state. (some state might be left unknown.)system reset
a hardware mechanism for setting or returning all hardware states to the initial conditions.cold reset(power on reset)
system reset following the application of power.warm reset
system reset without cycling the supplied power.bus reset
Reset bus and devices on the bus.device/function reset
Reset triggered by sending reset command to a device. This is bus/device specific.hot reset
Qemu doesn't emulate physical layer, so we don't care it. From software point of view, hot reset has same effect to warm reset.
Do you know what kind system_reset
does? Is there any support for cold resets? Or, is there a way to shutdown but reload a flash memory dump?
I don't know what people normally do for testing firmware. I've learned that the Gnuk/chopstx codebase doesn't have virtual tests, it assumes it is testing a hardware device plugged in over USB: https://salsa.debian.org/gnuk-team/gnuk/gnuk/blob/master/tests/conftest.py. What do you think Pebble did before they shut down? Surely they must have had a ton of weird tests handling all sorts of stateful cases.
Hi Andre,
I did some tests with your STM32 version of QEMU and I'm impressed by the improvements, even SysTick seems functional :-)
However I have a problem, when GDB is connected to QEMU, the semihosting output is temporarily lost; after I disconnect GDB, the semihosting output resumes.
I know that this is not related to your added features, but in case you figure out how to fix it, I'd be happy to test it.
Regards,
Liviu
When using cmsis_rtos_v2 or v1 implementation generated from STM32CubeMX execution asserts on "obtained from hardware parameter. I can't understand what causes this but it is certainly incorrect and manual variable modification helps this code to pass. This code works on real bluepill stm32.
File: port.c from cmsis_rtos_v2
#ifdef configPRIO_BITS
{
/* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried
from the hardware. */
ulMaxPRIGROUPValue = 3; // qemu is broken here. was 4294967295
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
}
#endif
I assume that ulMaxPRIGROUPValue is incorrect. Due to an error in NVIC register values.
This one probably
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
Hi beckus,
I just clone qemu_stm32 stm32
branch and, after make it and make uart_echo_QEMURUN
, I found that serial0 didn't answer my input anyway.
But, after downloading v0.13, and redo again, uart_echo_QEMURUN works.
I'm wondering why stm32
branch didn't work, can you give me some clue?
thanks!
p.s. using: gcc6.1, archlinux-x64
Hey @beckus,
Thanks! The repo is absolutely great.
Do you have any idea how to start porting it to STM32G0?
I've been trying for quite some time to adapt the addresses according to the G0 reference manual, but still no luck.
Seems to be an issue with the RCC initialization.
Thanks.
Itamar
I'm running my application with:
qemu-system-arm -M stm32vldiscovery -kernel ./build/modbus_example.elf -gdb tcp::4242
and I can connect the GDB server as expected. However, I couldn't figure out how to add UART2.
I want to know how did you learn to change qemu's source code ? If there are any guides or tutorials please point me out. :))
The uart_index of the Stm32Uart
struct is never set.
The peripheral id or name can be used instead, using the periph
field or the stm32_periph_name
function. IMHO, the uart_index
can be simply removed.
gcc-10 will now stops on Warnings and creates an error which prevents compiling this qemu (tested on Debian/GNU Linux unstable). I would advise, until warnings are solved, to add in the README.md autoconf command line
--disable-werror
to at least allow compilation to complete. I successfully completed compilation with
./configure --enable-debug --target-list="arm-softmmu" --disable-gtk --disable-sdl --disable-werror
I test your qemu-stm32 using your stm32_p103_demos project. I use the command "make qemu_test_QEMURUN" to run. But it print the following error. I don't know how to solve it. Can you help me, thanks.
ling@UBUNTU64:~/Desktop/stm32_p103_demos$ make qemu_test_QEMURUN
killall -q qemu-system-arm
make: [qemu_test_QEMURUN] error 1 (ignore)
/home/ling/Desktop/beckus-qemu_stm32-b37686f/arm-softmmu/qemu-system-arm -M stm32-p103 -kernel demos/qemu_test/main.bin
qemu-system-arm: -kernel demos/qemu_test/main.bin: Unsupported machine type
Use -machine help to list supported machines!
make: *** [qemu_test_QEMURUN] error 1
Hi,
When starting FreeRTOS port for STM32f103c8 an assert is fired in BaseType_t xPortStartScheduler( void )
(Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c:310
if generated with STM32CubeMX).
code that breaks:
defined somewhere else:
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
// begin value
ucMaxPriorityValue = 255 '\377' // on qemu_stm32
ucMaxPriorityValue = 240 '\360' // on real bluepill board
port.c:289:
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
ulMaxPRIGROUPValue--;
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}
#ifdef configPRIO_BITS
{
/* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried
from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
// ulMaxPRIGROUPValue = 4294967295 on qemu_stm32
// ulMaxPRIGROUPValue = 3 on real bluepill board
}
#endif
Seems like a overflow of some kind, not sure why it is happening yet. Commenting out the configASSERT()
makes the code run without any (noticeable) issues.
Today as I compile qemu-stm32
I ran into this compiler error
g_mem_set_vtable is deprecated
in vl.c:2951
There are some similar patches in other project depended on glib, such as these:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg01262.html
I will dig into this issue and try to fix them.
I test P103 uart, when press backspace get 127, but backspace should be 8.
Hi beckus,
Our project needs to use qemu to simulate a stm32 board with Ethernet or Wifi network support. Do you have any machines in your project that can support network peripheral?
We really appreciate your help.
Hi,
Is there a way to compile it with python3?
Are there plans to support python3?
-Anuraj
First, I clone form git.
git clone git://github.com/beckus/qemu_stm32.git
My config:
./configure --disable-werror --enable-debug
--target-list="arm-softmmu"
--extra-cflags=-DDEBUG_CLKTREE
--extra-cflags=-DDEBUG_STM32_RCC
--extra-cflags=-DDEBUG_STM32_UART
--extra-cflags=-DSTM32_UART_NO_BAUD_DELAY
--extra-cflags=-DSTM32_UART_ENABLE_OVERRUN
And then I build QEMU, strange error message occurred:
https://gist.github.com/kevinkao7960/9c775af56f0146392bbd
I have tried upgrading my system and installing libfdt-dev, but they don't work.
When running "make check-qtest-arm", the test seems to hang after displaying the first "LED Off" output. I see this behavior as far back as commit e85cdf1 .
I am using this version of qemu for teaching FreeRTOS including inconsistent access to a shared resource in a multitasking environment. Using the example at https://github.com/jmfriedt/tp_freertos/tree/master/3mutex I show how a slow peripheral such as a UART leads to unpredictable result if accessing the resource is not protected with a mutex. On both the hardware microcontroller and older versions of this qemu, the result should be
LED Off
22222222222222222221111111111111111222222222222222222222211111111111111111111122
111111
22222222222222222221111111111111111111112222222222222222222221111111111111111111111222
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
1111111111111111111222222222222222222222111111111111111111111222222222222222222222111
2
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222111111111111111111111
111111111111111111122222222222222222222111
22222222222222221111111111111111111112222222
1111111111111111111111
2222222222222222222222111111111111111111112222222222222222222221111111111111111111111
1
9 2222222222222222222222222222222222222222222
but now the result is
LED Off
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222
1111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222
meaning that the long delay introduced by a UART communication leading to the FreeRTOS scheduler to switch task is no longer detected by the emulator.
I git bisected the problem to commit 4ac96ba since 9852410 is still good. This commit is entitled "fix slow event loop" and touches hw/char/stm32_uart.c
: I believe the correction brought with this commit is incorrect and breaks the valid behaviour of the emulator.
Edit: I realize the change in behaviour is introduced by #define STM32_UART_NO_BAUD_DELAY
: commenting this options resumes to the original behaviour. I wonder what is the rationale for breaking proper peripheral timing analysis which seems to me as one of the highlights of qemu.
I have failed running examples linked with libopencm3 on qemu for STM32. Namely, starting an ADC conversion with adc_start_conversion_regular(ADC1); hangs. Indeed, this function tests the
ADC_CR2_SWSTART bit of ADC_CR2 to check that conversion has started. In the RM0008 user manual of the STM32F1, we are told (p.231) that
Bit 22 SWSTART: Start conversion of regular channels
This bit is set by software to start conversion and cleared by hardware as soon as conversion
starts. It starts a conversion of a group of regular channels if SWSTART is selected as trigger
event by the EXTSEL[2:0] bits.
so I think it is reasonable to conclude stm32_adc_start_conv(Stm32Adc *s) of hw/arm/stm32_adc.c with s->ADC_CR2&=~ADC_CR2_SWSTART; just before timer_mod. At least this solves the libopencm3 ADC conversion initialization issue.
On a current (Dec. 2022) Debian/GNU Linux system, if libxen-dev is installed, the configure
command will automatically enable Xen support
xen support yes
but the API seems no longer compatible with some function no longer available, making the compilation fail. Disabling explicitly Xen support
./configure --enable-debug --disable-xen --disable-werror --target-list="arm-softmmu"
solves the issue.
I try to follow the installation instruction. However when I mak
e, the compiler can't find Cocoa/Cocoa.h
header. Following is the error message.
OBJC ui/cocoa.o
ui/cocoa.m:25:9: fatal error: 'Cocoa/Cocoa.h' file not found
#import <Cocoa/Cocoa.h>
^~~~~~~~~~~~~~~
1 error generated.
make: *** [ui/cocoa.o] Error 1
I wonder if I miss some dependency to install?
I have had a couple discussions regarding merging the latest version of QEMU. I decided to open an issue to facilitate collaboration and avoid duplication of effort.
The last time I tried to merge the latest version of QEMU, it broke the unit tests (I don't recall if there were any other issues). While my original philosophy was to keep the unit tests working, I think it may be time to abandon them and let them break, and instead give priority to finishing the merge.
There was a pull request #16 opened for merging QEMU 2.7 - I did not finish looking at it, but it appeared that it was just a brute force merge that broke QEMU STM32 - i.e. the merge overwrote critical pieces, and the QEMU STM32 machine still needed to be re-incorporated. So, I never finished addressing this pull request. At this point, it is probably better to start a new merge process and close the pull request.
Incidentally, one thing I had hoped to do in tandem with the merge would be to update QEMU STM32 to use the QOM framework: the way I originally built the machine is kind of a hack, and using QOM seems to make things more elegant and scalable, and would also allow the peripherals to be viewed from within the device tree. But, the level of effort of doing this is probably too high (and would introduce risk of breaking things). But, this may be a worthwhile investment for anyone using QEMU for serious purposes, e.g. commercially.
At https://qemu.readthedocs.io/en/latest/system/arm/stm32.html, QEMU lists some available machines based on the stm32 chips, but there are lots of missing devices
A naive question, but does this project emulate the devices listed there as "Missing Devices" ?
I will try building it and run it, though a confirmation from your side will be helpful. Though Thanks for creating a project specifically for stm32.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.