【CC2530 教程 十二】CC2530 Z-Stack 硬件抽象層

目錄

一、硬件抽象層簡介:

(1)HAL 硬件抽象層是什么?

(2)通俗易懂的解釋:

(3)具體例子:

二、硬件抽象層HAL:

(1)HAL文件目錄及工程結構:

(2)工程結構說明:

(3)HAL文件使用:


一、硬件抽象層簡介:

(1)HAL 硬件抽象層是什么?

????????硬件抽象層(Hardware Abstraction Layer,簡稱 HAL) 是一種軟件設計模式,它的目的是將硬件的具體實現細節與軟件的其他部分隔離開來。簡單來說,HAL 就像是一個中間層,它站在軟件和硬件之間,讓軟件可以通過統一的接口來操作不同的硬件,而不需要關心硬件的具體實現細節。

(2)通俗易懂的解釋:

????????想象一下,你是一個廚師,你需要用不同的廚具來烹飪食物。如果你每次都要直接操作各種各樣的鍋、碗、瓢、盆,可能會很麻煩,尤其是當廚具的種類和品牌不同時。于是,你決定用一套統一的工具來操作這些廚具,比如用一個通用的鍋鏟來翻炒,用一個通用的勺子來攪拌。這樣,你就不需要記住每種廚具的具體操作方法,只需要掌握通用工具的使用方法即可。

????????在嵌入式系統中,HAL 就像是這套通用工具。它提供了一組統一的函數接口,讓軟件開發者可以通過這些接口來操作硬件,而不需要直接處理硬件的復雜細節。比如,你要控制一個 LED 燈亮起,你可以通過 HAL 提供的函數來實現,而不需要直接操作硬件寄存器。

(3)具體例子:

????????假設你有一個開發板,上面有多種硬件設備,比如 LED 燈、按鍵、串口等。如果沒有 HAL,你可能需要直接操作每個硬件設備的寄存器來控制它們,這會非常復雜,尤其是當硬件設備的類型和型號不同時。有了 HAL,你可以通過調用 HAL 提供的函數來控制這些設備,比如:

// 通過 HAL 函數點亮 LED 燈
HAL_LED_On(LED1);// 通過 HAL 函數讀取按鍵狀態
uint8_t keyState = HAL_KEY_Read(KEY1);

????????這些函數內部已經封裝了對硬件寄存器的操作,你只需要調用這些函數即可,不需要關心硬件的具體實現。

二、硬件抽象層HAL:

(1)HAL文件目錄及工程結構:

HAL的文件位于 C:\Texas Instruments\Z-Stack 3.0.2\Components\hal 文件夾中。

進入 HAL 文件,如下:

其中:

組名稱說明
common存放公共文件。
include存放驅動程序接口文件。
target存放各種類型主板的驅動程序源文件。

打開這三個文件夾,有:

文件名說明
hal_assert.c實現條件合法性判斷功能的源代碼文件。
hal_drivers.c硬件抽象層 HAL 任務初始化及事件處理函數所在文件,是 HAL 的入口源文件。

文件名說明
hal_adc.hADC(模擬數字轉換)驅動程序頭文件。
hal_assert.h條件合法性判斷功能的頭文件。
hal_board.h各種類型主板的硬件資源配置頭文件。
hal_defs.h通用定義頭文件。
hal_drivers.hHAL任務初始化及事件處理函數的頭文件。
hal_flash.hFLASH(存儲器)驅動程序頭文件。
hal_key.h按鍵驅動程序頭文件。
hal_lcd.h顯示屏驅動程序頭文件。
hal_led.hLED驅動程序頭文件。
hal_rpc.hRPC(Remote Procedure Call,遠程過程調用)驅動程序頭文件。
hal_sleep.h休眠功能驅動程序頭文件。
hal_timer.h定時器驅動程序頭文件。
hal_uart.h串口驅動程序頭文件。

文件夾名稱說明
CC2530EB針對芯片主控為CC2530的評估板相關的驅動程序。
CC2530USB針對芯片主控為CC2530的帶USB轉串口評估板的驅動程序。
CC2530ZNP針對芯片主控為CC2530的ZNP(ZigBee And Processor)評估板的驅動程序。
CC2538針對芯片主控為CC2538的評估板的驅動程序。
CC2538ZNP針對芯片主控為CC2538的ZNP(ZigBee And Processor)評估板的驅動程序。

?以第一個為例,打開CC2530EB有:

