14.2 - VDMA彩條顯示實驗之動態時鐘

文章目錄

  • 1 實驗任務
  • 2 系統框圖
  • 3 硬件設計
  • 4 軟件設計
    • 4.1 dynclk_api.h文件
    • 4.2 math_compat.h文件
    • 4.3 dynclk_api.c文件
    • 4.4 main.c文件

1 實驗任務

參見14.1。

2 系統框圖

參見14.1。

3 硬件設計

注意事項:基于14.1做如下改動

  1. 使能Clocking Wizard IP核的Dynamic Reconfig功能,并選擇AXI4-Lite接口;
  2. 將Clocking Wizard IP核的AXI4-Lite接口通過AXI Interconnect連接到PS的M_AXI_GP接口。

特別說明:為什么不使用Digilent公司提供的axi_dynclk IP核(正點原子教程使用該IP),原因如下

  1. axi_dynclk IP核輸出兩個時鐘,PXL_CLK_O和PXL_CLK_5X_O;
  2. PXL_CLK_5X_O由BUFIO驅動,PXL_CLK_O由BUFR驅動(5倍分頻);
  3. PXL_CLK_O在本實驗的Vivado工程中布線無法通過,提示路徑太遠,原因應該是BUFR是區域時鐘緩沖器,能夠驅動的資源有限,導致布線失敗;
  4. 正點原子的教程使用axi_dynclk IP核編譯可以通過,猜測原因可能是整個工程只使用一個時鐘,即PS提供的FCLK_CLK0;
  5. 本實驗的Vivado工程中使用三個時鐘
    • PS輸出的FCLK_CLK0(50MHz),用于連接AXI4-Lite接口;
    • PS輸出的FCLK_CLK1(150MHz),用于連接AXI4接口;
    • 板載時鐘(50MHz)經Clocking Wizard IP核輸出的視頻像素時鐘(148.5MHz)
  6. 嘗試在IP Packager中對axi_dynclk IP核進行修改,使其只輸出一個時鐘,且該時鐘由BUFG驅動,但是修改完成之后,在對IP進行重新封裝時,Vivado工具總是閃退,多次嘗試并重啟電腦,依舊如此,故放棄。

4 軟件設計

動態時鐘的軟件配置部分代碼,我是讓deepseek幫我生成的,我負責提需求,包括:

  1. pg065中關于通過AXI4-Lite接口動態配置時鐘的步驟;
  2. 輸出頻率Fout的計算公式
  3. 計算公式中各個參數的取值范圍,包括
    • Fvco = 600MHz~1200MHz(和器件型號及等級有關)
    • CLKFBOUT_MULT_F = 2.0 ~ 64.0(MMCM,小數部分以0.125步進)/1~64(PLL)
    • DIVCLK_DIVIDE = 1 ~ 106(MMCM)/1~56(PLL)
    • CLKOUT0_DIVIDE = 1.000 ~ 128.000(MMCM,小數部分以0.125步進)/1~128(PLL)
  4. 關鍵寄存器的說明,包括
    • Software Reset Register (SRR),偏移地址0x00
    • Status Register (SR),偏移地址0x04
    • Clock Configuration Register 0,偏移地址0x200
    • Clock Configuration Register 2,偏移地址0x208
    • Clock Configuration Register 23,偏移地址0x25C

代碼生成后,讓deepseek形成xxx_api.c文件和xxx_api.h文件,使用很方便,只需提供輸入時鐘頻率和期望的輸出時鐘頻率(不能輸出類似33.333MHz的時鐘),效果非常好。

4.1 dynclk_api.h文件

代碼如下所示:

