OpenHarmony平臺驅動開發(十),MMC

OpenHarmony平臺驅動開發(十)


MMC

概述

功能簡介

MMC(MultiMedia Card)即多媒體卡,是一種用于固態非易失性存儲的小體積大容量的快閃存儲卡。

MMC后續泛指一個接口協定(一種卡式),能符合這種接口的內存器都可稱作MMC儲存體。主要包括幾個部分:MMC控制器、MMC總線、存儲卡(包括MMC卡、SD卡、SDIO卡、TF卡)。

MMC、SD、SDIO總線,其總線規范類似,都是從MMC總線規范演化而來的。MMC強調的是多媒體存儲;SD強調的是安全和數據保護;SDIO是從SD演化出來的,強調的是接口,不再關注另一端的具體形態(可以是WIFI設備、Bluetooth設備、GPS等等)。

基本概念

  • SD卡(Secure Digital Memory Card)

    SD卡即安全數碼卡。它是在MMC的基礎上發展而來,SD卡強調數據的安全,可以設定存儲內容的使用權限,防止數據被他人復制。在數據傳輸和物理規范上,SD卡(24mm*32mm*2.1mm,比MMC卡更厚一點),向前兼容了MMC卡。所有支持SD卡的設備也支持MMC卡。

  • SDIO(Secure Digital Input and Output)

    即安全數字輸入輸出接口。SDIO是在SD規范的標準上定義的一種外設接口,它相較于SD規范增加了低速標準,可以用最小的硬件開銷支持低速I/O。SDIO接口兼容以前的SD內存卡,也可以連接SDIO接口的設備。

運作機制

在HDF框架中,MMC的接口適配模式采用獨立服務模式(如圖1所示)。在這種模式下,每一個設備對象會獨立發布一個設備服務來處理外部訪問,設備管理器收到API的訪問請求之后,通過提取該請求的參數,達到調用實際設備對象的相應內部方法的目的。獨立服務模式可以直接借助HDFDeviceManager的服務管理能力,但需要為每個設備單獨配置設備節點,增加內存占用。

獨立服務模式下,核心層不會統一發布一個服務供上層使用,因此這種模式下驅動要為每個控制器發布一個服務,具體表現為:

  • 驅動適配者需要實現HdfDriverEntry的Bind鉤子函數以綁定服務。

  • device_info.hcs文件中deviceNode的policy字段為1或2,不能為0。

MMC模塊各分層作用:

  • 接口層提供打開MMC設備、檢查MMC控制器是否存在設備、關閉MMC設備的接口。

  • 核心層主要提供MMC控制器、移除和管理的能力,還有公共控制器業務。通過鉤子函數與適配層交互。

  • 適配層主要是將鉤子函數的功能實例化,實現具體的功能。

圖 1 MMC獨立服務模式結構圖

MMC獨立服務模式結構圖

開發指導

場景介紹

MMC用于多媒體文件的存儲,當驅動開發者需要將MMC設備適配到OpenHarmony時,需要進行MMC驅動適配。下文將介紹如何進行MMC驅動適配。

接口說明

為了保證上層在調用MMC接口時能夠正確的操作MMC控制器,核心層在//drivers/hdf_core/framework/model/storage/include/mmc/mmc_corex.h中定義了以下鉤子函數,驅動適配者需要在適配層實現這些函數的具體功能,并與鉤子函數掛接,從而完成適配層與核心層的交互。

MmcCntlrOps定義:

struct MmcCntlrOps {int32_t (*request)(struct MmcCntlr *cntlr, struct MmcCmd *cmd);int32_t (*setClock)(struct MmcCntlr *cntlr, uint32_t clock);int32_t (*setPowerMode)(struct MmcCntlr *cntlr, enum MmcPowerMode mode);int32_t (*setBusWidth)(struct MmcCntlr *cntlr, enum MmcBusWidth width);int32_t (*setBusTiming)(struct MmcCntlr *cntlr, enum MmcBusTiming timing);int32_t (*setSdioIrq)(struct MmcCntlr *cntlr, bool enable);int32_t (*hardwareReset)(struct MmcCntlr *cntlr);int32_t (*systemInit)(struct MmcCntlr *cntlr);int32_t (*setEnhanceStrobe)(struct MmcCntlr *cntlr, bool enable);int32_t (*switchVoltage)(struct MmcCntlr *cntlr, enum MmcVolt volt);bool (*devReadOnly)(struct MmcCntlr *cntlr);bool (*devPlugged)(struct MmcCntlr *cntlr);bool (*devBusy)(struct MmcCntlr *cntlr);int32_t (*tune)(struct MmcCntlr *cntlr, uint32_t cmdCode);int32_t (*rescanSdioDev)(struct MmcCntlr *cntlr);
};

