概述
本文主要描述了在Qemu平台中,如何添加STM32F407的USART控制器模拟代码。
板子截图:
参考资料
STM32F4XX TRM手册,手册编号:RM0090
添加步骤
1、在hw/arm/Kconfig文件中添加STM32F4XX_USART,如下所示:
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -338,6 +338,7 @@ config STM32F407_SOC
select OR_IRQ
select STM32F4XX_SYSCFG
select STM32F4XX_EXTI
+ select STM32F4XX_USART
2、在include/hw/arm/stm32f407_soc.h文件中添加
--- a/include/hw/arm/stm32f407_soc.h
+++ b/include/hw/arm/stm32f407_soc.h
@@ -25,6 +25,7 @@
#include "hw/arm/armv7m.h"
#include "hw/misc/stm32f4xx_syscfg.h"
#include "hw/misc/stm32f4xx_exti.h"
+#include "hw/char/stm32f4xx_usart.h"
#define TYPE_STM32F407_SOC "stm32f407-soc"
#define STM32F407_SOC(obj) \
@@ -35,6 +36,12 @@
#define EXIT_BASE_ADDRESS 0x40013C00
+#define STM_NUM_USARTS 4
+#define STM32F407_USART1 0x40011000
+#define STM32F407_USART2 0x40004400
+#define STM32F407_USART3 0x40004800
+#define STM32F407_USART6 0x40011400
+
#define FLASH_BASE_ADDRESS 0x8000000
#define FLASH_SIZE 0x100000
#define SRAM_BASE_ADDRESS 0x20000000
@@ -53,6 +60,7 @@ typedef struct STM32F407State {
STM32F4xxSyscfgState syscfg;
STM32F4xxExtiState exti;
+ STM32F4XXUsartState usart[STM_NUM_USARTS];
} STM32F407State;
3、在hw/arm/stm32f407_soc.c文件中添加如下代码片段4.在hw/char/Kconfig中添加
--- a/hw/arm/stm32f407_soc.c
+++ b/hw/arm/stm32f407_soc.c
@@ -32,6 +32,15 @@
#include "hw/arm/stm32f407_soc.h"
#include "sysemu/sysemu.h"
+static const uint32_t usart_addr[STM_NUM_USARTS] = {
+ STM32F407_USART1, STM32F407_USART2, STM32F407_USART3,
+ STM32F407_USART6
+};
+
+static const int usart_irq[STM_NUM_USARTS] = {
+ 37, 38, 39, 71
+};
+
static const int exti_irq[] =
{
6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40,
@@ -42,6 +51,7 @@ static void stm32f407_soc_initfn(Object *obj)
{
STM32F407State *s = STM32F407_SOC(obj);
+ int i;
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
TYPE_ARMV7M);
@@ -49,6 +59,11 @@ static void stm32f407_soc_initfn(Object *obj)
TYPE_STM32F4XX_SYSCFG);
sysbus_init_child_obj(obj, "exti", &s->exti, sizeof(s->exti),
TYPE_STM32F4XX_EXTI);
+
+ for (i = 0; i < STM_NUM_USARTS; i++) {
+ object_initialize(&s->usart[i], sizeof(s->usart[i]), TYPE_STM32F4XX_USART);
+ qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
+ }
}
static void stm32f407_soc_realize(DeviceState *dev_soc, Error **errp)
@@ -95,6 +110,19 @@ static void stm32f407_soc_realize(DeviceState *dev_soc, Error **errp)
for (i = 0; i < 16; i++) {
qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev, i));
}
+ /* USART controllers */
+ for (i = 0; i < STM_NUM_USARTS;