#ifndef XCLK_WIZ_API_H
#define XCLK_WIZ_API_H#include "xparameters.h"
#include "xclk_wiz_hw.h"
#include "math_compat.h"// 寄存器基地址
#define XCLKWIZ_BASEADDR				XPAR_CLK_WIZ_0_BASEADDR// VCO頻率范圍(MHz)
#define MIN_VCO_FREQ 					600.0
#define MAX_VCO_FREQ 					1200.0// 參數范圍
#define MIN_CLKFBOUT_MULT 				2
#define MAX_CLKFBOUT_MULT 				64
#define MIN_DIVCLK_DIVIDE 				1
#define MAX_DIVCLK_DIVIDE 				106
#define MIN_CLKOUT0_DIVIDE 				1
#define MAX_CLKOUT0_DIVIDE 				128// 小數部分步進
#define FRAC_STEP 						0.125
#define FRAC_SCALE 						1000// 寄存器偏移量 (根據文檔修正)
#define XCLKWIZ_SOFT_RESET_OFFSET 		0x0    // Soft Reset Register
#define XCLKWIZ_STATUS_OFFSET     		0x4    // Status Register
#define XCLKWIZ_CLK_CONFIG_00_OFFSET	0x200  // Clock Configuation Register 00
#define XCLKWIZ_CLK_CONFIG_02_OFFSET	0x208  // Clock Configuation Register 02
#define XCLKWIZ_CLK_CONFIG_23_OFFSET	0x25C  // Clock Configuation Register 23// 寄存器值定義
/** To activate software reset, the value 0x0000_000A must be written to the register.*/
#define XCLKWIZ_RESET_VALUE       		0xA
/** When '1' MMCM/PLL is Locked and ready for the reconfiguration. Status of this bit is '0' during the reconfiguration.*/
#define XCLKWIZ_STATUS_LOCKED_MASK 		0x1// 錯誤代碼
#define XCLK_WIZ_SUCCESS 				0
#define XCLK_WIZ_ERROR_INVALID_PARAM	-1
#define XCLK_WIZ_ERROR_RESET_FAILED 	-2
#define XCLK_WIZ_ERROR_LOCK_FAILED 		-3// 100ms計數值定義
#define COUNT_NUM_100MS					(XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 10)/*** @brief 配置時鐘向導IP* @param input_freq 輸入時鐘頻率(MHz)* @param output_freq 期望的輸出時鐘頻率(MHz)* @return 成功返回XCLK_WIZ_SUCCESS,失敗返回錯誤代碼**/
int clk_wiz_configure(double input_freq, double output_freq);/*** @brief 復位時鐘向導IP* @return 成功返回XCLK_WIZ_SUCCESS,失敗返回錯誤代碼**/
int clk_wiz_reset(void);/*** @brief 檢查時鐘向導是否鎖定* @return 鎖定返回1,未鎖定返回0**/
int clk_wiz_is_locked(void);#endif // XCLK_WIZ_API_H

4.2 math_compat.h文件

代碼如下所示

#ifndef MATH_COMPAT_H
#define MATH_COMPAT_H/*****************************************************************************/// 替代ceil函數實現
static inline double ceil(double x) {if (x >= 0.0) {int int_part = (int)x;return (x == (double)int_part) ? x : (double)(int_part + 1);}else {int int_part = (int)x;return (double)int_part;}
}/*****************************************************************************/// 替代floor函數實現
static inline double floor(double x) {if (x >= 0.0) {return (double)((int)x);}else {int int_part = (int)x;return (x == (double)int_part) ? x : (double)(int_part - 1);}
}/*****************************************************************************/// 替代fmax函數實現
static inline double fmax(double x, double y) {return (x > y) ? x : y;
}/*****************************************************************************/// 替代fmin函數實現
static inline double fmin(double x, double y) {return (x < y) ? x : y;
}/*****************************************************************************/// 替代fabs函數實現(雖然math.h中有聲明,但可能缺少實現)
static inline double fabs(double x) {return (x < 0.0) ? -x : x;
}/*****************************************************************************/#endif // MATH_COMPAT_H

4.3 dynclk_api.c文件

代碼如下所示:

