qemu源码解析【03】qom实例

目录

  • qemu源码解析【03】qom实例
    • arm_sbcon_i2c实例

qemu源码解析【03】qom实例

arm_sbcon_i2c实例

  • 以hw/i2c/arm_sbcon_i2c.c代码为例,这个实例很简单,只用100行左右的代码,调用qemu系统接口实现了一个i2c硬件模拟
  • 先看include/hw/i2c/arm_sbcon_i2c.h头文件定义
#ifndef HW_I2C_ARM_SBCON_I2C_H
#define HW_I2C_ARM_SBCON_I2C_H

#include "hw/sysbus.h"
#include "hw/i2c/bitbang_i2c.h"
#include "qom/object.h"

// 定义类型名称,该名称会用type_register_static
// 注册到TypeInfo.name中
#define TYPE_ARM_SBCON_I2C "versatile_i2c"

typedef struct ArmSbconI2CState ArmSbconI2CState;
DECLARE_INSTANCE_CHECKER(ArmSbconI2CState, ARM_SBCON_I2C, TYPE_ARM_SBCON_I2C)

// 类型的私有数据结构
// 该数据结构的size会注册到TypeInfo.instance_size中
// 系统会根据这个size为我们分配内存
struct ArmSbconI2CState {
    /*< private >*/
    SysBusDevice parent_obj;
    /*< public >*/

    MemoryRegion iomem;
    bitbang_i2c_interface bitbang;
    int out;
    int in;
};

#endif /* HW_I2C_ARM_SBCON_I2C_H */
  • 分析一下上面的:DECLARE_INSTANCE_CHECKER(ArmSbconI2CState, ARM_SBCON_I2C, TYPE_ARM_SBCON_I2C)
    初步展开这个宏会变成:
static inline G_GNUC_UNUSED ArmSbconI2CState * \
ARM_SBCON_I2C(const void *obj) \
{ return OBJECT_CHECK(ArmSbconI2CState, obj, TYPE_ARM_SBCON_I2C); }
  • 再接着展开会变成:
static inline G_GNUC_UNUSED ArmSbconI2CState *ARM_SBCON_I2C(const void *obj) \
{
    return ((ArmSbconI2CState *)object_dynamic_cast_assert(OBJECT(obj), (TYPE_ARM_SBCON_I2C), \
    __FILE__, __LINE__, __func__));
}
  • object_dynamic_cast_assert()函数就不继续展开了,这个函数注释里面这样写道:perform type safe dynamic_casts to this object type,看起来就是一个指针类型的动态转换。所以这里定义了一个函数ARM_SBCON_I2C(),将给定的(void *)obj内存动态转换成(ArmSbconI2CState *)类型
  • 后面在arm_sbcon_i2c_init()函数中我们也可以看到,ArmSbconI2CState *s = ARM_SBCON_I2C(obj)这条语句正是使用了这个数据类型转换的功能
  • 再看hw/i2c/arm_sbcon_i2c.c具体实现,具体解析都写在注释中了
#include "qemu/osdep.h"
#include "hw/i2c/arm_sbcon_i2c.h"
#include "hw/registerfields.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"

// 声明该i2c硬件的寄存器
REG32(CONTROL_GET, 0)
REG32(CONTROL_SET, 0)
REG32(CONTROL_CLR, 4)

#define SCL BIT(0)
#define SDA BIT(1)

// 声明i2c read函数,注册到后面的arm_sbcon_i2c_ops结构体中
static uint64_t arm_sbcon_i2c_read(void *opaque, hwaddr offset,
                                   unsigned size)
{
    ArmSbconI2CState *s = opaque;

    // 解析寄存器参数
    switch (offset) {
    case A_CONTROL_SET:
        return (s->out & 1) | (s->in << 1);
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset 0x%x\n", __func__, (int)offset);
        return -1;
    }
}

// 声明i2c write函数,注册到后面的arm_sbcon_i2c_ops结构体中
static void arm_sbcon_i2c_write(void *opaque, hwaddr offset,
                                uint64_t value, unsigned size)
{
    ArmSbconI2CState *s = opaque;

    // 解析寄存器参数
    switch (offset) {
    case A_CONTROL_SET:
        s->out |= value & 3;
        break;
    case A_CONTROL_CLR:
        s->out &= ~value;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset 0x%x\n", __func__, (int)offset);
    }

    // 调用bitbang模拟I2C时序
    bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & SCL) != 0);
    s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & SDA) != 0);
}

