qemu早就可以跑stm32程序了。很簡單:
windows bat:
cd C:\Program Files\qemu
.\qemu-system-arm.exe ^
-M netduinoplus2 ^
-nographic ^
-kernel C:\Users\kk\STM32CubeIDE\workspace_1.4.0\uart405\Debug\uart405.elf
pause
(在window上安裝qemu軟件,然后把這段保存成 .bat 腳本,運行。然后就能在cmd窗口下看到程序的打印)

linux上的shell腳本可做類似修改。
1. stm32的源碼:
不廢話了,就是用stm32cubeIDE一鍵生成的代碼,選STM32F405RG,會stm32的知道,沒有難度。uart沒有使用中斷。rcc用的內部晶振,其實就是默認配置一點都沒改。
改動只有:
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
char *pData = "hello qemu\n";
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_UART_Transmit(&huart1, (uint8_t*)pData, strlen(pData), 100);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
2. 重點說說qemu的源碼:
hw/arm/netduinoplus2.c
static void netduinoplus2_init(MachineState *machine)
{
DeviceState *dev;
/*
* TODO: ideally we would model the SoC RCC and let it handle
* system_clock_scale, including its ability to define different
* possible SYSCLK sources.
*/
system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
dev = qdev_new(TYPE_STM32F405_SOC);
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
armv7m_load_kernel(ARM_CPU(first_cpu),
machine->kernel_filename,
FLASH_SIZE);
}
netduinoplus2是一種開發板,亞馬遜上有賣。它內置的就是一個STM32F405RG
在qemu里真正的芯片實現:hw/arm/stm32f405_soc.c
目前只實現了幾個外設,大部分是未實現的
#define SYSCFG_ADD 0x40013800
static const uint32_t usart_addr[] = { 0x40011000, 0x40004400, 0x40004800,
0x40004C00, 0x40005000, 0x40011400,
0x40007800, 0x40007C00 };
/* At the moment only Timer 2 to 5 are modelled */
static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
0x40000800, 0x40000C00 };
static const uint32_t adc_addr[] = { 0x40012000, 0x40012100, 0x40012200,
0x40012300, 0x40012400, 0x40012500 };
static const uint32_t spi_addr[] = { 0x40013000, 0x40003800, 0x40003C00,
0x40013400, 0x40015000, 0x40015400 };
#define EXTI_ADDR 0x40013C00
#define SYSCFG_IRQ 71
static const int usart_irq[] = { 37, 38, 39, 52, 53, 71, 82, 83 };
static const int timer_irq[] = { 28, 29, 30, 50 };
#define ADC_IRQ 18
static const int spi_irq[] = { 35, 36, 51, 0, 0, 0 };
static const int exti_irq[] = { 6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40,
40, 40, 40, 40, 40} ;
0x40011000就是uart1基地址,這個和stm32代碼、STM32F405RG是配套的。
uart1會被qemu默認映射到cmd窗口。qemu還支持映射到文件、網絡端口等等,參考qemu文檔
qemu支持gdb調試,會生成gdb server。命令如下
-gdb tcp::10101 ^
-S
可以用stm32cubeIDE通過TCP 端口遠程調試qemu里的程序。有時間再試