/*****************************************************************************/#include "dynclk_api.h"
#include <stdio.h>/*****************************************************************************/// 內部函數聲明
static int calculate_pll_params(double input_freq, double output_freq, int *divclk_divide, double *clkfbout_mult, double *clkout0_divide);
static u32 build_reg0_value(int divclk_divide, double clkfbout_mult);
static u32 build_reg2_value(double clkout0_divide);
static int wait_for_lock(u32 timeout_us);/*****************************************************************************/int clk_wiz_is_locked(void) {//u32 status = XClk_Wiz_ReadReg(XCLKWIZ_BASEADDR, XCLKWIZ_STATUS_OFFSET);//return (status & XCLKWIZ_STATUS_LOCKED_MASK) ? 1 : 0;
}/*****************************************************************************/static int wait_for_lock(u32 timeout_count) {//while (timeout_count--) {if (clk_wiz_is_locked()) {return XCLK_WIZ_SUCCESS;}}//return XCLK_WIZ_ERROR_LOCK_FAILED;
}/*****************************************************************************/int clk_wiz_reset(void) {//printf("2 - PLL Reset Start.\n");// 發送復位信號XClk_Wiz_WriteReg(XCLKWIZ_BASEADDR, XCLKWIZ_SOFT_RESET_OFFSET, XCLKWIZ_RESET_VALUE);// 檢查復位是否完成printf("\tWaiting for PLL lock...\n");if (wait_for_lock(COUNT_NUM_100MS) != XCLK_WIZ_SUCCESS) { // 100ms超時printf("\tError: PLL Lock Failed.\n");return XCLK_WIZ_ERROR_LOCK_FAILED;}//printf("\tPLL Reset Completed.\n\n");//return XCLK_WIZ_SUCCESS;
}/*****************************************************************************/static int calculate_pll_params(double input_freq, double output_freq, int *divclk_divide, double *clkfbout_mult, double *clkout0_divide) {//double vco_freq;int found = 0;double min_vco = MIN_VCO_FREQ;double max_vco = MAX_VCO_FREQ;// 嘗試不同的DIVCLK_DIVIDE值for (int d = MIN_DIVCLK_DIVIDE; d <= MAX_DIVCLK_DIVIDE && !found; d++) {// 計算可能的CLKFBOUT_MULT值范圍double min_mult = min_vco / (input_freq / d);double max_mult = max_vco / (input_freq / d);// 確保在有效范圍內 - 使用我們的fmax/fmin實現min_mult = (min_mult > MIN_CLKFBOUT_MULT) ? min_mult : MIN_CLKFBOUT_MULT;max_mult = (max_mult < MAX_CLKFBOUT_MULT) ? max_mult : MAX_CLKFBOUT_MULT;if (min_mult > max_mult) continue;// 計算整數部分范圍int min_int = (int)min_mult;int max_int = (int)max_mult + 1;// 嘗試CLKFBOUT_MULT值for (int m = min_int; m <= max_int && !found; m++) {// 嘗試小數部分for (int f = 0; f <= 7; f++) {  // 0.125步進(0-0.875)double mult = m + f * FRAC_STEP;// 檢查是否在范圍內if (mult < min_mult || mult > max_mult) continue;// 計算VCO頻率vco_freq = (input_freq / d) * mult;// 計算所需的CLKOUT0_DIVIDEdouble divide = vco_freq / output_freq;// 檢查CLKOUT0_DIVIDE是否在范圍內if (divide < MIN_CLKOUT0_DIVIDE || divide > MAX_CLKOUT0_DIVIDE) continue;// 檢查小數部分double fractional_part = divide - (int)divide;int valid_fraction = 0;// 檢查小數部分是否是0.125的整數倍for (int i = 0; i <= 7; i++) {if ((fractional_part - i * FRAC_STEP) < 0.0001 &&(fractional_part - i * FRAC_STEP) > -0.0001) {valid_fraction = 1;break;}}if (!valid_fraction && fractional_part > 0.0001) continue;// 找到有效參數*divclk_divide = d;*clkfbout_mult = mult;*clkout0_divide = divide;found = 1;break;}}}//return found ? 0 : -1;
}/*****************************************************************************/static u32 build_reg0_value(int divclk_divide, double clkfbout_mult) {//u32 reg_value = 0;// 提取整數和小數部分int integer_part = (int)clkfbout_mult;double fractional_part = clkfbout_mult - integer_part;int fractional_value = (int)(fractional_part * FRAC_SCALE);// 構建寄存器值reg_value |= (divclk_divide & 0xFF);           // Bits [7:0]reg_value |= (integer_part & 0xFF) << 8;       // Bits [15:8]reg_value |= (fractional_value & 0x3FF) << 16; // Bits [25:16]//return reg_value;
}/*****************************************************************************/static u32 build_reg2_value(double clkout0_divide) {//u32 reg_value = 0;// 提取整數和小數部分int integer_part = (int)clkout0_divide;double fractional_part = clkout0_divide - integer_part;int fractional_value = (int)(fractional_part * FRAC_SCALE);// 構建寄存器值reg_value |= (integer_part & 0xFF);           // Bits [7:0]reg_value |= (fractional_value & 0x3FF) << 8; // Bits [17:8]//return reg_value;
}/*****************************************************************************/int clk_wiz_configure(double input_freq, double output_freq) {//int divclk_divide;double clkfbout_mult, clkout0_divide;u32 reg0_value, reg2_value;// 參數檢查if (input_freq <= 0 || output_freq <= 0) {printf("Error: Invalid Frequency Parameters.\n");return XCLK_WIZ_ERROR_INVALID_PARAM;}// 1. 計算PLL參數if (calculate_pll_params(input_freq, output_freq, &divclk_divide,&clkfbout_mult, &clkout0_divide) != 0) {printf("Error: Cannot Find Suitable PLL Parameters.\n");return XCLK_WIZ_ERROR_INVALID_PARAM;}printf("1 - Calculate FVCO Parameters:\n");printf("\tDIVCLK_DIVIDE: %d\n", divclk_divide);printf("\tCLKFBOUT_MULT: %.3f\n", clkfbout_mult);printf("\tCLKOUT0_DIVIDE: %.3f\n\n", clkout0_divide);// 2. 復位PLLif (clk_wiz_reset() != XCLK_WIZ_SUCCESS) {return XCLK_WIZ_ERROR_RESET_FAILED;}// 3. 構建寄存器值reg0_value = build_reg0_value(divclk_divide, clkfbout_mult);reg2_value = build_reg2_value(clkout0_divide);printf("3 - Build Clock Configuration Register Values:\n");printf("\tReg0 (0x%x): 0x%lx\n", XCLKWIZ_CLK_CONFIG_00_OFFSET, reg0_value);printf("\tReg2 (0x%x): 0x%lx\n\n", XCLKWIZ_CLK_CONFIG_02_OFFSET, reg2_value);// 4. 配置寄存器XClk_Wiz_WriteReg(XCLKWIZ_BASEADDR, XCLKWIZ_CLK_CONFIG_00_OFFSET, reg0_value);XClk_Wiz_WriteReg(XCLKWIZ_BASEADDR, XCLKWIZ_CLK_CONFIG_02_OFFSET, reg2_value);printf("4 - Write Clock Configuration Register Values.\n\n");// 5. 加載新配置XClk_Wiz_WriteReg(XCLKWIZ_BASEADDR, XCLKWIZ_CLK_CONFIG_23_OFFSET, 0x3);printf("5 - Load Clock Configuration Register Values.\n\n");// 6. 等待鎖定printf("6 - Waiting for PLL Lock...\n");if (wait_for_lock(COUNT_NUM_100MS) != XCLK_WIZ_SUCCESS) {printf("Error: PLL Lock Failed.\n");return XCLK_WIZ_ERROR_LOCK_FAILED;}printf("\tPLl Lock Succeeded.\n\n");//return XCLK_WIZ_SUCCESS;
}/*****************************************************************************/