對應類型主板的接口源文件和程序驅動源文件。

文件名作用說明
hal_uart_dma.c實現串口通信的直接內存訪問(DMA)功能,用于高效的數據傳輸。
hal_uart_isr.c包含串口通信的中斷服務例程(ISR),處理串口的中斷事件。
hal_adc.c提供模數轉換(ADC)功能的實現,用于采集模擬信號并轉換為數字數據。
hal_aes.c提供高級加密標準(AES)加密算法的實現,用于數據加密和解密操作。
hal_board_cfg.h包含評估板硬件配置的宏定義和配置參數,用于適配具體的硬件平臺。
hal_ccm.h提供CCM(Counter with CBC-MAC)加密模式的相關定義和函數聲明。
hal_dma.c實現直接內存訪問(DMA)功能,用于在不同內存區域或外設之間直接傳輸數據。
hal_dma.h提供DMA功能的函數聲明和相關宏定義,用于配置和控制DMA操作。
hal_flash.c提供對存儲器(FLASH)的操作函數,包括讀取、寫入和擦除等操作。
hal_key.c實現按鍵輸入的相關功能,包括按鍵掃描和狀態檢測。
hal_lcd.c提供液晶顯示屏(LCD)的驅動函數,用于顯示字符或圖形。
hal_led.c實現LED控制功能,包括點亮、熄滅和閃爍等操作。
hal_led_cfg.h包含LED配置的宏定義,如LED引腳定義和初始狀態設置。
hal_mac_cfg.h包含MAC層配置的宏定義,用于設置無線通信的相關參數。
hal_mcu.h提供微控制器(MCU)相關的函數聲明和宏定義,如時鐘配置和復位操作。
hal_oad.c實現無線固件更新(Over-the-Air Download,OAD)功能的源代碼。
hal_oad.h提供OAD功能的函數聲明和相關宏定義,用于無線固件更新操作。
hal_ota.c提供OTA(Over-the-Air)升級功能的實現,用于遠程更新設備固件。
hal_ota.h包含OTA功能的函數聲明和相關定義,用于支持遠程固件升級。
hal_sleep.c實現低功耗睡眠模式的相關功能,用于節能操作。
hal_startup.c包含系統啟動相關的代碼,如初始化和主函數入口等。
hal_timer.c提供定時器功能的實現,用于精確的時間控制和延遲操作。
hal_types.h定義常用的類型和數據結構,為其他模塊提供統一的數據類型聲明。
hal_uart.c實現串口通信的基本功能,包括數據發送和接收操作。

(2)工程結構說明:

打開 Z-Stack 中的一個示例工程:

?打開HAL目錄,分別展開Common、Include和Target目錄如下:

文件夾路徑作用說明
HAL/Common存放公共文件,包含通用函數實現和工具代碼,可在不同項目和硬件平臺上復用。
HAL/Include存放各種驅動程序的接口文件,定義函數原型、數據結構和宏等,供其他模塊調用和配置。
HAL/Target存放針對特定類型主板的驅動程序源文件和配置文件,每個子文件夾對應不同的硬件平臺。
HAL/Target/CC2530EB針對主控芯片為CC2530的評估板,包含該平臺下的驅動實現和配置文件。
HAL/Target/CC2530USB針對帶USB轉串口的CC2530評估板,包含該平臺下的驅動實現和配置文件。
HAL/Target/CC2530ZNP針對CC2530的ZNP評估板,包含該平臺下的驅動實現和配置文件。
HAL/Target/CC2538針對主控芯片為CC2538的評估板,包含該平臺下的驅動實現和配置文件。
HAL/Target/CC2538ZNP針對CC2538的ZNP評估板,包含該平臺下的驅動實現和配置文件。

(3)HAL文件使用:

初始化函數:

HAL中的初始化函數位于hal_drivers.c文件為Hal_Init(),如下:

/*************************************************************************************************** @fn      Hal_Init** @brief   Hal初始化函數。** @param   task_id - Hal TaskId** @return  None**************************************************************************************************/
void Hal_Init( uint8 task_id )
{/*注冊任務ID */Hal_TaskID = task_id;#ifdef CC2591_COMPRESSION_WORKAROUNDosal_start_reload_timer( Hal_TaskID, PERIOD_RSSI_RESET_EVT, PERIOD_RSSI_RESET_TIMEOUT );
#endif
}

驅動程序初始化:

HAL中的驅動程序初始化函數位于hal_drivers.c文件為HalDriverInit(),如下:

/*************************************************************************************************** @fn      Hal_DriverInit** @brief   初始化硬件(HW)- 這些需要在任何人之前初始化。*          該函數負責按正確的順序初始化各個硬件模塊,確保系統正常運行。** @param   task_id - Hal TaskId(任務ID),用于標識HAL相關的任務或事件。** @return  None**************************************************************************************************/
void HalDriverInit(void)
{/* TIMER(定時器)*/
#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)// 如果定義了HAL_TIMER且其值為TRUE,則初始化定時器模塊// 定時器模塊用于提供精確的時間控制和延遲功能
#endif/* ADC(模數轉換)*/
#if (defined HAL_ADC) && (HAL_ADC == TRUE)// 如果定義了HAL_ADC且其值為TRUE,則初始化ADC模塊// ADC模塊用于將模擬信號轉換為數字信號HalAdcInit();
#endif/* DMA(直接內存訪問)*/
#if (defined HAL_DMA) && (HAL_DMA == TRUE)// 如果定義了HAL_DMA且其值為TRUE,則初始化DMA模塊// DMA模塊允許在外設和內存之間直接傳輸數據,而無需CPU干預,提高效率// 必須在調用任何使用DMA模塊的初始化函數之前調用此函數HalDmaInit();
#endif/* AES(高級加密標準)*/
#if (defined HAL_AES) && (HAL_AES == TRUE)// 如果定義了HAL_AES且其值為TRUE,則初始化AES模塊// AES模塊用于數據加密和解密操作HalAesInit();
#endif/* LCD(液晶顯示屏)*/
#if (defined HAL_LCD) && (HAL_LCD == TRUE)// 如果定義了HAL_LCD且其值為TRUE,則初始化LCD模塊// LCD模塊用于顯示字符或圖形HalLcdInit();
#endif/* LED(發光二極管)*/
#if (defined HAL_LED) && (HAL_LED == TRUE)// 如果定義了HAL_LED且其值為TRUE,則初始化LED模塊// LED模塊用于控制LED的點亮、熄滅和閃爍等操作HalLedInit();
#endif/* UART(通用異步收發傳輸器)*/
#if (defined HAL_UART) && (HAL_UART == TRUE)// 如果定義了HAL_UART且其值為TRUE,則初始化UART模塊// UART模塊用于串行通信,實現數據的發送和接收HalUARTInit();
#endif/* KEY(按鍵)*/
#if (defined HAL_KEY) && (HAL_KEY == TRUE)// 如果定義了HAL_KEY且其值為TRUE,則初始化按鍵模塊// 按鍵模塊用于檢測按鍵輸入和處理按鍵事件HalKeyInit();
#endif/* SPI(串行外設接口)*/
#if (defined HAL_SPI) && (HAL_SPI == TRUE)// 如果定義了HAL_SPI且其值為TRUE,則初始化SPI模塊// SPI模塊用于與外部設備進行高速串行通信HalSpiInit();
#endif/* HID(人機接口設備)*/
#if (defined HAL_HID) && (HAL_HID == TRUE)// 如果定義了HAL_HID且其值為TRUE,則初始化HID模塊// HID模塊用于與人機接口設備(如鍵盤、鼠標等)進行通信usbHidInit();
#endif
}

????????在開發過程中可以需求來使用指定的外設,例如設置 HAL_TIMER = TRUE、HAL_ADC = TRUE、HAL_DMA = TRUE、HAL_AES =?TRUE、HAL_LCD = TRUE、HAL_LED =?TRUE、HAL_UART =?TRUE 等等,指定對應的外設對應的宏。如果不用用到,那么就不用定義。在定義了對應的宏后就會執行對應的初始化。如果需要增加這里沒有的外設,可以按照協議棧的這個架構新增外設。

事件處理:

????????HAL的事件處理函數為位于hal_drivers.c文件中的Hal_ProcessEvent(),它的主要作用是處理HAL層的事件,位置如下:

/*************************************************************************************************** @fn      Hal_ProcessEvent** @brief   處理 HAL 相關的事件。*          該函數根據傳入的事件標志,調用相應的處理函數或執行特定的操作。** @param   task_id - Hal TaskId(任務ID),用于標識HAL相關的任務。*          events - 需要處理的事件標志,每個標志代表一種特定的事件。** @return  返回未處理的事件標志。**************************************************************************************************/
uint16 Hal_ProcessEvent(uint8 task_id, uint16 events)
{uint8 *msgPtr;  // 用于接收消息的指針(void)task_id;  // 有意未引用的參數,避免編譯器警告// 檢查是否有系統消息事件if (events & SYS_EVENT_MSG){msgPtr = osal_msg_receive(Hal_TaskID);  // 接收消息while (msgPtr){/* 在這里做些事情 - 目前,只是釋放消息并繼續 *//* 釋放消息內存 */osal_msg_deallocate(msgPtr);/* 接收下一條消息 */msgPtr = osal_msg_receive(Hal_TaskID);}// 清除 SYS_EVENT_MSG 事件標志,表示該事件已處理return events ^ SYS_EVENT_MSG;}#if (defined HAL_BUZZER) && (HAL_BUZZER == TRUE)// 檢查是否有蜂鳴器事件if (events & HAL_BUZZER_EVENT){HalBuzzerStop();  // 停止蜂鳴器// 清除 HAL_BUZZER_EVENT 事件標志,表示該事件已處理return events ^ HAL_BUZZER_EVENT;}
#endif#ifdef CC2591_COMPRESSION_WORKAROUND// 檢查是否有周期性 RSSI 重置事件if (events & PERIOD_RSSI_RESET_EVT){macRxResetRssi();  // 重置 RSSI// 清除 PERIOD_RSSI_RESET_EVT 事件標志,表示該事件已處理return (events ^ PERIOD_RSSI_RESET_EVT);}
#endif// 檢查是否有 LED 閃爍事件if (events & HAL_LED_BLINK_EVENT){
#if (defined (BLINK_LEDS)) && (HAL_LED == TRUE)HalLedUpdate();  // 更新 LED 狀態
#endif /* BLINK_LEDS && HAL_LED */// 清除 HAL_LED_BLINK_EVENT 事件標志,表示該事件已處理return events ^ HAL_LED_BLINK_EVENT;}// 檢查是否有按鍵事件if (events & HAL_KEY_EVENT){
#if (defined HAL_KEY) && (HAL_KEY == TRUE)/* 檢查按鍵狀態 */HalKeyPoll();/* 如果中斷已禁用,則安排下一次輪詢 */if (!Hal_KeyIntEnable){osal_start_timerEx(Hal_TaskID, HAL_KEY_EVENT, 100);}
#endif// 清除 HAL_KEY_EVENT 事件標志,表示該事件已處理return events ^ HAL_KEY_EVENT;}#if defined POWER_SAVING// 檢查是否有睡眠定時器事件if (events & HAL_SLEEP_TIMER_EVENT){halRestoreSleepLevel();  // 恢復睡眠級別// 清除 HAL_SLEEP_TIMER_EVENT 事件標志,表示該事件已處理return events ^ HAL_SLEEP_TIMER_EVENT;}// 檢查是否有電源管理保持事件if (events & HAL_PWRMGR_HOLD_EVENT){(void)osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_HOLD);(void)osal_stop_timerEx(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);(void)osal_clear_event(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);// 清除 HAL_PWRMGR_HOLD_EVENT 和 HAL_PWRMGR_CONSERVE_EVENT 事件標志return (events & ~(HAL_PWRMGR_HOLD_EVENT | HAL_PWRMGR_CONSERVE_EVENT));}// 檢查是否有電源管理節能事件if (events & HAL_PWRMGR_CONSERVE_EVENT){(void)osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_CONSERVE);// 清除 HAL_PWRMGR_CONSERVE_EVENT 事件標志,表示該事件已處理return events ^ HAL_PWRMGR_CONSERVE_EVENT;}
#endif// 如果沒有處理任何事件,返回 0return 0;
}

HAL輪詢:

??HAL的HAL輪詢函數為位于hal_drivers.c文件中的Hal_ProcessPoll(),它的主要作用為輪詢那些不支持中斷或者需要定期檢查狀態的硬件模塊,位置如下:

