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)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/63219.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63219.shtml
英文地址,請注明出處:http://en.pswp.cn/web/63219.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

小程序自定義tab-bar,踩坑記錄

從官方下載代碼 https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 1、把custom-tab-bar 文件放置 pages同級 修改下 custom-tab-bar 下的 JS文件 Component({data: {selected: 0,color: "#7A7E83",selectedColor: "#3…

操作系統(14)請求分頁

前言 操作系統中的請求分頁&#xff0c;也稱為頁式虛擬存儲管理&#xff0c;是建立在基本分頁基礎上&#xff0c;為了支持虛擬存儲器功能而增加了請求調頁功能和頁面置換功能的一種內存管理技術。 一、基本概念 分頁&#xff1a;將進程的邏輯地址空間分成若干個大小相等的頁&am…

git企業開發的相關理論(一)

目錄 一.初識git 二.git的安裝 三.初始化/創建本地倉庫 四.配置用戶設置/配置本地倉庫 五.認識工作區、暫存區、版本庫 六.添加文件__場景一 七.查看 .git 文件/添加到本地倉庫后.git中發生的變化 1.執行git add后的變化 index文件&#xff08;暫存區&#xff09; log…

wxpython圖形用戶界面編程

wxpython圖形用戶界面編程 一、wxpython的基礎 1.1 wxpython的基礎 作為圖形用戶界面開發工具包 wxPython&#xff0c;主要提供了如下 GUI 內容&#xff1a; 窗口。控件。事件處理。布局管理。 1.2 wxpython的類層次機構 1.3 wxpython的安裝 Windows 和 macOS 平臺安裝&a…

水仙花數(流程圖,NS流程圖)

題目&#xff1a;打印出所有的100-999之間的"水仙花數"&#xff0c;并畫出流程圖和NS流程圖。所謂"水仙花數"是指一個三位數&#xff0c;其各位數字立方和等于該數本身。例如&#xff1a;153是一個"水仙花數"&#xff0c;因為1531的三次方&#…

不配置python環境,直接用PyCharm就可以?

有的伙伴可能遇到不安裝python環境只安裝pycharm也可以進行運行代碼。 所以自認為是不需要解釋器就可以運行&#xff1f; 這個是不現實的&#xff0c;有很多伙伴可能是安裝了Pycharm&#xff0c;但Pycharm看你電腦上沒有解釋器&#xff0c;所以在安裝的時候給你默認安裝在C盤…

網絡安全滲透測試概論

滲透測試&#xff0c;也稱為滲透攻擊測試是一種通過模擬惡意攻擊者的手段來評估計算機系統、網絡或應用程序安全性的方法。 目的 旨在主動發現系統中可能存在的安全漏洞、脆弱點以及潛在風險&#xff0c;以便在被真正的惡意攻擊者利用之前&#xff0c;及時進行修復和加固&…

爬蟲數據能用于商業嗎?

在當今數字化時代&#xff0c;數據已成為企業獲取競爭優勢的關鍵資源。網絡爬蟲作為一種數據收集工具&#xff0c;能夠從互聯網上抓取大量數據&#xff0c;這些數據在商業分析中扮演著重要角色。然而&#xff0c;使用爬蟲技術獲取的數據是否合法、能否用于商業分析&#xff0c;…

前端面試匯總(不定時更新)

目錄 HTML & CSS1. XML、HTML、XHTML 有什么區別&#xff1f;?2. XML和JSON的區別&#xff1f;3. 是否了解W3C的規范&#xff1f;?4. 什么是語義化標簽&#xff1f;??5. 行內元素和塊級元素的區別&#xff1f;?6. 行內元素和塊級元素的轉換&#xff1f;?7. 常用的塊級…

SpringCloud微服務實戰系列:03spring-cloud-gateway業務網關灰度發布

目錄 spring-cloud-gateway 和zuul spring webflux 和 spring mvc spring-cloud-gateway 的兩種模式 spring-cloud-gateway server 模式下配置說明 grayLb://system-server 灰度發布代碼實現 spring-cloud-gateway 和zuul zuul 是spring全家桶的第一代網關組件&#x…

QT3學習之進階理解信號和槽:如何自定義一個類信號,供其它類調用槽函數

下面是QWidget源碼&#xff0c;定義了兩個事件 /*!This event handler can be reimplemented in a subclass to receivewidget enter events.An event is sent to the widget when the mouse cursor enters thewidget.\sa leaveEvent(), mouseMoveEvent(), event() */void QWi…

GaLore和Q-GaLore:一種記憶高效的預訓練和微調策略,用于大型語言模型(LLMs)

GaLore和Q-GaLore&#xff1a;一種記憶高效的預訓練和微調策略&#xff0c;用于大型語言模型&#xff08;LLMs&#xff09; GaLore和Q-GaLore的設計背景、工作原理及其優勢 設計背景 隨著大型語言模型&#xff08;LLMs&#xff09;的發展&#xff0c;模型的規模和復雜性不斷…

【網絡云計算】2024第51周-每日【2024/12/17】小測-理論-解析

文章目錄 1. 計算機網絡有哪些分類2. 計算機網絡中協議與標準的區別3. 計算機網絡拓撲有哪些結構4. 常用的網絡設備有哪些&#xff0c;分屬于OSI的哪一層5. IEEE802局域網標準有哪些 【網絡云計算】2024第51周-每日【2024/12/17】小測-理論-解析 1. 計算機網絡有哪些分類 計算…

ActiveMQ 反序列化漏洞CVE-2015-5254復現

文章目錄 一、產生原因二、利用條件三、利用過程四、PoC&#xff08;概念驗證&#xff09;五、poc環境驗證使用find搜索vulhub已安裝目錄打開activeMQ組件查看配置文件端口啟動鏡像-文件配置好后對于Docker 鏡像下載問題及解決辦法設置好鏡像源地址&#xff0c;進行重啟docker查…

shardingsphere分庫分表跨庫訪問 添加分片規則

shardingsphere分庫分表跨庫訪問 添加分片規則 建立 JDBC 環境 創建表 t_order&#xff1a; CREATE TABLE t_order (tid bigint(20) NOT NULL,tname varchar(255) DEFAULT NULL,goods_id bigint(20) DEFAULT NULL,tstatus varchar(255) DEFAULT NULL,PRIMARY KEY (tid) ) E…

C++ 中,構造函數、拷貝構造函數和移動構造函數區別

在 C 中&#xff0c;構造函數、拷貝構造函數和移動構造函數是類中用于對象初始化的三種不同類型的構造函數。它們的功能和使用場景有所不同&#xff0c;下面詳細解釋它們之間的區別。 1. 構造函數 (Constructor) 定義&#xff1a; 構造函數是一個特殊的成員函數&#xff0c;用…

MYSQL執行一條update語句,期間發生了什么

客戶端先通過連接器建立連接&#xff0c;連接器自會判斷用戶身份&#xff1b; 因為這是一條 update 語句&#xff0c;所以不需要經過查詢緩存&#xff0c;但是表上有更新語句&#xff0c;是會把整個表的查詢緩存清空的&#xff0c;所以說查詢緩存很雞肋&#xff0c;在 MySQL 8…

vue3監聽橫向滾動條的位置;鼠標滾輪滑動控制滾動條滾動;監聽滾動條到頂端

1.橫向取值scrollLeft 豎向取值scrollTop 2.可以監聽到最左最右側 3.鼠標滾輪滑動控制滾動條滾動 效果 <template><div><div class"scrollable" ref"scrollableRef"><!-- 內容 --><div style"width: 2000px; height: 100…

深入理解MyBatis的Mapper層:讓數據訪問更高效

目錄 1. 什么是MyBatis的Mapper層&#xff1f; 1.1 典型的Mapper層結構 1.2 示例&#xff1a;一個簡單的用戶管理系統 2. 創建Mapper層 2.1 創建實體類 2.2 創建Mapper接口 2.3 創建Mapper XML文件&#xff08;可選&#xff09; 2.4 配置MyBatis的SQL映射 3. 使用Mapp…

WPF xaml 文件詳解

<div id"content_views" class"htmledit_views"><h2><a name"t0"></a>1.總述</h2> 創建好了WPF項目后&#xff0c;最重要的是對 App和MainWindow的理解&#xff0c;在一開始的時候&#xff0c;極容易就直接在Main…