表 1 MmcCntlrOps結構體成員的鉤子函數功能說明

成員函數入參返回值功能
doRequestcntlr:結構體指針,核心層MMC控制器
cmd:結構體指針,傳入命令值
HDF_STATUS相關狀態request相應處理
setClockcntlr:結構體指針,核心層MMC控制器
clock:uint32_t類型,時鐘傳入值
HDF_STATUS相關狀態設置時鐘頻率
setPowerModecntlr:結構體指針,核心層MMC控制器
mode:枚舉值(見MmcPowerMode定義),功耗模式
HDF_STATUS相關狀態設置功耗模式
setBusWidthcntlr:核心層結構體指針,核心層MMMC控制器
width:枚舉類型(見MmcBusWidth定義),總線帶寬
HDF_STATUS相關狀態設置總線帶寬
setBusTimingcntlr:結構體指針,核心層MMC控制器
timing:枚舉類型(見MmcBusTiming定義),總線時序
HDF_STATUS相關狀態設置總線時序
setSdioIrqcntlr:結構體指針,核心層MMC控制器
enable:布爾值,控制中斷
HDF_STATUS相關狀態使能/去使能SDIO中斷
hardwareResetcntlr:結構體指針,核心層MMC控制器HDF_STATUS相關狀態復位硬件
systemInitcntlr:結構體指針,核心層MMC控制器HDF_STATUS相關狀態系統初始化
setEnhanceStrobecntlr:結構體指針,核心層MMC控制器
enable:布爾值,設置功能
HDF_STATUS相關狀態設置增強選通
switchVoltagecntlr:結構體指針,核心層MMC控制器
volt:枚舉值,電壓值(3.3,1.8,1.2V)
HDF_STATUS相關狀態設置電壓值
devReadOnlycntlr:結構體指針,核心層MMC控制器布爾值檢驗設備是否只讀
cardPluggedcntlr:結構體指針,核心層MMC控制器布爾值檢驗設備是否拔出
devBusycntlr:結構體指針,核心層MMC控制器布爾值檢驗設備是否忙碌
tunecntlr:結構體指針,核心層MMC控制器
cmdCode:uint32_t類型,命令代碼
HDF_STATUS相關狀態調諧
rescanSdioDevcntlr:結構體指針,核心層MMC控制器HDF_STATUS相關狀態掃描并添加SDIO設備

開發步驟

MMC模塊適配包含以下四個步驟:

  • 實例化驅動入口

  • 配置屬性文件

  • 實例化MMC控制器對象

  • 驅動調試

開發實例