/*************************************************************************************************** @fn      Hal_ProcessPoll** @brief   該例程將被OSAL調用來輪詢UART、TIMER等硬件模塊的狀態。*          主要用于輪詢那些不支持中斷或者需要定期檢查狀態的硬件模塊。** @param   task_id - Hal TaskId(任務ID),用于標識HAL相關的任務。** @return  None**************************************************************************************************/
void Hal_ProcessPoll()
{
#if defined(POWER_SAVING)/* 允許在下一個OSAL事件循環之前進入睡眠模式 *//* 這個宏可能用于節能模式,允許系統在空閑時進入低功耗狀態 */ALLOW_SLEEP_MODE();
#endif/* UART輪詢 */
#if (defined HAL_UART) && (HAL_UART == TRUE)/* 如果定義了HAL_UART且其值為TRUE,則調用HalUARTPoll函數輪詢UART狀態 *//* UART輪詢用于檢查串口通信的狀態,如是否有數據可讀取或發送緩沖區是否為空 */HalUARTPoll();
#endif/* SPI輪詢 */
#if (defined HAL_SPI) && (HAL_SPI == TRUE)/* 如果定義了HAL_SPI且其值為TRUE,則調用HalSpiPoll函數輪詢SPI狀態 *//* SPI輪詢用于檢查SPI通信的狀態,如是否有數據傳輸完成或是否有錯誤發生 */HalSpiPoll();
#endif/* HID輪詢 */
#if (defined HAL_HID) && (HAL_HID == TRUE)/* 如果定義了HAL_HID且其值為TRUE,則調用usbHidProcessEvents函數處理HID事件 *//* HID輪詢用于處理人機接口設備(如鍵盤、鼠標等)的事件,如按鍵按下或移動事件 */usbHidProcessEvents();
#endif
}

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

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

相關文章

Linux如何判斷磁盤是否已分區?

在 Linux 系統中,判斷磁盤是否已分區可通過以下方法實現: 方法 1:使用 fdisk -l 命令 此命令會列出所有磁盤及其分區的詳細信息: sudo fdisk -l輸出解讀: 若磁盤(如 /dev/sdb)下有類似 /dev/…

《熔化焊接與熱切割作業》考試注意事項

考試前的準備 攜帶必要的證件和材料:考生需攜帶身份證、準考證等有效證件,以及考試所需的焊接工具、材料等。確保證件齊全,避免因證件問題影響考試。 提前檢查焊接設備和工具:在考試前,考生應仔細檢查焊接設備和工具是…

Matlab Hessian矩陣計算(LoG算子)

文章目錄 一、簡介二、實現代碼三、實現效果參考資料一、簡介 圖像的Hessian矩陣用于描述圖像灰度值的二階導數,可以用來分析圖像的局部曲率和變化。例如,在圖像邊緣檢測、特征點檢測等任務中,Hessian矩陣能幫助我們識別圖像的結構。 Hessian矩陣定義 對于二維圖像,Hessian…

selenium之處理彈框(alert、confirm、prompt)

彈框 WebDriver提供了一個API, 用于處理JavaScript提供的三種類型的原生彈窗消息. 這些彈窗由瀏覽器提供限定的樣式.;分別為以下三種 alerts警告框confirm確認框prompt提示框 話不多說,開始實踐下就知道怎么一回事了 alerts 警告框,顯示…

Visual Studio 2019 Qt QML 項目環境搭建常見問題處理方法

在 Visual Studio 2019 運行 Qt/QML 項目比直接使用QtCreator環境麻煩,主要是有qmake 的一些配置項不能在 Visual Studio中設置。下面整理一些常見問題的處理方法,供參考: 搭建VS Qt 環境,在Visual Studios 2019下面安裝 Qt Vis…

【Linux】POSIX信號量與基于環形隊列的生產消費者模型

目錄 一、POSIX信號量: 接口: 二、基于環形隊列的生產消費者模型 環形隊列: 單生產單消費實現代碼: RingQueue.hpp: main.cc: 多生產多消費實現代碼: RingQueue.hpp: main.…

RAG優化:python從零實現GraphRag 一場文檔與知識的“戀愛”之旅

嘿,親愛的算法工程師們,準備好迎接一場文檔與知識的“戀愛”之旅了嗎?今天我們要介紹的 Graph RAG,就像是一位“紅娘”,幫助文檔和知識在圖的世界里找到彼此,擦出智慧的火花! 文章目錄 為什么需要 Graph RAG?Graph RAG 的“戀愛秘籍”準備好了嗎?讓我們開始吧!環境設…

深入 SVG:矢量圖形、濾鏡與動態交互開發指南

1.SVG 詳細介紹 SVG(Scalable Vector Graphics) 是一種基于 XML 的矢量圖形格式,用于描述二維圖形。 1. 命名空間 (Namespace) ★ 了解 命名空間 URI:http://www.w3.org/2000/svg 用途:在 XML 或 XHTML 中區分不同標…

