GD32F303 GCC 環境搭建

一、引言

在嵌入式開發領域,GD32F303 微控制器以其出色的性能和豐富的功能被廣泛應用。為了充分發揮其潛力,搭建一個高效的開發環境并深入理解項目構建過程至關重要。本文將詳細介紹如何基于 GCC 工具鏈搭建 GD32F303 的開發環境,重點聚焦于 Makefile 文件的編寫與解析,助力開發者快速上手項目開發。

二、工具鏈安裝

以下是在 Linux 系統上搭建 GCC 工具鏈的詳細步驟:

下載工具鏈

  • 使用 wget 命令從上述下載鏈接下載工具鏈(以下是一個示例,根據你選擇的版本更新 URL):
wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2

解壓工具鏈

將工具鏈解壓到 /opt 目錄下,這是一個常見的系統級軟件安裝目錄。使用以下命令進行解壓:

sudo tar -xvf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 -C /opt

配置環境變量

  • 為了能夠在命令行中方便地使用工具鏈,需要將工具鏈的 bin 目錄添加到系統的 PATH 環境變量中。你可以將以下命令添加到用戶的 .bashrc 或系統的 /etc/profile 文件中:
export PATH=$PATH:/opt/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux/bin
  • 為了使環境變量的修改立即生效,執行以下命令(如果你將上述命令添加到 .bashrc):
source ~/.bashrc

三、EmbeddedBuilder 獲取相關文件

EmbeddedBuilder 是一款基于 Eclipse 和 Java 平臺的軟件,用于開發 GD32 系列單片機。它具有圖形化界面,方便用戶進行引腳和外設的配置,并能自動生成代碼。通過EmbeddedBuilder 工具生成我們在gcc環境下所需要的文件和代碼。

官網地址及安裝步驟

EmbeddedBuilder 的官網地址為:https://gd32mcu.com/cn/download/7 。

安裝步驟如下:

  1. 安裝 JAVA 環境:在 Oracle 官網下載相應的 Java 安裝包(如 jdk-8u152-windows-x64.exe),以管理員身份運行并安裝,記住安裝路徑(如 “D:\Program Files\Java\jdk1.8.0_351”)。然后編輯系統變量,添加 JAVA_HOME 變量,并在 Path 變量中添加相關路徑,在系統變量中新建 CLASSPATH 變量。最后在 Windows+R 鍵打開的 dos 窗口中分別輸入 java 和 javac,若能正常輸出提示信息則說明配置成功。
  2. 下載 EmbeddedBuilder:從官網下載 EmbeddedBuilder 壓縮包。
  3. 解壓并運行:解壓后雙擊 “EmbeddedBuilder.exe” 打開 IDE,選擇一個路徑作為 workspace 的存放位置,確認后即可進入 IDE 頁面。|

創建GD32F303工程

  1. 創建新工程:在導航欄依次單擊 “File->New->Project…”,選擇 C Project,并在可執行文件 “Executable” 選項卡下選擇 “GigaDevice ARM C Project”,填寫項目名字后進行芯片選擇和其他配置。

  2. 導入工程:在導航欄處依次選擇 “File->Import”,在導入頁面的 General 選項卡下選擇 “Existing Projects into Workspace”,選擇原有工程的路徑,IDE 會自動檢索并列出存在的 Embedded Builder 項目,勾選需要導入的項目后單擊 Finish 即可。

    在這里插入圖片描述

獲取相關文件

  1. 官方庫:GD32F303 的官方庫提供了豐富的驅動函數和底層支持,能夠大大簡化開發過程。通過 EmbeddedBuilder 可以方便地獲取官方庫,并將其集成到項目中

  2. LD文件:LD 文件(鏈接腳本)在項目構建中起著關鍵作用,它描述了如何將各個目標文件組合成最終的可執行文件,并確定內存布局。

  3. 啟動文件:.s 文件通常包含匯編啟動代碼,是系統啟動過程的關鍵部分。

在這里插入圖片描述

GCC工程目錄構建

在項目存儲路徑下創建以下目錄結構,已將代碼遞交到gitee倉庫 https://gitee.com/myliujiuri/gd32f303_gcc

