Qemu-STM32(十七):STM32F103加入AFIO控制器

概述

本文主要描述了在Qemu平台中,如何添加STM32F103的AFIO控制器模拟代码,AFIO是属于GPIO引脚复用配置的功能。

参考资料

STM32F1XX TRM手册,手册编号:RM0008

添加步骤

1、在hw/arm/Kconfig文件中添加STM32F1XX_AFIO,如下所示:

+号部分为新增加内容

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 2a66ff5f..c0edade0 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -419,6 +419,7 @@ config STM32F103_SOCselect STM32F1XX_FLASHselect STM32F1XX_USARTselect STM32F1XX_GPIO
+    select STM32F1XX_AFIO

2、在include/hw/arm/stm32f103_soc.h文件中添加

+号部分为新增加内容

diff --git a/include/hw/arm/stm32f103_soc.h b/include/hw/arm/stm32f103_soc.h
index c4c9bc52..ee015939 100644
--- a/include/hw/arm/stm32f103_soc.h
+++ b/include/hw/arm/stm32f103_soc.h
@@ -29,6 +29,7 @@#include "hw/misc/stm32f1xx_flash.h"#include "hw/char/stm32f1xx_usart.h"#include "hw/gpio/stm32f1xx_gpio.h"
+#include "hw/misc/stm32f1xx_afio.h"#define RCC_BASE_ADDR    0x40021000#define EXTI_BASE_ADDR   0x40010400
@@ -40,14 +41,16 @@#define UART2_BASE_ADDR  0x40004400#define UART3_BASE_ADDR  0x40004800+#define STM_AFIO_BASE   0x40010000#define TYPE_STM32F103_SOC "stm32f103-soc"#define STM32F103_SOC(obj) \
@@ -68,6 +71,7 @@ typedef struct STM32F103State {STM32F1XXFlashState flash;STM32F1XXUsartState usart[STM_NUM_USARTS];STM32F1XXGPIOState gpio[STM_NUM_GPIOS];
+    STM32F1XXAFIOState afio;} STM32F103State;

3、在hw/arm/stm32f103_soc.c文件中添加如下代码片段

+号部分为新增加内容