HTTPS 加密過程詳解

HTTPS 的核心組成是 HTTP 協議與 SSL/TLS 加密層的結合,通過加密傳輸、身份驗證和完整性校驗機制,確保數據安全。其加密過程通過以下方式保障數據的機密性、完整性和身份驗證: 一、HTTPS 的核心組成 1. HTTP 協議 作為基礎通信協議&#xf…

嵌入式硬件工程師從小白到入門-速通版(一)

嵌入式硬件工程師從小白到入門:知識點速通與實戰指南 一、基礎硬件知識體系 電子電路基礎 基本概念:電流、電壓、電阻、電容、電感等;電路分析:歐姆定律、基爾霍夫定律、戴維南定理;元器件特性:二極管、三極…

SpringBoot通過Map實現天然的策略模式

😊 作者: 一恍過去 💖 主頁: https://blog.csdn.net/zhuocailing3390 🎊 社區: Java技術棧交流 🎉 主題: SpringBoot通過Map實現天然的策略模式 ?? 創作時間: 202…

WordPress WooCommerce 本地文件包含漏洞(CVE-2025-1661)

免責聲明 僅供網絡安全研究與教育目的使用。任何人不得將本文提供的信息用于非法目的或未經授權的系統測試。作者不對任何由于使用本文信息而導致的直接或間接損害承擔責任。如涉及侵權,請及時與我們聯系,我們將盡快處理并刪除相關內容。 一:產品介紹 HUSKY – WooCommer…

matlab近似計算聯合密度分布

在 Matlab 中,當A和B是兩個序列數據時,可以通過以下步驟來近似求出A大于B的概率分布:數據準備:確保序列A和B具有相同的長度。如果長度不同,需要進行相應的處理(例如截取或插值)。計算A大于B的邏…

可視化動態表單動態表單界的天花板--Formily(阿里開源)

文章目錄 1、Formily表單介紹2、安裝依賴2.1、安裝內核庫2.2、 安裝 UI 橋接庫2.3、Formily 支持多種 UI 組件生態: 3、表單設計器3.1、核心理念3.2、安裝3.3、示例源碼 4、場景案例-登錄注冊4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、純 JSX 案例 1、Form…

NAT 實驗:多私網環境下 NAPT、Easy IP 配置及 FTP 服務公網映射

NAT基本概念 定義:網絡地址轉換(Network Address Translation,NAT)是一種將私有(保留)地址轉化為合法公網 IP 地址的轉換技術,它被廣泛應用于各種類型 Internet 接入方式和各種類型的網絡中。作…

C語言-橋接模式詳解與實踐

文章目錄 C語言橋接模式詳解與實踐1. 什么是橋接模式?2. 為什么需要橋接模式?3. 實際應用場景4. 代碼實現4.1 UML 關系圖4.2 頭文件 (display_bridge.h)4.3 實現文件 (display_bridge.c)4.4 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特點 6.…

el-table 合并單元格

vue2使用el-table合并單元格&#xff0c;包括合并行、合并列 <el-table:header-cell-style"handerMethod":span-method"arraySpanMethod"cell-click"handleCellClick":data"tableData"style"width: 100%"><el-tabl…

網絡安全之vlan實驗

在對vlan進行一定的學習之后我們來練習一個小實驗來加深理解記憶 首先是對實驗進行一個搭建 第一部分&#xff1a;給交換機配置vlan 首先是sw1 [Huawei]vlan batch 2 to 5 [Huawei]int g0/0/1 [Huawei-GigabitEthernet0/0/1]port hybrid tagged vlan 2 [Huawei-GigabitEthe…

STM32 - 在機器人、自動化領域,LL庫相比HAL優勢明顯

在機器人控制器、電機控制器等領域的開發&#xff0c;需要高實時性、精細化控制或者對代碼執行效率、占用空間有較高要求。所以&#xff0c;大家常用的HAL庫明顯不符合要求。再加上&#xff0c;我們學習一門技術&#xff0c;一定要學會掌握底層的原理。MCU開發的底層就是寄存器…

mysql中show命令的使用

在 MySQL 中&#xff0c;SHOW 命令是一個非常實用的工具&#xff0c;用于查詢數據庫元數據&#xff08;如數據庫、表、列、索引等信息&#xff09;。以下是常見的 SHOW 命令及其用法&#xff1a; 1. 顯示所有數據庫 SHOW DATABASES;列出服務器上的所有數據庫。 2. 顯示當前數據…