// 定义了memory region上面绑定的操作函数,后面使用memory_region_init_io,在声明memory region的时候进行注册
static const MemoryRegionOps arm_sbcon_i2c_ops = {
    .read = arm_sbcon_i2c_read,
    .write = arm_sbcon_i2c_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void arm_sbcon_i2c_init(Object *obj)
{
    DeviceState *dev = DEVICE(obj);

    // 在头文件中用DECLARE_INSTANCE_CHECKER(ArmSbconI2CState, ARM_SBCON_I2C, TYPE_ARM_SBCON_I2C)
    // 已经声明了ARM_SBCON_I2C()函数
    ArmSbconI2CState *s = ARM_SBCON_I2C(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    I2CBus *bus;

    // qemu系统的i2c函数,创建一个i2c总线
    bus = i2c_init_bus(dev, "i2c");

    // i2c bitbang,软件层通过IO脚去模拟I2C的时序,从而实现I2C协议
    bitbang_i2c_init(&s->bitbang, bus);

    // 分配一块memory空间,用来做io操作
    // 其实就是模拟硬件的寄存器地址空间
    // 注意这里将ArmSbconI2CState *s指针作为参数传进去
    // 后面每次调用io操作的时候,都会作为void *opaque参数
    memory_region_init_io(&s->iomem, obj, &arm_sbcon_i2c_ops, s,
                          "arm_sbcon_i2c", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
}

static const TypeInfo arm_sbcon_i2c_info = {
    // 类型名称
    .name          = TYPE_ARM_SBCON_I2C,
    // 类型的父类型
    .parent        = TYPE_SYS_BUS_DEVICE,
    // 类型的数据size
    .instance_size = sizeof(ArmSbconI2CState),
    // 注册类型的初始化函数
    .instance_init = arm_sbcon_i2c_init,
};

static void arm_sbcon_i2c_register_types(void)
{
    // 调用系统接口注册类型
    type_register_static(&arm_sbcon_i2c_info);
}

type_init(arm_sbcon_i2c_register_types)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FireFox火狐浏览器企业策略禁止更新

一直在用火狐浏览器&#xff0c;但是经常提示更新&#xff0c;进入浏览器右上角就弹出提示&#xff0c;比较烦。多方寻找&#xff0c;一直没有找到合适的方案&#xff0c;毕竟官方没有给出禁用检查更新的选项&#xff0c;甚至about:config里都没有。 最终找到了通过企业策略控…

【Qt】按钮类控件:QPushButton、QRadioButton、QCheckBox、ToolButton

目录 QPushButton 例子&#xff1a; QRadioButton 例子&#xff1a; 按钮的常见信号函数 单选按钮分组 例子&#xff1a; QCheckButton 例子&#xff1a; QToolButton QWidget的常见属性及其功能对于它的派生类控件都是有效的(也就是Qt中的各种控件)&#xff0c;包括…

SpringBoot3 升级介绍

优质博文&#xff1a;IT-BLOG-CN 一、项目背景 截止2023.05.18&#xff0c;springboot发布了最新版本3.1.0。而在我们开发项目中&#xff0c;springboot一直使用的是1.5.8版本(相差6年的维护更新)。版本差距较大&#xff0c;很多新功能未能得到使用。例如近几年Loom的兴起&am…

运筹说 第130期 | 对策论引言

通过对对策论基础知识进行梳理和总结&#xff0c;小编绘制了《对策论思维导图》&#xff0c;如下图所示&#xff0c;对策论章节一共包含4个小节。 第1小节是对策论引言。介绍了对策论的基本概念&#xff0c;包含对策行为和对策论、对策现象的三要素、对策问题举例及对策的分类…

Windows 与 Linux 下 Ping IPv6 地址 | 常用网络命令

注&#xff1a;本文为网络命令相关文章合辑。 未整理去重。 一、IPv6 概述 IPv6 即 “Internet 协议版本 6”&#xff0c;因 IPv4 地址资源面临耗尽问题而被引入以替代 IPv4。IPv6 则提供了理论上多达 2 128 2^{128} 2128 个地址&#xff0c;有效解决地址不足困境。 IPv6 具…

密码学——密码学概述、分类、加密技术(山东省大数据职称考试)

大数据分析应用-初级 第一部分 基础知识 一、大数据法律法规、政策文件、相关标准 二、计算机基础知识 三、信息化基础知识 四、密码学 五、大数据安全 六、数据库系统 七、数据仓库. 第二部分 专业知识 一、大数据技术与应用 二、大数据分析模型 三、数据科学 密码学 大数据…

Android Studio、JDK、AGP、Gradle、kotlin-gradle-plugin 兼容性问题

文章目录 问题&#xff1a;解决办法&#xff1a;gradle与 java的版本兼容AGP与Gradle的版本兼容kotlin 与 jvm 的版本兼容KGP、Gradle、AGP兼容关系kotlin 与 java 的编译版本配置 问题&#xff1a; 你从githb上clone了一个项目&#xff0c;本地跑的时候&#xff0c;各种报错。…

ChatGPT搜索全新升级,向全体用户开放,近屿智能助力AI行业发展

12月17日&#xff0c;OpenAI在第八天直播中正式宣布ChatGPT搜索功能全面升级&#xff0c;并即日起对所有ChatGPT用户开放。此次更新不仅带来了显著的性能提升&#xff0c;还引入了多项突破性功能&#xff0c;如更快的搜索速度、全新的地图体验以及YouTube视频嵌入&#xff0c;为…

VSCode编辑+GCC for ARM交叉编译工具链+CMake构建+OpenOCD调试(基于STM32的标准库/HAL库)

本文以【STM32F103ZET6】单片机作为示例来进行演示&#xff0c;标准库/HAL库的工程是通用的&#xff0c;修改CMakeLists.txt里面的源文件和头文件引用部分即可。 更多细节请参考【VSCode编辑GCC for ARM交叉编译工具链Makefile构建OpenOCD调试&#xff08;基于STM32的标准库&am…

ResNet网络:深度学习中的革命性架构

目录 ​编辑 引言 ResNet网络的特点 1. 残差块&#xff08;Residual Block&#xff09; 2. 恒等映射&#xff08;Identity Mapping&#xff09; 3. 深层网络训练 4. Batch Normalization 5. 全局平均池化 6. 灵活的结构 ResNet的应用案例 ResNet的研究进展 实战案例…

Axure9设置画布固定

在使用AxureRP9设计原型时&#xff0c;如果遇到画布在拖动时变得难以控制&#xff0c;可以尝试在Windows系统中通过‘文件’>‘首选项’&#xff0c;或在Mac系统中通过‘AxureRP9’>‘偏好设置’进行设置&#xff0c;以稳定画布的行为。 现象 页面底层的画布&#xff0…

景联文科技入选中国信通院发布的“人工智能数据标注产业图谱”

近日&#xff0c;由中国信息通信研究院、中国人工智能产业发展联盟牵头&#xff0c;联合中国电信集团、沈阳市数据局、保定高新区等70多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业&#xff0c;入选图谱中技术服务板块。…

ESlint代码规范,手动与自动修复

规范说明 规则参考 - ESLint - 插件化的 JavaScript 代码检查工具 规范说明 ​ ​ 可看到是main.js文件报错分别是第三行第30个字符&#xff0c;以及第七行第一个字符 后面则是规范说明&#xff0c;可以根据说明查找相应的规范 一.手动修正 ctrl f 可以搜索 二.自动修正 …

一条线上的点

给你一个数组 points &#xff0c;其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。 提示&#xff1a; 1 < points.length < 300points[i].length 2-104 < xi, yi < 104points 中的所有点 互不相同 解析&#xff1a;使用斜…

wxpython图形用户界面编程

wxpython图形用户界面编程 一、wxpython的基础 1.1 wxpython的基础 作为图形用户界面开发工具包 wxPython&#xff0c;主要提供了如下 GUI 内容&#xff1a; 窗口。控件。事件处理。布局管理。 1.2 wxpython的类层次机构 1.3 wxpython的安装 Windows 和 macOS 平台安装&a…

【优选算法篇】位运算小课堂:从入门到精通的奇妙之旅(上篇)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

pytest入门九:feature

fixture是pytest特有的功能&#xff0c;用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识&#xff0c;定义在函数前面。在你编写测试函数的时候&#xff0c;你可以将此函数名称做为传入参数&#xff0c;pytest将会以依赖注入方式&#xff0c;将该函数…

Day9 神经网络的偏导数基础

多变量函数与神经网络 在神经网络中&#xff0c;我们经常遇到多变量函数。这些函数通常描述了网络的输入、权重、偏置与输出之间的关系。例如&#xff0c;一个简单的神经元输出可以表示为&#xff1a; z f ( w 1 x 1 w 2 x 2 … w n x n b ) z f(w_1x_1 w_2x_2 \ldots…

sg-exam:Star 2.2k,一套完善的在线教育平台,支持在线考试、在线学习,教育项目用它就没有错~~

​嗨&#xff0c;大家好&#xff0c;我是小华同学&#xff0c;关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 sg-exam是一个基于Java语言的在线考试系统&#xff0c;它集成了试卷管理、试题管理、考试安排、在线作答、自动阅卷等功能。该项目旨在帮助教育机构…

ArkTS中string和String/number和Number类型大小写的区别

ArkTS和TypeScript类似&#xff0c;string 和 String&#xff0c;number 和 Number 之间有一些重要的区别&#xff1a; 基本类型与对象类型 基本类型 (string, number)&#xff1a; string 和 number 是基本数据类型&#xff0c;用于表示原始值。例如&#xff1a;let str: str…