diff --git a/hw/arm/stm32f103_soc.c b/hw/arm/stm32f103_soc.c
index d673eace..f9f0c120 100644
--- a/hw/arm/stm32f103_soc.c
+++ b/hw/arm/stm32f103_soc.c
@@ -72,6 +72,9 @@ static void stm32f103_soc_initfn(Object *obj)sysbus_init_child_obj(obj, "flash", &s->flash, sizeof(s->flash),TYPE_STM32F1XX_FLASH);+    sysbus_init_child_obj(obj, "afio", &s->afio, sizeof(s->afio),
+                        TYPE_STM32F1XX_AFIO);
+for (i = 0; i < STM_NUM_USARTS; i++) {object_initialize(&s->usart[i], sizeof(s->usart[i]), TYPE_STM32F1XX_USART);qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
@@ -167,6 +170,15 @@ static void stm32f103_soc_realize(DeviceState *dev_soc, Error **errp)busdev = SYS_BUS_DEVICE(dev);sysbus_mmio_map(busdev, 0, gpio_addr[i]);}
+    /* AFIO Controller */
+    dev = DEVICE(&s->afio);
+    object_property_set_bool(OBJECT(&s->afio), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, STM_AFIO_MAPR2);}static Property stm32f103_soc_properties[] = {

4.在hw/misc/Kconfig中添加

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index af2c8f8b..d140a18a 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -113,6 +113,9 @@ config STM32F1XX_PWRconfig STM32F1XX_FLASHbool+config STM32F1XX_AFIO
+    bool
+config STM32F2XX_SYSCFGbool

5.在hw/misc/Makefile.objs中添加

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ec738e27..743d2b83 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -69,6 +69,7 @@ common-obj-$(CONFIG_STM32F1XX_RCC) += stm32f1xx_rcc.ocommon-obj-$(CONFIG_STM32F1XX_EXTI) += stm32f1xx_exti.ocommon-obj-$(CONFIG_STM32F1XX_PWR) += stm32f1xx_pwr.ocommon-obj-$(CONFIG_STM32F1XX_FLASH) += stm32f1xx_flash.o
+common-obj-$(CONFIG_STM32F1XX_AFIO) += stm32f1xx_afio.oobj-$(CONFIG_STM32F4XX_RCC) += stm32f4xx_rcc.oobj-$(CONFIG_STM32F4XX_PWR) += stm32f4xx_pwr.oobj-$(CONFIG_STM32F4XX_FLASH) += stm32f4xx_flash.o

6.在hw/misc/创建新文件hw/misc/stm32f1xx_afio.c

+/*
+ * Copyright (c) 2025 liang yan <yanl1229@163.com>
+ *
+ * STM32F1XX AFIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/misc/stm32f1xx_afio.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+
+#ifndef STM_AFIO_ERR_DEBUG
+#define STM_AFIO_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_AFIO_ERR_DEBUG >= lvl) { \
+        qemu_log("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f1xx_afio_reset(DeviceState *dev)
+{
+    STM32F1XXAFIOState *s = STM32F1XX_AFIO(dev);
+    s->afio_evcr     = 0x00000000;
+    s->afio_mapr     = 0x00000000;
+    s->afio_exticr1  = 0x00000000;
+    s->afio_exticr2  = 0x00000000;
+    s->afio_exticr3  = 0x00000000;
+    s->afio_exticr4  = 0x00000000;
+    s->afio_mapr2    = 0x00000000;
+}
+
+static uint64_t stm32f1xx_afio_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    STM32F1XXAFIOState *s = opaque;
+    uint64_t retvalue = 0;
+
+    DB_PRINT("Address: 0x%" HWADDR_PRIx "\n", addr);
+    switch(addr) {
+    case STM_AFIO_EVCR:
+        retvalue = s->afio_evcr;
+        break;
+    case STM_AFIO_MAPR:
+        retvalue = s->afio_mapr;
+        break;
+    case STM_AFIO_EXTICR1:
+        retvalue = s->afio_exticr1;
+        break;
+    case STM_AFIO_EXTICR2:
+        retvalue = s->afio_exticr2;
+        break;
+    case STM_AFIO_EXTICR3:
+        retvalue = s->afio_exticr3;
+        break;
+    case STM_AFIO_EXTICR4:
+        retvalue = s->afio_exticr4;
+        break;
+    case STM_AFIO_MAPR2:
+        retvalue = s->afio_mapr2;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
+            __func__, addr);
+        retvalue = 0;
+        break;
+    }
+    return retvalue;
+}
+
+static void stm32f1xx_afio_write(void *opaque, hwaddr addr,
+                                uint64_t val64, unsigned int size)
+{
+    STM32F1XXAFIOState *s = opaque;
+    uint32_t value = val64;
+
+    DB_PRINT("Address: 0x%" HWADDR_PRIx ", Value: 0x%x\n", addr, value);
+    switch(addr) {
+    case STM_AFIO_EVCR:
+        s->afio_evcr = value;
+        break;
+    case STM_AFIO_MAPR:
+        s->afio_mapr = value;
+        break;
+    case STM_AFIO_EXTICR1:
+        s->afio_exticr1 = value;
+        break;
+    case STM_AFIO_EXTICR2:
+        s->afio_exticr2 = value;
+        break;
+    case STM_AFIO_EXTICR3:
+        s->afio_exticr3 = value;
+        break;
+    case STM_AFIO_EXTICR4:
+        s->afio_exticr4 = value;
+        break;
+    case STM_AFIO_MAPR2:
+        s->afio_mapr2 = value;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
+            __func__, addr);
+    }
+}
+
+static const MemoryRegionOps stm32f1xx_afio_ops = {
+    .read = stm32f1xx_afio_read,
+    .write = stm32f1xx_afio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_stm32f1xx_afio = {
+    .name = TYPE_STM32F1XX_AFIO,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(afio_evcr, STM32F1XXAFIOState),
+        VMSTATE_UINT32(afio_mapr, STM32F1XXAFIOState),
+        VMSTATE_UINT32(afio_exticr1, STM32F1XXAFIOState),
+        VMSTATE_UINT32(afio_exticr2, STM32F1XXAFIOState),
+        VMSTATE_UINT32(afio_exticr3, STM32F1XXAFIOState),
+        VMSTATE_UINT32(afio_exticr4, STM32F1XXAFIOState),
+        VMSTATE_UINT32(afio_mapr2, STM32F1XXAFIOState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void stm32f1xx_afio_init(Object *obj)
+{
+    STM32F1XXAFIOState *s = STM32F1XX_AFIO(obj);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f1xx_afio_ops, s,
+                          TYPE_STM32F1XX_AFIO, 0x400);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+}
+
+static void stm32f1xx_afio_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f1xx_afio_reset;
+    dc->vmsd = &vmstate_stm32f1xx_afio;
+}
+
+static const TypeInfo stm32f1xx_afio_info = {
+    .name          = TYPE_STM32F1XX_AFIO,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F1XXAFIOState),
+    .instance_init = stm32f1xx_afio_init,
+    .class_init    = stm32f1xx_afio_class_init,
+};
+
+static void stm32f1xx_afio_register_types(void)
+{
+    type_register_static(&stm32f1xx_afio_info);
+}
+
+type_init(stm32f1xx_afio_register_types)

7.在include/hw/misc/创建stm32f1xx_afio.h文件

+/*
+ * Copyright (c) 2025- liang yan <yanl1229@163.com>
+ *
+ * STM32F1XX AFIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#ifndef STM32F1XX_AFIO_H
+#define STM32F1XX_AFIO_H
+
+#include "hw/sysbus.h"
+
+#define STM_AFIO_EVCR               0x00
+#define STM_AFIO_MAPR               0x04
+#define STM_AFIO_EXTICR1            0x08
+#define STM_AFIO_EXTICR2            0x0c
+#define STM_AFIO_EXTICR3            0x10
+#define STM_AFIO_EXTICR4            0x14
+#define STM_AFIO_MAPR2              0x1c
+
+#define TYPE_STM32F1XX_AFIO "stm32f1xx-afio"
+#define STM32F1XX_AFIO(obj) \
+    OBJECT_CHECK(STM32F1XXAFIOState, (obj), TYPE_STM32F1XX_AFIO)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion mmio;
+
+    uint32_t afio_evcr;
+    uint32_t afio_mapr;
+    uint32_t afio_exticr1;
+    uint32_t afio_exticr2;
+    uint32_t afio_exticr3;
+    uint32_t afio_exticr4;
+    uint32_t afio_mapr2;
+
+
+    qemu_irq irq;
+
+} STM32F1XXAFIOState;
+
+#endif

总结

本文描述了如何在qemu中添加stm32f103平台上AFIO控制器实现步骤。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QuecPython+audio:实现音频的录制与播放

概述 QuecPython 作为专为物联网设计的开发框架&#xff0c;通过高度封装的 Python 接口为嵌入式设备提供了完整的音频处理能力。本文主要介绍如何利用 QuecPython 快速实现音频功能的开发。 核心优势 极简开发&#xff1a;3行代码完成基础音频录制与播放。快速上手&#xf…

企业架构之旅(3):TOGAF ADM架构愿景的核心价值

一、引言&#xff1a;为什么架构愿景是企业架构的「导航图」 在企业数字化转型的浪潮中&#xff0c;TOGAF ADM&#xff08;架构开发方法&#xff09;作为公认的企业架构「方法论圣经」&#xff0c;其首个关键阶段 —— 架构愿景&#xff08;Architecture Vision&#xff09;&a…

C++:Lambda表达式

C&#xff1a;Lambda表达式 C中lambda的基本语法1. 捕获列表&#xff08;Capture List&#xff09;2. 示例代码示例 1&#xff1a;简单的lambda示例 2&#xff1a;捕获变量示例 3&#xff1a;按引用捕获示例 4&#xff1a;捕获所有变量示例 5&#xff1a;作为函数参数 3. lambd…

被关在idea小黑屏里写spark程序

一、先在idea中添加Scala插件 二、使用Maven创建新项目 1.启动idea,选择新建项目。之后的设置如下&#xff1a; 2.将Scala添加到全局库中&#xff08;注意&#xff1a;Scala的版本不宜太高&#xff0c;最好是2-12.否则后面会报下面这个错误 E:\tool接口\SparkCore_01\src\mai…

自动化立库/AGV物流仿真详细步骤

以下是一种可以在预算和周期内实现自动化立库及AGV 方案仿真分析的方法&#xff1a; 一、工具选择 软件工具FlexSim&#xff1a;这是一款流行的离散事件仿真软件。它具有直观的图形用户界面&#xff0c;通过简单的拖拽操作就可以构建自动化立库和 AGV 的模型。其内置的丰富的…

使用springboot+easyexcel实现导出excel并合并指定单元格

1&#xff1a;准备一个单元格合并策略类代码&#xff1a; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.metadata.holder.Writ…

Python三大Web框架对比:Django、Flask、Tornado的异步实现方式详解

目录 引言 一、框架基础概览 1.1 Django 1.2 Flask 1.3 Tornado 二、异步编程基础 2.1 同步 vs 异步 2.2 Python异步演进 三、框架异步实现对比 3.1 Django的异步进化 3.2 Flask的异步扩展 3.3 Tornado的异步范式 四、异步实现差异对比 4.1 实现机制对比 4.2 性…

深入理解Spring AI框架的核心概念

深入理解Spring AI框架的核心概念 前言 在当今人工智能飞速发展的时代&#xff0c;将AI技术集成到应用程序中已成为众多开发者关注的焦点。Spring AI框架为Java开发者提供了便捷的途径来实现这一目标。理解其核心概念对于充分发挥框架的潜力至关重要。本文将详细探讨Spring A…

LabVIEW基于VI Server的控件引用操作

本 VI 通过展示控件引用&#xff08;Control References&#xff09;的使用&#xff0c;借助 VI Server 实现对前面板对象的编程操作。 ​ 详细说明 隐式属性节点&#xff08;Implicitly Linked Property Node&#xff09;&#xff1a;通过右键单击控件&#xff08;或其控件终…

AI 边缘计算网关十大品牌

引言 在物联网与人工智能技术飞速发展的当下&#xff0c;数据量呈爆发式增长&#xff0c;对数据处理的实时性、准确性和安全性要求不断提高。AI边缘计算网关应运而生&#xff0c;它融合了人工智能、边缘计算与物联网技术&#xff0c;在靠近数据源或物理设备的网络边缘侧&#…

基于深度学习的视频目标跟踪算法研究

标题:基于深度学习的视频目标跟踪算法研究 内容:1.摘要 随着视频数据的爆炸式增长&#xff0c;视频目标跟踪在智能监控、自动驾驶、人机交互等领域有着广泛的应用需求。本文的目的是研究基于深度学习的视频目标跟踪算法&#xff0c;以提高跟踪的准确性和实时性。方法上&#x…

C++代码随想录刷题知识分享-----面试题链表相交

一、题目要求 题目&#xff1a;给定两条单链表 headA、headB&#xff0c;找出它们相交的起始节点&#xff08;节点对象相同而非数值相等&#xff09;。若无交点返回 null。 限制&#xff1a;链表无环&#xff1b;函数返回后链表结构不能被破坏。 图示两个链表在节点 c1 开始相…

修改输入框选择框颜色

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 有时候需要改写element原来输入框/选择框的颜色 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 输入框的话需要hover时边框颜色修改&#xff0c;选择值的时候边框颜色修改以及选…

8.学习笔记-Maven进阶(P82-P89)

&#xff08;一&#xff09;Maven-08-配置文件加载属性 通过maven可以做版本的集中管理&#xff0c;所以能不能通过maven进行配置文件&#xff08;jdbc.properties&#xff09;的集中管理。 &#xff08;1&#xff09;resource-》jdbc.properties 可以识别$符号 因为只能…

基于Springboot+Mysql的汉服推广网站(含LW+PPT+源码+系统演示视频+安装说明)

系统功能 管理员功能&#xff1a;首页、个人中心、汉服知识管理、服装展示管理、服装类别管理、用户相册管理、论坛交流、系统管理、订单管理&#xff1b;用户功能&#xff1a;首页、个人中心、用户相册管理、论坛交流、我的收藏管理、订单管理。 作者&#xff1a;计算机搬砖家…

Missashe考研日记-day30

Missashe考研日记-day30 0 写在前面 日记也是写到第30篇了哈哈&#xff0c;满月了&#xff0c;虽然过了不止30天中间有断更&#xff0c;但还是表扬一下自己坚持下来了。&#xff1a;&#xff09; 1 专业课408 学习时间&#xff1a;2h30min学习内容&#xff1a; 今天有其他事…

HHsuite同源序列搜索数据库构建

HHsuite 可用的数据库格式简介 HHsuite 是用于蛋白质序列比对和同源性检测的工具套件,它使用特定的数据库格式以实现高效的数据存储和快速的检索。HHsuite 常用的数据库格式主要基于 FFINDEX(Flat-File Index),这是一种简单而高效的文件索引系统,它将数据文件(如蛋白质序…

基于HTML CANVAS和EXCEL的xlsx文件展示工具websheet

什么是WEBSHEET websheet基于HTML5的CANVAS和JAVASCRIPT开发的纯前端xlsx文件展示控件&#xff0c;该控件着重的页面展示&#xff0c;主要完成了文件导入、导出、文本展示、格式化文本、合并单元格、边框、底色、设置行列宽度高度&#xff0c;行列隐藏、视图锁定、基础表格、撤…

Android Studio for Platform(ASFP)真机调试

连接设备 由于ubuntu连接adb设备每次都需要配置usb权限&#xff0c;很麻烦。并且每次换设备还要重新配置&#xff0c;我多数设备都是用wifi的adb方式连接。 开发板显示 连接显示器配合usb鼠标或者遥控器操作&#xff08;因为开发板默认开启了adb&#xff0c;我这里是使用有线…

基于springboot+vue的健康健身追踪系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.3.9 系统展示 用户信息管理 健…