下方將基于Hi3516DV300開發板以//device/soc/hisilicon/common/platform/mmc/himci_v200/himci.c驅動為示例,展示需要驅動適配者提供哪些內容來完整實現設備功能。

  1. 實例化驅動入口

    驅動入口必須為HdfDriverEntry(在hdf_device_desc.h中定義)類型的全局變量,且moduleName要和device_info.hcs中保持一致。HDF框架會將所有加載的驅動的HdfDriverEntry對象首地址匯總,形成一個類似數組的段地址空間,方便上層調用。

    一般在加載驅動時HDF會先調用Bind函數,再調用Init函數加載該驅動。當Init調用異常時,HDF框架會調用Release釋放驅動資源并退出。

    MMC驅動入口開發參考:

    struct HdfDriverEntry g_mmcDriverEntry = {.moduleVersion = 1,.Bind = HimciMmcBind,                 // 見Bind參考.Init = HimciMmcInit,                 // 見Init參考.Release = HimciMmcRelease,           // 見Release參考.moduleName = "hi3516_mmc_driver",    // 【必要且與HCS文件中里面的moduleName匹配】
    };
    HDF_INIT(g_mmcDriverEntry);               // 調用HDF_INIT將驅動入口注冊到HDF框架中
    
  2. 配置屬性文件

    完成驅動入口注冊之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息與驅動入口注冊相關。本例以三個MMC控制器為例,如有多個器件信息,則需要在device_info.hcs文件增加對應的deviceNode信息,以及在mmc_config.hcs文件中增加對應的器件屬性。器件屬性值與核心層MmcCntlr成員的默認值或限制范圍有密切關系,需要在mmc_config.hcs中配置器件屬性。

    獨立服務模式的特點是device_info.hcs文件中設備節點代表著一個設備對象,如果存在多個設備對象,則按需添加,注意服務名與驅動私有數據匹配的關鍵字名稱必須唯一。其中各項參數如表2所示:

    表 2 device_info.hcs節點參數說明

    成員名
    policy驅動服務發布的策略,MMC控制器具體配置為2,表示驅動對內核態和用戶態都發布服務
    priority驅動啟動優先級(0-200),值越大優先級越低。MMC控制器控制器具體配置為10
    permission驅動創建設備節點權限,MMC控制器控制器具體配置為0664
    moduleName驅動名稱,MMC控制器控制器固定為hi3516_mmc_driver
    serviceName驅動對外發布服務的名稱,MMC控制器控制器服務名設置為HDF_PLATFORM_MMC_X,X代表MMC控制器號
    deviceMatchAttr驅動私有數據匹配的關鍵字,MMC控制器控制器設置為hi3516_mmc_X,X代表控制器類型名
    • device_info.hcs 配置參考:

      在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。

      root {device_info {match_attr = "hdf_manager";platform :: host {hostName = "platform_host";priority = 50;device_mmc:: device {device0 :: deviceNode {                     // 驅動的DeviceNode節點policy = 2;                             // policy字段是驅動服務發布的策略,如果需要面向用戶態,則為2priority = 10;                          // 驅動啟動優先級permission = 0644;                      // 驅動創建設備節點權限moduleName = "hi3516_mmc_driver";       // 【必要】用于指定驅動名稱,需要與驅動Entry中的moduleName一致。serviceName = "HDF_PLATFORM_MMC_0";     // 【必要】驅動對外發布服務的名稱,必須唯一。deviceMatchAttr = "hi3516_mmc_emmc";    // 【必要】用于配置控制器私有數據,要與mmc_config.hcs中對應控制器保持一致。emmc類型。}device1 :: deviceNode {policy = 1;priority = 20;permission = 0644;moduleName = "hi3516_mmc_driver";serviceName = "HDF_PLATFORM_MMC_1";deviceMatchAttr = "hi3516_mmc_sd";      // SD類型}device2 :: deviceNode {policy = 1;priority = 30;permission = 0644;moduleName = "hi3516_mmc_driver";serviceName = "HDF_PLATFORM_MMC_2";deviceMatchAttr = "hi3516_mmc_sdio";    // SDIO類型}......}}}
      }
      
    • mmc_config.hcs配置參考:

      在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/mmc/mmc_config.hcs文件配置器件屬性,其中配置參數如下:

      root {platform {mmc_config {template mmc_controller {                     // 配置模板,如果下面節點使用時繼承該模板,則節點中未聲明的字段會使用該模板中的默認值。match_attr = "";voltDef = 0;                              // MMC默認電壓,0代表3.3V,1代表1.8V,2代表1.2VfreqMin = 50000;                          // 【必要】最小頻率值freqMax = 100000000;                      // 【必要】最大頻率值freqDef = 400000;                         // 【必要】默認頻率值maxBlkNum = 2048;                         // 【必要】最大的block號maxBlkSize = 512;                         // 【必要】最大block大小ocrDef = 0x300000;                        // 【必要】工作電壓設置相關caps2 = 0;                                // 【必要】屬性寄存器相關,見mmc_caps.h中MmcCaps2定義。regSize = 0x118;                          // 【必要】寄存器位寬hostId = 0;                               // 【必要】主機號regBasePhy = 0x10020000;                  // 【必要】寄存器物理基地址irqNum = 63;                              // 【必要】中斷號devType = 2;                              // 【必要】模式選擇:EMMC、SD、SDIO、COMBOcaps = 0x0001e045;                        // 【必要】屬性寄存器相關,見mmc_caps.h中MmcCaps定義。}controller_0x10100000 :: mmc_controller {match_attr = "hi3516_mmc_emmc";           // 【必要】需要和device_info.hcs中的deviceMatchAttr值一致hostId = 0;regBasePhy = 0x10100000;irqNum = 96;devType = 0;                              // eMMC類型caps = 0xd001e045;caps2 = 0x60;}controller_0x100f0000 :: mmc_controller {match_attr = "hi3516_mmc_sd";hostId = 1;regBasePhy = 0x100f0000;irqNum = 62;devType = 1;                              // SD類型caps = 0xd001e005;}controller_0x10020000 :: mmc_controller {match_attr = "hi3516_mmc_sdio";hostId = 2;regBasePhy = 0x10020000;irqNum = 63;devType = 2;                              // SDIO類型caps = 0x0001e04d;}}}
      }
      

      需要注意的是,新增mmc_config.hcs配置文件后,必須在產品對應的hdf.hcs文件中將其包含如下語句所示,否則配置文件無法生效。

      #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/mmc/mmc_config.hcs" // 配置文件相對路徑
      
  3. 實例化MMC控制器對象

    完成配置屬性文件之后,下一步就是以核心層MmcCntlr對象的初始化為核心,包括驅動適配自定義結構體(傳遞參數和數據),實例化MmcCntlr成員MmcCntlrOps(讓用戶可以通過接口來調用驅動底層函數),實現HdfDriverEntry成員函數(Bind、Init、Release)。

    • 驅動適配者自定義結構體參考。

      從驅動的角度看,自定義結構體是參數和數據的載體,而且mmc_config.hcs文件中的數值會被HDF讀入并通過DeviceResourceIface來初始化結構體成員,一些重要數值也會傳遞給核心層對象。

      struct HimciHost {struct MmcCntlr *mmc;                              // 【必要】核心層控制對象struct MmcCmd *cmd;                                // 【必要】核心層結構體,傳遞命令,相關命令見枚舉量MmcCmdCodevoid *base;                                        // 地址映射需要,寄存器基地址enum HimciPowerStatus powerStatus;uint8_t *alignedBuff;uint32_t buffLen;struct scatterlist dmaSg;struct scatterlist *sg;uint32_t dmaSgNum;DMA_ADDR_T dmaPaddr;uint32_t *dmaVaddr;uint32_t irqNum;bool isTuning;uint32_t id;struct OsalMutex mutex;bool waitForEvent;HIMCI_EVENT himciEvent;
      };
      // MmcCntlr是核心層控制器結構體,其中的成員在Bind函數中會被賦值。
      struct MmcCntlr {struct IDeviceIoService service;struct HdfDeviceObject *hdfDevObj;struct PlatformDevice device;struct OsalMutex mutex;struct OsalSem released;uint32_t devType;struct MmcDevice *curDev;struct MmcCntlrOps *ops;struct PlatformQueue *msgQueue;uint16_t index;uint16_t voltDef;uint32_t vddBit;uint32_t freqMin;uint32_t freqMax;uint32_t freqDef;union MmcOcr ocrDef;union MmcCaps caps;union MmcCaps2 caps2;uint32_t maxBlkNum;uint32_t maxBlkSize;uint32_t maxReqSize;bool devPlugged;bool detecting;void *priv;
      };
      
    • MmcCntlr成員鉤子函數結構體MmcCntlrOps的實例化。

      static struct MmcCntlrOps g_himciHostOps = {.request = HimciDoRequest,.setClock = HimciSetClock,.setPowerMode = HimciSetPowerMode,.setBusWidth = HimciSetBusWidth,.setBusTiming = HimciSetBusTiming,.setSdioIrq = HimciSetSdioIrq,.hardwareReset = HimciHardwareReset,.systemInit = HimciSystemInit,.setEnhanceStrobe = HimciSetEnhanceStrobe,.switchVoltage = HimciSwitchVoltage,.devReadOnly = HimciDevReadOnly,.devPlugged = HimciCardPlugged,.devBusy = HimciDevBusy,.tune = HimciTune,.rescanSdioDev = HimciRescanSdioDev,
      };
      
    • Bind函數開發參考。

      入參:

      HdfDeviceObject:HDF框架給每一個驅動創建的設備對象,用來保存設備相關的私有數據和服務接口。

      返回值:

      HDF_STATUS相關狀態(表3為部分展示,如需使用其他狀態,可參考//drivers/hdf_core/interfaces/inner_api/utils/hdf_base.h中HDF_STATUS的定義)。

      表 3 HDF_STATUS相關狀態說明

      狀態(值)問題描述
      HDF_ERR_INVALID_OBJECT控制器對象非法
      HDF_ERR_MALLOC_FAIL內存分配失敗
      HDF_ERR_INVALID_PARAM參數非法
      HDF_ERR_IOI/O?錯誤
      HDF_SUCCESS初始化成功
      HDF_FAILURE初始化失敗

      函數說明: MmcCntlr、HimciHost、HdfDeviceObject之間互相賦值,方便其他函數可以相互轉化,初始化自定義結構體HimciHost對象,初始化MmcCntlr成員,調用核心層MmcCntlrAdd函數,完成MMC控制器的添加。

      static int32_t HimciMmcBind(struct HdfDeviceObject *obj)
      {struct MmcCntlr *cntlr = NULL;struct HimciHost *host = NULL;int32_t ret;cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost));host->mmc = cntlr;                              // 【必要】使HimciHost與MmcCntlr可以相互轉化的前提cntlr->priv = (void *)host;                     // 【必要】使HimciHost與MmcCntlr可以相互轉化的前提cntlr->ops = &g_himciHostOps;                   // 【必要】MmcCntlrOps的實例化對象的掛載cntlr->hdfDevObj = obj;                         // 【必要】使HdfDeviceObject與MmcCntlr可以相互轉化的前提obj->service = &cntlr->service;                 // 【必要】使HdfDeviceObject與MmcCntlr可以相互轉化的前提ret = MmcCntlrParse(cntlr, obj);                // 【必要】 初始化cntlr,失敗就goto _ERR。......ret = HimciHostParse(host, obj);                // 【必要】 初始化host對象的相關屬性,失敗就goto _ERR。......ret = HimciHostInit(host, cntlr);               // 驅動適配者自定義的初始化,失敗就goto _ERR。......ret = MmcCntlrAdd(cntlr);                       // 調用核心層函數,失敗就goto _ERR。......(void)MmcCntlrAddDetectMsgToQueue(cntlr);       // 將卡檢測消息添加到隊列中。HDF_LOGD("HimciMmcBind: success.");return HDF_SUCCESS;
      ERR:HimciDeleteHost(host);HDF_LOGD("HimciMmcBind: fail, err = %d.", ret);return ret;
      }
      
    • Init函數開發參考。

      入參:

      HdfDeviceObject:HDF框架給每一個驅動創建的設備對象,用來保存設備相關的私有數據和服務接口。

      返回值:

      HDF_STATUS相關狀態。

      函數說明:

      實現ProcMciInit。

      static int32_t HimciMmcInit(struct HdfDeviceObject *obj)
      {static bool procInit = false;(void)obj;if (procInit == false) {if (ProcMciInit() == HDF_SUCCESS) {procInit = true;HDF_LOGD("HimciMmcInit: proc init success.");}}HDF_LOGD("HimciMmcInit: success.");return HDF_SUCCESS;
      }
      
    • Release函數開發參考。

      入參:

      HdfDeviceObject:HDF框架給每一個驅動創建的設備對象,用來保存設備相關的私有數據和服務接口。

      返回值:

      無。

      函數說明:

      釋放內存和刪除控制器等操作,該函數需要在驅動入口結構體中賦值給Release接口,當HDF框架調用Init函數初始化驅動失敗時,可以調用Release釋放驅動資源。

      說明:
      所有強制轉換獲取相應對象的操作前提是在Init函數中具備對應賦值的操作。

      static void HimciMmcRelease(struct HdfDeviceObject *obj)
      {struct MmcCntlr *cntlr = NULL;......cntlr = (struct MmcCntlr *)obj->service;             // 這里有HdfDeviceObject到MmcCntlr的強制轉化,通過service成員,賦值見Bind函數。......HimciDeleteHost((struct HimciHost *)cntlr->priv);    // 驅動適配者自定義的內存釋放函數,這里有MmcCntlr到HimciHost的強制轉化。
      }
      
  4. 驅動調試

    【可選】針對新增驅動程序,建議驗證驅動基本功能,例如掛載后的信息反饋,數據讀寫成功與否等。

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

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

相關文章

C++ 的 VS 項目中引入跨平臺包管理工具 conan

我們知道 C 不像很多其他語言有包管理工具,比如 Python 有 pip,Java 有 maven,C# 有 nuget,JS 有 npm,Go 有 go mod,Rust 有 cargo,項目中需要自己手動引入第三方庫,手動維護帶來了很…

vscode 默認環境路徑

1.下面放在項目根目錄上: .vscode/settings.json 2.settings.json內容: {"python.analysis.extraPaths": ["${workspaceFolder}"],"python.defaultInterpreterPath": "/shared_disk/users/lbg/envs/py310_see3d/b…

Android 項目中配置了多個 maven 倉庫,但依賴還是下載失敗,除了使用代理,還有其他方法嗎?

文章目錄 前言解決方案gradlemaven 倉庫 前言 我們在Android 開發的過程中,經常會遇到三方依賴下載不下來的問題。一般情況下我們會在項目的build.gradle文件中配置多個 maven 倉庫來解決。 // Top-level build file where you can add configuration options com…

uni-app 引入vconsole web端正常,安卓端報錯 Cannot read property ‘sendBeacon‘ of undefined

reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property sendBeacon of undefined vconsole 只支持 web 端,…

火山RTC 7 獲得遠端裸數據

一、獲得遠端裸數據 1、獲得h264數據 1&#xff09;、遠端編碼后視頻數據監測器 /*** locale zh* type callback* region 視頻管理* brief 遠端編碼后視頻數據監測器<br>* 注意&#xff1a;回調函數是在 SDK 內部線程&#xff08;非 UI 線程&#xff09;同步拋出來的&a…

web 自動化之 Unittest 四大組件

文章目錄 一、如何開展自動化測試1、項目需求分析&#xff0c;了解業務需求 web 功能納入自動化測試2、選擇何種方式實現自動化測試 二、Unittest 框架三、TestCase 測試用例四、TestFixture 測試夾具 執行測試用例前的前置操作及后置操作五、TestSuite 測試套件 & TestLoa…

42、在.NET 中能夠將?靜態的?法覆寫成靜態?法嗎?

在.NET中&#xff0c;不能將非靜態方法&#xff08;實例方法&#xff09;直接覆寫&#xff08;Override&#xff09;為靜態方法&#xff08;Static Method&#xff09;。以下是關鍵原因和解釋&#xff1a; 1. 方法綁定的本質區別 實例方法&#xff1a;屬于對象的實例&#xf…

8天Python從入門到精通【itheima】-1~5

目錄 1節&#xff1a; 1.Python的優勢&#xff1a; 2.Python的獨具優勢的特點&#xff1a; 2節-初識Python&#xff1a; 1.Python的起源 2.Python廣泛的適用面&#xff1a; 3節-什么是編程語言&#xff1a; 1.編程語言的作用&#xff1a; 2.編程語言的好處&#xff1a;…

3D迷宮探險:偽3D渲染與運動控制的數學重構

目錄 3D迷宮探險:偽3D渲染與運動控制的數學重構引言第一章 偽3D渲染引擎1.1 射線投射原理1.2 紋理透視校正第二章 迷宮生成算法2.1 圖論生成模型2.2 復雜度控制第三章 第一人稱控制3.1 運動微分方程3.2 鼠標視角控制第四章 碰撞檢測優化4.1 層級檢測體系4.2 滑動響應算法第五章…

mac一鍵安裝gpt-sovit教程中,homebrew卡住不動的問題

mac一鍵安裝gpt-sovit教程 僅作為安裝過程中解決homebrew卡住問題的記錄 資源地址 https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/znoph9dtetg437xb#mlAoP 下載一鍵包 下載后并解壓&#xff0c;找到install for mac.sh&#xff0c;終端執行bash空格拖拽in…

git 遠程倉庫管理詳解

Git 的遠程倉庫管理是多人協作和代碼共享的核心功能。以下是 Git 遠程倉庫管理的詳細說明&#xff0c;包括常用操作、命令和最佳實踐。 1. 什么是遠程倉庫&#xff1f; 遠程倉庫&#xff08;Remote Repository&#xff09;&#xff1a;存儲在網絡服務器上的 Git 倉庫&#xff0…

【超詳細教程】安卓模擬器如何添加本地文件?音樂/照片/視頻一鍵導入!

作為一名安卓開發者或手游愛好者&#xff0c;安卓模擬器是我們日常工作和娛樂的重要工具。但很多新手在使用過程中常常遇到一個共同問題&#xff1a;**如何將電腦本地的音樂、照片、視頻等文件導入到安卓模擬器中&#xff1f;**今天&#xff0c;我將為大家帶來一份全網最詳細的…

使用vite重構vue-cli的vue3項目

一、修改依賴 首先修改 package.json&#xff0c;修改啟動方式與相應依賴 移除vue-cli并下載vite相關依賴&#xff0c;注意一些peerDependency如fast-glob需要手動下載 # 移除 vue-cli 相關依賴 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

uniapp|實現手機通訊錄、首字母快捷導航功能、多端兼容(H5、微信小程序、APP)

基于uniapp實現帶首字母快捷導航的通訊錄功能,通過拼音轉換庫實現漢字姓名首字母提取與分類,結合uniapp的scroll-view組件與pageScrollTo API完成滾動定位交互,并引入uni-indexed-list插件優化索引欄性能。 目錄 核心功能實現動態索引欄生成?聯系人列表渲染?滾動定位聯動性…

C#中SetProperty方法使用

SetProperty 是 MVVM&#xff08;Model-View-ViewModel&#xff09; 模式中用于實現 屬性變更通知&#xff08;INotifyPropertyChanged&#xff09; 的核心方法&#xff0c;主要用于在屬性值變化時自動更新 UI 綁定。 1. SetProperty 的基本作用 更新字段值&#xff1a;修改屬性…

MYSQL 全量,增量備份與恢復

目錄 一 數據備份的重要性 1 數據備份的重要性 2 數據庫備份類型 2.1 從物理與邏輯的角度分類 2.2. 從數據庫的備份策略角度分類從數據庫的備份策略角度,數據庫的備份可分為完全備份、差異備份和增量備份。 3 常見的備份方法 3.1 物理冷備份 物理冷備份時需要在數據庫處…

豆瓣電影Top250數據工程實踐:從爬蟲到智能存儲的技術演進(含完整代碼)

目錄 引言:當豆瓣榜單遇見大數據技術 項目文檔 1.1 選題背景 1.2 項目目標 2. 項目概述 2.1 系統架構設計 2.2 技術選型 2.3 項目環境搭建 2.3.1 基礎環境準備 2.3.2 爬蟲環境配置 2.3.3 Docker安裝ES連接Kibana 安裝IK插件 2.3.4 vscode依賴服務安裝 3. 核心模…

深度 |國產操作系統“破繭而出”:鴻蒙電腦填補自主生態空白

真心為國內能有像華為這樣的技術型公司而自豪&#xff0c;一步步突圍技術封鎖。從這篇信息&#xff0c;可以給軟件從業者一個啟示&#xff1a;鴻蒙生態將是一個新的機會&#xff0c;值得好好把握。 鴻蒙電腦正成為中國電子信息技術新坐標。 超10億鴻蒙生態設備、2800家鴻蒙智…

【網絡安全】——大端序(Big-Endian)??和??小端序(Little-Endian)

字節序&#xff08;Endianness&#xff09;是計算機系統中多字節數據&#xff08;如整數、浮點數&#xff09;在內存中存儲或傳輸時&#xff0c;??字節排列順序??的規則。它分為兩種類型&#xff1a;??大端序&#xff08;Big-Endian&#xff09;??和??小端序&#xf…

六個倉庫合并為一個倉庫,保留master和develop分支的bat腳本

利用git subtree可以實現多個倉庫合并為一個倉庫&#xff0c;手動操作起來太麻煩了&#xff0c;今天花了點時間寫了一個可執行的腳本&#xff0c;現在操作起來就方便多了。 1、本地新建setup.bat文件 2、用編輯器打開&#xff08;我用的是Notepad&#xff09; 3、把下面代碼…