在這里插入圖片描述

四、Makefile

makefile需要我們自己來實現,以下是一個標準的 Makefile 模板,用戶可以根據實際項目情況進行修改。

# target
TARGET = app# building variables
DEBUG = 1
OPT = -Os# paths
BUILD_DIR = build# source
C_SOURCES = \
Firmware/CMSIS/GD/GD32F30x/Source/system_gd32f30x.c \
# 其他 C 源文件路徑省略C_INCLUDES =  \
-IFirmware/CMSIS \
# 其他頭文件路徑省略ASM_SOURCES =  \
Firmware/CMSIS/GD/GD32F30x/Source/GCC/startup_gd32f30x_hd.SARM_TOOCHAIN?=./Toolchain/arm-gnu-toolchain/bin# binaries
PREFIX = $(ARM_TOOCHAIN)/arm-none-eabi-
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S# CFLAGS
CPU = -mcpu=cortex-m4
FPU = 
FLOAT-ABI = 
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
AS_DEFS = 
C_DEFS =  \
-DUSE_STDPERIPH_DRIVER \
-DGD32F30X_HD
AS_INCLUDES = 
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -std=c99
ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"# LDFLAGS
LDSCRIPT = Firmware/Ld/gd32f30x_flash.ld
LIBS = -lc -lm -lnosys 
LIBDIR = 
LDFLAGS = $(MCU) -u_printf_float -specs=nosys.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -Wl,--print-memory-usage # default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin# build the application
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASM_SOURCES)))$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)$(AS) -c $(CFLAGS) $< -o $@$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile$(CC) $(OBJECTS) $(LDFLAGS) -o $@$(SZ) $@$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(HEX) $< $@$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(BIN) $< $@	$(BUILD_DIR):mkdir $@		# program
program:openocd -f /usr/share/openocd/scripts/interface/cmsis-dap.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg -c "program build/$(TARGET).elf verify reset exit"# clean up
clean:-rm -fR $(BUILD_DIR)# dependencies
-include $(wildcard $(BUILD_DIR)/*.d)

五、Makefile 詳解

目標與變量定義

  1. 目標(Target)
    • TARGET = app:定義了最終生成的可執行文件的名稱為 app。在后續的構建規則中,所有的中間文件和最終輸出文件都圍繞這個名稱展開,如 $(BUILD_DIR)/$(TARGET).elf$(BUILD_DIR)/$(TARGET).hex$(BUILD_DIR)/$(TARGET).bin 分別表示生成的 ELF 格式可執行文件、十六進制文件和二進制文件。
  2. 構建變量
    • DEBUG = 1:用于控制是否開啟調試信息。當 DEBUG 為 1 時,在 CFLAGS 中會添加調試相關的編譯選項 -g -gdwarf-2,這些選項使得生成的可執行文件包含調試符號,方便在調試器中進行源代碼級別的調試。
    • OPT = -Os:指定了優化級別為 Os,這是一種針對代碼大小的優化選項。GCC 提供了多種優化級別,如 -O0(不優化)、-O1(基本優化)、-O2(更高級別的優化)、-O3(激進的優化)等,-Os 會在保證一定性能的前提下盡量減小代碼體積,適用于資源受限的嵌入式系統。
  3. 路徑變量
    • BUILD_DIR = build:定義了構建過程中生成的中間文件和最終輸出文件的存放目錄為 build。在后續的規則中,所有的目標文件(.o 文件)、可執行文件等都會存放在這個目錄下,通過這種方式可以保持項目目錄的整潔,便于管理和清理構建產物。

源文件與頭文件路徑

  1. C 源文件(C_SOURCES)
    • 這里列出了項目中所有的 C 語言源文件路徑,包括來自固件庫(如 Firmware/CMSIS/GD/GD32F30x/Source/system_gd32f30x.c)和用戶自定義的源文件(如 User/main.c 等)。這些源文件是項目的核心代碼部分,在構建過程中會被編譯成目標文件(.o 文件),然后鏈接成最終的可執行文件。在實際項目中,隨著功能的增加,可能會不斷添加新的源文件到這個列表中。
  2. C 頭文件路徑(C_INCLUDES)
    • 定義了 C 語言源文件在編譯時所需的頭文件搜索路徑。例如 -IFirmware/CMSIS 表示編譯器會在 Firmware/CMSIS 目錄下搜索頭文件。這些頭文件包含了函數聲明、宏定義和類型定義等信息,對于源文件的正確編譯至關重要。如果頭文件路徑設置不正確,編譯器將無法找到相應的頭文件,導致編譯錯誤。

工具鏈相關定義

  1. 工具鏈路徑(ARM_TOOCHAIN)
    • ARM_TOOCHAIN?=./Toolchain/arm-gnu-toolchain/bin:指定了 ARM GNU 工具鏈的安裝路徑。這里使用了條件賦值 ?=,如果在外部沒有定義 ARM_TOOCHAIN 變量,就會使用這個默認值。工具鏈包含了編譯器(gcc)、匯編器(as)、鏈接器(ld)等工具,是將源代碼轉換為可執行文件的關鍵。
  2. 工具前綴(PREFIX)
    • PREFIX = $(ARM_TOOCHAIN)/arm-none-eabi-:定義了工具鏈中各個工具的前綴。例如,$(PREFIX)gcc 就是實際調用的 ARM 架構的 GCC 編譯器。這個前綴確保了在系統中安裝了多個工具鏈或存在不同版本工具鏈時,能夠準確地調用所需的工具。
  3. 編譯器及相關工具定義
    • 根據是否定義了 GCC_PATH 變量,分別設置了編譯器(CC)、匯編器(AS)、目標文件復制工具(CP)和文件大小查看工具(SZ)的具體路徑。如果定義了 GCC_PATH,則會在該路徑下查找工具,否則使用默認的 PREFIX 路徑下的工具。例如,CC = $(PREFIX)gcc 表示使用默認路徑下的 GCC 編譯器進行 C 語言源文件的編譯。

編譯參數(CFLAGS 和 ASFLAGS)

  1. 通用編譯參數
    • CPU = -mcpu=cortex-m4:指定了目標處理器為 Cortex-M4 內核。這是因為 GD32F303 基于 Cortex-M4 內核,編譯器需要針對這個內核進行特定的代碼生成和優化。
    • MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI):綜合了處理器設置、Thumb 指令集啟用以及浮點運算相關設置(這里 FPUFLOAT-ABI 根據實際情況可能為空或有特定設置)。-mthumb 表示啟用 Thumb 指令集,這是一種在 ARM 架構中常用的指令集模式,能夠減小代碼體積。
    • CFLAGSASFLAGS 都包含了 $(MCU)$(OPT)-Wall-fdata-sections-ffunction-sections 等參數。-Wall 啟用了所有常見的警告信息,有助于在編譯過程中發現潛在的問題。-fdata-sections-ffunction-sections 分別將數據和函數放入獨立的節區,這在鏈接階段可以實現更精細的內存管理和優化,例如可以只鏈接實際使用到的節區,減小最終可執行文件的大小。
  2. 調試相關參數
    • DEBUG = 1 時,CFLAGS += -g -gdwarf-2-g 選項開啟調試信息生成,-gdwarf-2 指定了調試信息的格式為 DWARF-2,這是一種廣泛支持的調試信息格式,使得調試器能夠正確解析源代碼和變量信息,方便開發者進行調試。
  3. 依賴信息生成參數
    • CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)":這些參數用于自動生成源文件的依賴關系信息。-MMD 表示生成依賴文件(.d 文件),-MP 會為每個依賴添加一個虛擬的目標,避免在頭文件更新時出現不必要的錯誤,-MF 則指定了依賴文件的名稱格式,其中 $(@:%.o=%.d) 表示將目標文件(.o 文件)的擴展名替換為 .d 作為依賴文件的名稱。這些依賴文件在后續的構建過程中會被 Makefile 自動包含,確保在源文件或頭文件發生變化時,能夠正確地重新編譯相關的文件。

鏈接參數(LDFLAGS)

  1. 鏈接腳本(LDSCRIPT)
    • LDSCRIPT = Firmware/Ld/gd32f30x_flash.ld:指定了鏈接腳本文件的路徑。鏈接腳本詳細描述了可執行文件的內存布局,包括代碼段、數據段在 Flash 和 RAM 中的位置和大小等信息。對于 GD32F303 項目,這個鏈接腳本需要根據芯片的內存映射進行定制,確保程序能夠正確地加載和運行。
  2. 庫文件與鏈接選項
    • LIBS = -lc -lm -lnosys:列出了鏈接過程中需要鏈接的庫文件。-lc 是 C 標準庫,-lm 是數學庫,-lnosys 通常用于提供一些系統調用的空實現,在嵌入式系統中可能不需要完整的操作系統級別的系統調用,這個庫可以提供一些基本的替代實現。
    • LDFLAGS 還包含了 -u_printf_float-specs=nosys.specs-Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -Wl,--print-memory-usage 等參數。-u_printf_float 確保鏈接器在鏈接時包含浮點格式的 printf 函數。-specs=nosys.specs 指定了鏈接器的規范文件,用于調整鏈接行為。-Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref 會生成一個鏈接映射文件,該文件詳細展示了可執行文件中各個節區的內存地址分配、符號引用等信息,方便開發者分析程序的內存布局。-Wl,--gc-sections 啟用了鏈接器的垃圾回收功能,會刪除未使用的節區,進一步減小可執行文件的大小。-Wl,--print-memory-usage 則會在鏈接過程中輸出內存使用情況的統計信息,幫助開發者了解程序的內存占用情況。

構建規則

  1. 目標文件生成規則

    • $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR):這兩條規則分別定義了如何從 C 源文件和匯編源文件生成目標文件(.o 文件)。對于 C 源文件,使用 $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ 命令進行編譯。其中 $(CC) 是前面定義的 C 編譯器,-c 表示只進行編譯不進行鏈接,$(CFLAGS) 是編譯選項,-Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) 是傳遞給匯編器的選項,用于生成匯編列表文件(.lst 文件),$< 表示第一個依賴文件(即源文件),$@ 表示目標文件。對于匯編源文件,使用 $(AS) -c $(CFLAGS) $< -o $@ 進行編譯,其中 $(AS) 是匯編器,過程類似。
  2. 可執行文件生成規則

    • $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile:這條規則定義了如何從所有的目標文件生成最終的 ELF 格式可執行文件。使用 $(CC) $(OBJECTS) $(LDFLAGS) -o 命令進行鏈接,其中(CC) 是編譯器,是前面生成的所有目標文件列表,(LDFLAGS) 是鏈接選項,表示目標文件(即(BUILD_DIR)/)。鏈接完成后,還使用(SZ) 命令查看生成的可執行文件的大小信息,這里(SZ) 是前面定義的文件大小查看工具。
      \3. 十六進制和二進制文件生成規則

      • $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR):這兩條規則分別定義了如何從 ELF 格式可執行文件生成十六進制文件和二進制文件。對于十六進制文件,使用 $(HEX) $< $@ 命令,其中 $(HEX) 是前面定義的目標文件轉換工具,$< 表示輸入文件(即 ELF 文件),$@ 表示目標文件(即十六進制文件)。對于二進制文件,使用 $(BIN) $< $@ 命令,過程類似。
      1. 目錄創建規則
        • $(BUILD_DIR)::這條規則定義了如何創建構建目錄 $(BUILD_DIR)。使用 mkdir $@ 命令創建目錄,如果目錄已經存在,該命令不會產生錯誤。這個目錄在構建過程中用于存放中間文件和最終輸出文件,確保項目目錄結構的清晰。

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

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

相關文章

【C++】詳細講解繼承(下)

本篇來繼續說說繼承。上篇可移步至【C】詳細講解繼承&#xff08;上&#xff09; 1.繼承與友元 友元關系不能繼承 &#xff0c;也就是說基類友元不能訪問派?類私有和保護成員。 class Student;//前置聲明class Same //基類 { public:friend void Fun(const Same& p, con…

考研機試題:今年的第幾天

描述 輸入年、月、日&#xff0c;計算該天是本年的第幾天。 輸入描述: 包括三個整數年(1<Y<3000)、月(1<M<12)、日(1<D<31)。 輸出描述: 輸入可能有多組測試數據&#xff0c;對于每一組測試數據&#xff0c; 輸出一個整數&#xff0c;代表Input中的年、…

解鎖羅技鍵盤新技能:輕松鎖定功能鍵(羅技K580)

在使用羅技鍵盤的過程中&#xff0c;你是否曾因 F11、F12 功能鍵的默認設置與實際需求不符而感到困擾&#xff1f; 別擔心&#xff0c;今天就為大家分享一個簡單實用的小技巧 —— 鎖定羅技鍵盤的 F11、F12 功能鍵&#xff0c;讓你的操作更加得心應手&#xff01; 通常情況下…

Flink把kafa數據寫入Doris的N種方法及對比。

用Flink+Doris來開發實時數倉,首要解決是如何接入kafka實時流,下面是參考Doris官方文檔和代碼,在自己項目開發的實踐中總結,包括一些容易踩坑的細節。 目錄 Routine Load方法 接入kafka實時數據 踩坑的問題細節 Flink Doris Connector方法 完整示例 Routine Load方法…

小識JVM堆內存管理的優化機制TLAB

JVM&#xff08;Java虛擬機&#xff09;在堆內存分配空間時&#xff0c;TLAB&#xff08;Thread Local Allocation Buffer&#xff0c;線程本地分配緩存區&#xff09;是一種重要的內存管理優化技術。以下是對TLAB的詳細解釋&#xff1a; 一、TLAB的定義 TLAB是JVM堆內存管理…

(開源)基于Django+Yolov8+Tensorflow的智能鳥類識別平臺

1 項目簡介&#xff08;開源地址在文章結尾&#xff09; 系統旨在為了幫助鳥類愛好者、學者、動物保護協會等群體更好的了解和保護鳥類動物。用戶群體可以通過平臺采集野外鳥類的保護動物照片和視頻&#xff0c;甄別分類、實況分析鳥類保護動物&#xff0c;與全世界各地的用戶&…

【力扣Hot 100】普通數組2

3. 輪轉數組 給定一個整數數組 nums&#xff0c;將數組中的元素向右輪轉 k **個位置&#xff0c;其中 k **是非負數。 示例 1: 輸入: nums [1,2,3,4,5,6,7], k 3 輸出:[5,6,7,1,2,3,4]解釋: 向右輪轉 1 步:[7,1,2,3,4,5,6] 向右輪轉 2 步:[6,7,1,2,3,4,5] 向右輪轉 3 步:[…

專題三_窮舉vs暴搜vs深搜vs回溯vs剪枝_全排列

dfs解決 全排列&子集 1.全排列 link:46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 全局變量回溯 code class Solution { public:vector<vector<int>> ans;vector<int> cur;vector<bool> used;vector<vector<int>> permute…

2_高并發內存池_各層級的框架設計及ThreadCache(線程緩存)申請內存設計

一、高并發內存池框架設計 高并發池框架設計&#xff0c;特別是針對內存池的設計&#xff0c;需要充分考慮多線程環境下&#xff1a; 性能問題鎖競爭問題內存碎片問題 高并發內存池的整體框架設計旨在提高內存的申請和釋放效率&#xff0c;減少鎖競爭和內存碎片。 高并發內存…

JAVA 使用反射比較對象屬性的變化,記錄修改日志。使用注解【策略模式】,來進行不同屬性枚舉值到中英文描述的切換,支持前端國際化。

1.首先定義一個接口&#xff0c;接口中有兩個方法&#xff0c;分別是將屬性轉換成英文描述和中文描述。 其實就是將數據庫中記錄的 0 1 &#xff0c;轉換成后面的描述 這邊定義了中文轉換為默認方法&#xff0c;是因為有些屬性不需要進行中文轉換&#xff0c;或者該屬性的枚舉…

webrtc入門系列(五)amazon-kinesis-video-streams-webrtc-sdk-c編譯

《webrtc入門系列&#xff08;一&#xff09;easy_webrtc_server 入門環境搭建》 《webrtc入門系列&#xff08;二&#xff09;easy_webrtc_server 入門example測試》 《webrtc入門系列&#xff08;三&#xff09;云服務器coturn環境搭建》 《webrtc入門系列&#xff08;四&…

AIGC大模型詳解(ChatGPT,Cursor,豆包,文心一格)

定義與概念 AIGC&#xff08;AI Generated Content&#xff09;大模型是基于人工智能技術&#xff0c;具有海量參數、強大算力支持&#xff0c;能處理和生成多種類型內容的深度學習模型。可自主學習數據中的模式和規律&#xff0c;生成文本、圖像、音頻等內容&#xff0c;如Ch…

.NET9增強OpenAPI規范,不再內置swagger

ASP.NETCore in .NET 9.0 OpenAPI官方文檔ASP.NET Core API 應用中的 OpenAPI 支持概述 | Microsoft Learnhttps://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/openapi/overview?viewaspnetcore-9.0https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/ope…

第38周:貓狗識別 (Tensorflow實戰第八周)

目錄 前言 一、前期工作 1.1 設置GPU 1.2 導入數據 輸出 二、數據預處理 2.1 加載數據 2.2 再次檢查數據 2.3 配置數據集 2.4 可視化數據 三、構建VGG-16網絡 3.1 VGG-16網絡介紹 3.2 搭建VGG-16模型 四、編譯 五、訓練模型 六、模型評估 七、預測 總結 前言…

我的2024年年度總結

序言 在前不久&#xff08;應該是上周&#xff09;的博客之星入圍賽中鎩羽而歸了。雖然心中頗為不甘&#xff0c;覺得這一年兢兢業業&#xff0c;每天都在發文章&#xff0c;不應該是這樣的結果&#xff08;連前300名都進不了&#xff09;。但人不能總抱怨&#xff0c;總要向前…

Trimble三維激光掃描-地下公共設施維護的新途徑【滬敖3D】

三維激光掃描技術生成了復雜隧道網絡的高度詳細的三維模型 項目背景 紐約州北部的地下通道網絡已有100年歷史&#xff0c;其中包含供暖系統、電線和其他公用設施&#xff0c;現在已經開始顯露出老化跡象。由于安全原因&#xff0c;第三方的進入受到限制&#xff0c;在沒有現成紙…

QT 中 UDP 的使用

目錄 一、UDP 簡介 二、QT 中 UDP 編程的基本步驟 &#xff08;一&#xff09;包含頭文件 &#xff08;二&#xff09;創建 UDP 套接字對象 &#xff08;三&#xff09;綁定端口 &#xff08;四&#xff09;發送數據 &#xff08;五&#xff09;接收數據 三、完整示例代…

開源鴻蒙開發者社區記錄

lava鴻蒙社區可提問 Laval社區 開源鴻蒙項目 OpenHarmony 開源鴻蒙開發者論壇 OpenHarmony 開源鴻蒙開發者論壇

Git上傳了秘鑰如何徹底修改包括歷史記錄【從安裝到實戰詳細版】

使用 BFG Repo-Cleaner 清除 Git 倉庫中的敏感信息 1. 背景介紹 在使用 Git 進行版本控制時&#xff0c;有時會不小心將敏感信息&#xff08;如 API 密鑰、密碼等&#xff09;提交到倉庫中。即使后續刪除&#xff0c;這些信息仍然存在于 Git 的歷史記錄中。本文將介紹如何使用…

多層 RNN原理以及實現

數學原理 多層 RNN 的核心思想是堆疊多個 RNN 層&#xff0c;每一層的輸出作為下一層的輸入&#xff0c;從而逐層提取更高層次的抽象特征。 1. 單層 RNN 的數學表示 首先&#xff0c;單層 RNN 的計算過程如下。對于一個時間步 t t t&#xff0c;單層 RNN 的隱藏狀態 h t h_t…