4.4 main.c文件

在14.1提供的main函數基礎上,修改while循環部分,代碼如下所示:

    while (1) {//sleep(20);result = clk_wiz_configure(50, 123.75);switch(result) {case XCLK_WIZ_SUCCESS:printf("PLL Configuration Completed.\n\n");break;case XCLK_WIZ_ERROR_INVALID_PARAM:printf("Error: Invalid Parameters Provided.\n\n");break;case XCLK_WIZ_ERROR_RESET_FAILED:printf("Error: PLL Reset Failed.\n\n");break;case XCLK_WIZ_ERROR_LOCK_FAILED:printf("Error: PLL Lock Failed.\n\n");break;default:printf("Error: Unknown Error Occurred.\n\n");}//sleep(20);result = clk_wiz_configure(50, 148.5);switch(result) {case XCLK_WIZ_SUCCESS:printf("PLL Configuration Completed.\n\n");break;case XCLK_WIZ_ERROR_INVALID_PARAM:printf("Error: Invalid Parameters Provided.\n\n");break;case XCLK_WIZ_ERROR_RESET_FAILED:printf("Error: PLL Reset Failed.\n\n");break;case XCLK_WIZ_ERROR_LOCK_FAILED:printf("Error: PLL Lock Failed.\n\n");break;default:printf("Error: Unknown Error Occurred.\n\n");}}

實測效果:每隔20s,重配置一次時鐘頻率,輸出視頻在1080p@50Hz和1080p@60Hz之間切換。

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

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

相關文章

在邊緣端進行tensorflow模型的部署(小白初探)

1.配置tensorflow的環境 &#xff08;我是安裝GPU版本的&#xff09; 建議參考這個博主的文章&#xff0c;確實非常快速&#xff01; 十分鐘安裝Tensorflow-gpu2.6.0本機CUDA12 以及numpymatplotlib各包版本協調問題_tensorflow cuda12-CSDN博客 2.學習自制數據集 &#xf…

windows下使用nginx + waitress 部署django

架構介紹 linux一般采用nginx uwsgi部署django&#xff0c;在Windows下&#xff0c;可以取代uwsgi的選項包括Waitressa、Daphnea、Hypercoma和Gunicorna(通過WSLa 運行)。windows服務器一般采用nginx waitress 部署django&#xff0c;,他們的關系如下 django是WEB應用…

利用pnpm patch命令實現依賴包熱更新:精準打補丁指南

需求場景 在Element Plus的el-table組件二次開發中&#xff0c;需新增列顯示/隱藏控件功能。直接修改node_modules源碼存在兩大痛點&#xff1a; 團隊協作時修改無法同步 依賴更新導致自定義代碼丟失 解決方案選型 通過patch-package工具實現&#xff1a; &#x1f4e6; 非…

ThinkPad T520 無法讀到硬盤 問題排查思路

錯誤提示&#xff1a;2100:detection error on hdd0(Main hdd) 1、判斷錯誤提示含義 表示電腦在啟動時無法檢測到主硬盤&#xff08;HDD0&#xff09;。 2、 常見原因&#xff1a; 硬盤松動或接觸不良 → 特別是筆記本在移動或震動后&#xff0c;硬盤排線松了。 硬盤損壞 →…

Doris部署生產集群最低要求的部署方案

Doris生產集群最低部署方案&#xff08;2025年4月版&#xff09; 一、節點規劃與數量 1. FE節點&#xff08;Frontend&#xff09; 數量&#xff1a;至少 3個節點&#xff08;1個Follower 2個 Observer&#xff09;&#xff0c;確保高可用&#xff08;HA&#xff09;。角色分…

游戲引擎學習第227天

今天的計劃 今天的工作重點是進行吸引模式&#xff08;attract mode&#xff09;的開發&#xff0c;主要是處理游戲的進出和其他一些小的細節問題&#xff0c;這些是之前想要整理和清理的部分。我做了一些工作&#xff0c;將游戲代碼中的不同部分分離到邏輯上獨立的區域&#…

spark-SQL數據加載和保存

數據加載與保存 通用方式&#xff1a; 通過 spark.read.load 和 df.write.save 實現數據加載與保存。可利用 format 指定數據格式&#xff0c;如 csv 、 jdbc 等&#xff1b; option 用于設置特定參數&#xff0c;像 jdbc 格式下的數據庫連接信息&#xff1b; load 和 save 則…

算法升級戰報:亞馬遜受眾定向工具實測點擊成本降37%

隨著廣告成本居高不下&#xff0c;精準投放成為賣家們繞不開的焦慮點。而最近一輪亞馬遜DSP廣告系統的算法升級&#xff0c;似乎正在給這場投放內卷帶來新的轉機。在這篇文章中&#xff0c;我們將基于實際測試數據&#xff0c;詳細解析亞馬遜受眾定向工具的表現&#xff0c;并復…

大帶寬服務器的優勢

大帶寬服務器最大的優勢就在于可以顯著提高數據傳輸的速度&#xff0c;這對于有著高流量應用和實時數據交換需求的企業來說&#xff0c;大帶寬服務器中的帶寬越大&#xff0c;所提供的數據傳輸速度就越快&#xff0c;同時網絡的延遲度也會變低&#xff0c;所以大帶寬服務器往往…

華為OD機試真題——阿里巴巴找黃金寶箱 IV(2025A卷:200分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 200分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析&#xff1b; 并提供Java、python、JavaScript、C、C語言、GO六種語言的最佳實現方式&#xff01; 華為OD機試真題《阿里巴巴找黃金寶箱 IV》&#xff1a; 目錄 題目名稱&…

C++零基礎實踐教程

模塊一&#xff1a;準備工作與第一個程序 (熱身) 在正式編寫代碼之前&#xff0c;我們需要了解為什么要學習 C&#xff0c;并搭建好我們的開發環境。然后&#xff0c;我們將編寫并運行第一個簡單的 C 程序。 1. 為什么選擇 C&#xff1f; 你可能聽說過很多編程語言&#xff…

6 CMD 與 PowerShell 指令大全、C 程序終端運行、字符編碼切換指南

1 CMD 與 PowerShell 常用指令 在命令行環境中高效運行程序&#xff0c;掌握終端的基本操作命令至關重要。無論是 Windows 系統下的 CMD&#xff08;命令提示符&#xff09;還是 PowerShell&#xff0c;它們都配備了一系列實用的命令&#xff0c;助力我們管理文件、執行程序以及…

Linux——共享內存

目錄 一、共享內存概念 二、共享內存的一些函數 2.1 shmget 創建共享內存 2.2 shmat 訪問共享內存 2.3 shmdt 解除共享內存的映射 2.4 shnctl 刪除共享內存段 三、共享內存 3.1 創建測試進程 3.2 使用循環測試 ?編輯 3.3 共享內存寫入程序 3.4 帶有信號量的共享內…

數啟新疆,智領未來!2025新疆數字經濟發展戰略研討會在烏市啟幕

2025年4月20日&#xff0c;由新疆維吾爾自治區數字經濟聯合會主辦、中鈞科技有限公司承辦的"2025新疆數字經濟發展戰略研討會"將在烏魯木齊水磨溝區金正大廈三層會議中心隆重召開。 作為本年度新疆數字經濟領域規格最高的行業盛會&#xff0c;會議將匯聚自治區14個廳…

Nginx:輕量級高性能的Web服務器與反向代理服務器

目錄 一.引言 二.Nginx的核心特點 2.1高性能與高并發 2.2低資源消耗 2.3功能豐富 2.4高度擴展性 三.Nginx的應用場景 3.1靜態資源服務器 3.2反向代理服務器 3.3API網關 3.4Nginx的配置與使用 四.總結 一.引言 在互聯網高速發展的今天&#xff0c;Web服務器的性能與…

嵌入式Linux設備使用Go語言快速構建Web服務,實現設備參數配置管理方案探究

本文探討&#xff0c;利用Go語言及gin框架在嵌入式Linux設備上高效搭建Web服務器&#xff0c;以實現設備參數的網頁配置。通過gin框架&#xff0c;我們可以在幾分鐘內創建一個功能完善的管理界面&#xff0c;方便對諸如集中器&#xff0c;集線器等沒有界面的嵌入式設備的管理。…

KALI搭建log4j2靶場及漏洞復現全流程

這里使用了兩臺KALI虛擬機&#xff0c;一臺用于安裝靶場環境&#xff0c;一臺用于攻擊 一、Docker的安裝&#xff08;靶機&#xff09; 1、Linux內核版本查看 #安裝docker要求內核版本kerner>3.10 #為此&#xff0c;先檢查當前Linux系統的內核版本 uname -a 2、Linux apt…

學習筆記—C++—模板初階

目錄 模板初階 泛型編程 函數模板 模版概念 函數模版格式 模版的原理 函數模板的實例化 模版參數的匹配規則 類模板 模板初階 泛型編程 使用函數重載雖然可以實現&#xff0c;但是有一下幾個不好的地方&#xff1a; 1. 重載的函數僅僅是類型不同&#xff0c;代碼復…

Docker 中多個容器之間的通信

在 Docker 中&#xff0c;多個容器之間的通信可以通過以下幾種主要方式實現&#xff0c;具體選擇取決于網絡需求、隔離性及管理復雜度&#xff1a; 一、自定義 Bridge 網絡&#xff08;推薦&#xff09; 通過創建自定義的 Docker 網絡&#xff0c;容器可以加入同一網絡并通過容…

Day1-初次接觸UFS

經過導師初次介紹&#xff0c;了解工作以芯片測試為主&#xff0c;需堅持學習&#xff0c;小白大致需3-6月入門。整體學習應分為3大塊&#xff0c;UFS協議占40%&#xff08;3-4h&#xff09;,C技能占40%&#xff08;3-4h&#xff09;,工具或業務占20%&#xff08;1-2h&#xff…