EtherCAT開源主站 SOEM 2.0 最新源碼在嵌入式 Linux 下的移植與編譯

EtherCAT 作為工業自動化領域的主流現場總線協議,因其高實時性和高帶寬被廣泛應用。而 SOEM(Simple Open EtherCAT Master)則是開源社區中最受歡迎的 EtherCAT 主站協議棧之一。本文將以 SOEM 2.0 最新源碼為例,詳細介紹其在嵌入式 Linux 平臺下的移植與編譯流程,并結合實際問題給出解決方案,助力開發者高效上手 EtherCAT 主站開發。


文章目錄

    • 一、SOEM 項目結構簡介
    • 二、samples 目錄下的示例程序作用
    • 三、嵌入式 Linux 下的移植與編譯流程
      • 1. 安裝交叉編譯工具鏈(如果已有非必須)
      • 2. 編寫 CMake 工具鏈文件
      • 3. 配置 CMake
      • 4. 編譯
      • 5. 可執行文件部署
    • 四、常見編譯報錯與解決方案
      • 1. 找不到 eniconv.py
    • 五、跨平臺移植建議
    • 六、移植到stm32單片機涉及的內容
      • 1、移植需要的步驟
      • 2、移植需要修改或新增的文件
      • 3、移植流程簡述
      • 4、常見移植注意事項
      • 5、移植總結
    • 參考資源

一、SOEM 項目結構簡介

github地址:https://github.com/OpenEtherCATsociety/SOEM

SOEM 項目結構清晰,便于移植和二次開發。

源碼目錄結構介紹:

soem/
├── cmake/                # CMake 構建相關腳本和工具
│   ├── AddENI.cmake
│   ├── Linux.cmake
│   ├── Windows.cmake
│   └── tools/
├── contrib/              # 貢獻的代碼,包含不同操作系統的適配層
│   ├── cmake/
│   ├── osal/             # OS Abstraction Layer(操作系統抽象層)
│   ├── oshw/             # OS Hardware Layer(硬件抽象層)
│   └── test/
├── include/              # 頭文件,主要對外接口和數據結構定義
│   └── soem/
├── osal/                 # OS Abstraction Layer 的主目錄
│   ├── linux/
│   ├── rtk/
│   ├── win32/
│   └── osal.h            # OSAL 的主頭文件
├── oshw/                 # OS Hardware Layer 的主目錄
│   ├── linux/
│   ├── rtk/
│   ├── win32/
│   └── win32/wpcap/      # Windows 下的 WinPcap 相關頭文件和庫
├── samples/              # 示例程序,演示 SOEM 的用法
│   ├── ec_sample/
│   ├── eepromtool/
│   ├── eni_test/
│   ├── eoe_test/
│   ├── firm_update/
│   ├── simple_ng/
│   └── slaveinfo/
├── scripts/              # 輔助腳本(如 ENI 文件轉換)
├── src/                  # SOEM 核心源代碼
├── CMakeLists.txt        # CMake 主構建腳本
├── CMakePresets.json     # CMake 構建預設
├── LICENSE.md            # 許可證
├── README.md             # 項目說明

主要目錄說明如下:

  • cmake/:跨平臺構建腳本,支持多操作系統和工具鏈。
  • contrib/:第三方貢獻的適配代碼,包括不同操作系統的 OSAL(操作系統抽象層)和 OSHW(硬件抽象層)。
  • include/soem/:SOEM 的公共頭文件,定義主要數據結構和 API。
  • osal/oshw/:分別為操作系統和硬件抽象層的具體實現,按平臺分類(如 linux、win32)。
  • samples/:豐富的示例程序,涵蓋 EtherCAT 主站開發的常見場景。
  • src/:SOEM 協議棧核心源代碼。
  • scripts/:實用腳本,如 ENI 文件轉換工具 eniconv.py

src目錄下為SOEM2.0核心的協議棧源碼。

各個文件的功能介紹:

文件名作用簡介主要內容說明
ec_base.cEtherCAT 基礎功能實現提供幀的發送/接收、底層數據處理等基礎操作,供其他模塊調用
ec_coe.cCoE(CANopen over EtherCAT)協議實現實現 SDO/PDO 通信、對象字典訪問、參數配置等 CANopen 協議相關功能
ec_config.cEtherCAT 網絡配置相關功能負責從站掃描、初始化、配置、分布式時鐘同步等主站自動化配置流程
ec_dc.c分布式時鐘(DC)功能實現實現主站與從站之間的高精度時鐘同步、調整和管理
ec_eoe.cEoE(Ethernet over EtherCAT)協議實現支持以太網幀在 EtherCAT 網絡中的透傳,實現以太網數據通信
ec_foe.cFoE(File over EtherCAT)協議實現支持主站與從站之間的文件傳輸,如固件升級、配置文件下發等
ec_main.cSOEM 主流程與核心控制邏輯負責主站初始化、主循環、狀態機管理,是協議棧的核心調度中心
ec_print.c調試與信息打印功能實現提供數據包、狀態、錯誤等信息的格式化輸出,便于開發調試
ec_soe.cSoE(Servo over EtherCAT)協議實現支持伺服驅動器參數訪問和控制,適用于需要 SoE 協議的 EtherCAT 設備

這些文件共同組成了 SOEM 協議棧的核心功能模塊,各自負責 EtherCAT 協議的不同部分。

二、samples 目錄下的示例程序作用

samples 目錄下每個子目錄都是一個獨立的示例程序,覆蓋了 EtherCAT 主站開發的常見需求:

  • ec_sample:基礎 EtherCAT 主站示例,適合新手快速入門。
  • eepromtool:EEPROM 操作工具,用于從站底層參數的讀寫。
  • eni_test:ENI 文件解析與測試,適合基于 ENI 文件的網絡配置。
  • eoe_test:Ethernet over EtherCAT 協議測試,實現以太網幀透傳。
  • firm_update:從站固件升級示例,適合遠程維護場景。
  • simple_ng:極簡新一代主站示例,便于快速集成。
  • slaveinfo:從站信息查詢工具,常用于調試和設備信息采集。

samples 目錄總結

samples 目錄下的每個子目錄都是一個獨立的示例程序,覆蓋了 EtherCAT 主站開發的常見場景:

  • 基礎通信(ec_sample、simple_ng)
  • 從站信息查詢(slaveinfo)
  • EEPROM 操作(eepromtool)
  • ENI 文件支持(eni_test)
  • EOE 協議(eoe_test)
  • 固件升級(firm_update)

這些示例有助于開發者快速上手 SOEM,并根據實際需求進行二次開發。

三、嵌入式 Linux 下的移植與編譯流程

1. 安裝交叉編譯工具鏈(如果已有非必須)

以 ARM 平臺為例:

sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

如果已經有了交叉編譯工具鏈,則此步驟非必須。

2. 編寫 CMake 工具鏈文件

在項目根目錄新建 toolchain-arm.cmake

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)

我的交叉編譯工具鏈toolchain.cmake文件如下:

# 交叉編譯工具鏈配置文件
# 用于嵌入式Linux系統和RISC-V MCU的交叉編譯# 設置系統名稱
set(CMAKE_SYSTEM_NAME Linux)# 設置處理器架構變量,可以通過命令行參數傳入
# 例如: cmake -DTARGET_ARCH=arm ..
if(NOT DEFINED TARGET_ARCH)set(TARGET_ARCH "arm" CACHE STRING "Target architecture (arm or riscv)")
endif()# 設置ARM工具鏈路徑
set(ARM_TOOLCHAIN_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi")
# 設置RISC-V工具鏈路徑
set(RISCV_TOOLCHAIN_PATH "/home/zh1an/tronlong/tina5.0_v1.0/rtos/lichee/rtos/tools/riscv64-elf-x86_64-20201104")# 根據目標架構設置主工具鏈
if(${TARGET_ARCH} STREQUAL "arm")# ARM Linux工具鏈配置set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-gcc)set(CMAKE_CXX_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-g++)set(CMAKE_FIND_ROOT_PATH /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/)set(CMAKE_SYSTEM_PROCESSOR arm)# 設置額外的編譯標志set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfloat-abi=hard -mfpu=neon" CACHE STRING "" FORCE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfloat-abi=hard -mfpu=neon" CACHE STRING "" FORCE)# 設置鏈接器set(CMAKE_LINKER ${CMAKE_C_COMPILER})set(CMAKE_AR ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-ar)set(CMAKE_RANLIB ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-ranlib)elseif(${TARGET_ARCH} STREQUAL "riscv")# RISC-V工具鏈配置 (C906核心)set(CMAKE_C_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-gcc)set(CMAKE_CXX_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-g++)set(CMAKE_FIND_ROOT_PATH ${RISCV_TOOLCHAIN_PATH}/riscv64-unknown-elf)set(CMAKE_SYSTEM_PROCESSOR riscv)# 設置RISC-V特定的編譯標志 (C906核心)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv64gcv0p7 -mabi=lp64d" CACHE STRING "" FORCE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gcv0p7 -mabi=lp64d" CACHE STRING "" FORCE)# 設置鏈接器set(CMAKE_LINKER ${CMAKE_C_COMPILER})set(CMAKE_AR ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ar)set(CMAKE_RANLIB ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ranlib)else()message(FATAL_ERROR "不支持的目標架構: ${TARGET_ARCH}. 請使用 'arm' 或 'riscv'")
endif()# 定義ARM工具鏈變量,供CMakeLists.txt使用
set(ARM_C_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-gcc)
set(ARM_CXX_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-g++)
set(ARM_AR ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-ar)
set(ARM_RANLIB ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-ranlib)
set(ARM_C_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")
set(ARM_CXX_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")# 定義RISC-V工具鏈變量,供CMakeLists.txt使用
set(RISCV_C_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-gcc)
set(RISCV_CXX_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-g++)
set(RISCV_AR ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ar)
set(RISCV_RANLIB ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ranlib)
set(RISCV_C_FLAGS "-march=rv64gcv0p7 -mabi=lp64d")
set(RISCV_CXX_FLAGS "-march=rv64gcv0p7 -mabi=lp64d")# 設置查找規則
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)# 禁用系統庫路徑
set(CMAKE_SKIP_RPATH TRUE)# 設置交叉編譯環境的庫和頭文件搜索路徑
set(CMAKE_SYSROOT ${CMAKE_FIND_ROOT_PATH}) 

3. 配置 CMake

mkdir build
cd build
cmake ../ -DCMAKE_TOOLCHAIN_FILE=../toolchain1.cmake   -DTARGET_ARCH=arm  -DSOEM_BUILD_SAMPLES=ON  -DENICONV=../scripts/eniconv.py -DCMAKE_INSTALL_PREFIX=${HOME}/arm_install

如在目標板上直接編譯,可省略 -DCMAKE_TOOLCHAIN_FILE

4. 編譯

make -j$(nproc)

在這里插入圖片描述

5. 可執行文件部署

編譯完成后,samples 目錄下的各示例程序會在 build/samples/xxx/ 生成對應可執行文件,拷貝到目標設備即可運行。

我編譯構建輸出的內容如下:
在這里插入圖片描述


四、常見編譯報錯與解決方案

在這里插入圖片描述
原因:CMake 沒找到 scripts/eniconv.py 腳本。因為上述構建,啟用了構建自帶的samples,其中有個ENI工具的測試(sample-eni.c)需要用到這個腳本。

解決方法:
將 scripts 目錄加入 PATH:

export PATH=$PATH:/path/to/soem/scripts

或在 CMake 配置時指定腳本路徑:

  cmake .. -DENICONV=/path/to/soem/scripts/eniconv.py

1. 找不到 eniconv.py

報錯:

Could not find ENICONV using the following names: eniconv.py

原因:CMake 沒找到 scripts/eniconv.py 腳本。

解決方法

  • scripts 目錄加入 PATH:
    export PATH=$PATH:/path/to/soem/scripts
    
  • 或在 CMake 配置時指定腳本路徑:
    cmake .. -DENICONV=/path/to/soem/scripts/eniconv.py
    

五、跨平臺移植建議

  • SOEM 2.0 結構清晰,適合嵌入式 Linux 平臺移植。
  • 編譯前務必理清依賴關系,尤其是 Python 腳本和 ENI 工具的路徑問題。
  • 遇到 CMake 報錯時,仔細檢查路徑設置和環境變量,絕大多數問題都能快速定位解決。
  • 推薦優先參考 samples 目錄下的示例程序,結合實際需求進行裁剪和二次開發。

六、移植到stm32單片機涉及的內容

將 SOEM 2.0 移植到 STM32 等嵌入式平臺,主要涉及操作系統適配硬件驅動適配編譯環境配置。下面詳細說明移植步驟和需要修改的文件:

1、移植需要的步驟

  1. 操作系統抽象層(OSAL)適配
    • SOEM 通過 OSAL 屏蔽不同操作系統的差異。你需要為 STM32 平臺實現一套 OSAL(如基于裸機、FreeRTOS、RT-Thread 等)。
  2. 硬件抽象層(OSHW)適配
    • SOEM 通過 OSHW 屏蔽不同網卡/硬件平臺的差異。你需要為 STM32 的以太網 MAC(如 RMII/GMII)實現底層收發驅動。
  3. 編譯環境與工具鏈配置
    • 配置適合 STM32 的交叉編譯工具鏈(如 arm-none-eabi-gcc)。
    • 編寫或修改 Makefile/CMakeLists.txt 以適配 STM32 工程結構。
  4. 內存與性能優化
    • 根據 STM32 的 RAM/Flash 資源,裁剪不必要的功能,優化內存分配。

2、移植需要修改或新增的文件

目錄/文件說明與操作
contrib/osal/新增 stm32/ 目錄,實現 STM32 平臺的 osal.c 和 osal_defs.h
contrib/oshw/新增 stm32/ 目錄,實現 STM32 平臺的 nicdrv.c、nicdrv.h、oshw.c、oshw.h
osal/如需全局適配,可在此新增或修改 osal.h
oshw/如需全局適配,可在此新增或修改 oshw.h
CMakeLists.txt 或 Makefile增加對 STM32 平臺的編譯選項、源文件路徑、交叉編譯工具鏈等配置
samples/可根據 STM32 資源,移植或精簡示例程序

3、移植流程簡述

  1. 實現 OSAL(操作系統抽象層)

    • 主要包括互斥鎖、延時、內存分配等函數。
    • 參考 contrib/osal/linux/contrib/osal/win32/,仿照實現 contrib/osal/stm32/
  2. 實現 OSHW(硬件抽象層)

    • 主要包括以太網幀的收發、網卡初始化等。
    • 參考 contrib/oshw/linux/contrib/oshw/win32/,仿照實現 contrib/oshw/stm32/
    • 需要調用 STM32 HAL/LL 庫的以太網驅動(如 ETH DMA、PHY 配置等)。
  3. 配置編譯環境

    • 新建適合 STM32 的 Makefile 或 CMake 工程,指定交叉編譯器和目標架構。
    • 配置頭文件和源文件路徑,確保編譯時能找到 STM32 適配的 OSAL/OSHW。
  4. 裁剪和優化

    • 移除不需要的協議模塊(如 EoE、FoE、SoE 等),只保留核心 EtherCAT 功能。
    • 優化內存分配,避免動態分配,適應 STM32 的內存限制。
  5. 移植和測試示例程序

    • 選擇 samples/simple_ngsamples/ec_sample 進行移植,作為移植驗證入口。

4、常見移植注意事項

  • STM32 以太網驅動需支持“原始幀”收發(Raw Ethernet),不能走 TCP/IP 協議棧。
  • 需保證中斷/輪詢方式下的實時性,避免丟包。
  • 可能需要移植 lwIP 的 RAW API 或直接操作 ETH HAL/LL 驅動。
  • 調試時建議先用 PC 端抓包工具(如 Wireshark)配合分析。

5、移植總結

SOEM 2.0 移植到 STM32 的主要步驟:

  1. 新增并實現 STM32 平臺的 OSAL 和 OSHW 適配層(contrib/osal/stm32/contrib/oshw/stm32/)。
  2. 配置交叉編譯環境,修改編譯腳本。
  3. 移植并測試示例程序,逐步完善和優化。

結語

SOEM 2.0 的移植和編譯并不復雜,關鍵在于理解其目錄結構和構建流程。希望本文能幫助你順利在嵌入式 Linux 平臺上部署 EtherCAT 主站應用,開啟高效、穩定的工業自動化之路!如有更多問題,歡迎留言交流。

參考資源

https://github.com/lipoyang/SOEM4Mbed
https://os.mbed.com/users/EasyCAT/code/EasyCAT_LAB/
https://openethercatsociety.github.io/doc/soes/tutorial_8txt.html

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

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

相關文章

面試150 填充每個節點的下一個右側節點指針Ⅱ

思路 采用層序遍歷的方式來連接二叉樹中同一層的節點。首先將根節點加入隊列,然后按層處理節點:每一層依次從隊列中取出節點,并將其 next 指針指向該層中的下一個節點(即隊列中的下一個節點);若是該層最后一…

Windows 本地 使用mkcert 配置HTTPS 自簽名證書

🧩 場景假設 項目本地運行或通過本地 web 服務器(如 Nginx、http-server、vite)訪問 假設域名為 myadmin.local(可以任意命名) 步驟 1:安裝 mkcert 下載 mkcert: 訪問 https://github.com/Fil…

vue3 ref vs reactive值的修改

ref vs reactive reactive 定義的響應式對象不能直接整體修改(即obj1obj2),如果想要修改,可以使用 Object.assign(obj1,obj2) 上述賦值是淺拷貝,對象地址不變,屬性值被修改了淺拷貝:創建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。如果屬性值是基本類型…

【Datawhale AI 夏令營】 用AI做帶貨視頻評論分析(一)

引言 以訊飛「基于帶貨視頻評論的用戶洞察挑戰賽」的賽事項目為背景,將電商直播帶貨視頻的碎片化用戶評論轉化為可量化的商業洞察信息。其實本質上在于利用自然語言處理、機器學習或者大模型技術,從海量的文本數據中提取有價值的商業洞察。 主要涉及以下…

Vue中的render()函數

在 Vue 中&#xff0c;render() 是一個用于手動編寫組件渲染邏輯的方法&#xff0c;它直接返回虛擬節點&#xff08;VNode&#xff09;&#xff0c;替代模板語法&#xff08;<template>&#xff09;來描述組件的 UI 結構。以下是關于 render() 方法的詳細解析&#xff1a…

板凳-------Mysql cookbook學習 (十一--------9)

13.2 分組描述統計 mysql> select age, count(score) as n,-> sum(score) as sum,-> min(score) as minimum,-> max(score) as maximum,-> avg(score) as mean,-> stddev_samp(score) as std. dev.,-> var_samp(score) as variance-> from testscore-&…

編寫產品需求文檔:黃歷日歷小程序

整理產品需求文檔&#xff1a;黃歷日歷小程序版本&#xff1a;1.0 更新時間&#xff1a;2025-7-9一、文檔概述1.1 產品背景開發一款融合傳統黃歷文化的日歷工具&#xff0c;提供每日吉兇查詢、神煞展示和個人運勢分析功能。1.2 目標用戶關注傳統歷法的中老年群體婚嫁/搬家等需要…

Spring Boot + MyBatis 實現用戶登錄功能詳解(基礎)

一、項目概述做了幾個項目發現有人問到怎么使用springbootHTMLjsCSS開發一個項目呢所以本文將介紹如何使用Spring Boot和MyBatis實現一個完整的用戶登錄功能。系統包含前端登錄頁面、后端控制器、服務層、數據訪問層以及數據庫交互。二、技術棧Spring Boot 2.xMyBatis 持久層框…

adb 簡介與常用命令

1. adb 簡介adb 的全稱為 Android Debug Bridge&#xff0c;就是起到調試橋的作用。借助 adb 工具&#xff0c;我們可以管理設備或手機模擬器的狀態。還可以進行很多手機操作&#xff0c;如安裝軟件、系統升級、運行 shell 命令等等。其實簡而言說&#xff0c;adb 就是連接 And…

阿里云-跨賬號同步OSS Bucket

說明 阿里云A賬號的OSS BUCKET同步到B賬號的指定OSS BUCKET。 賬號Bucket NamesRAM角色A{源buctket}OSS-SYNCERB{目標buctket} 步驟 在阿里云A,B賬號分別建上表buckets, 最好是相同地域的在A號-RAM控制臺建立角色OSS-SYNCER&#xff0c;并賦權AliyunOSSFullAccess&#xff…

uniapp小程序無感刷新token

request.js // request.js import {getApptoken,getStoredApptoken } from ./tokenRequest // 從合并模塊導入// 全局配置 const MAX_RETRIES 1 // 最大重試次數 const baseURL https://your-api.com// 請求隊列和刷新狀態 let requestsQueue [] let isRefreshing false// …

MySQL優化高手筆記

語雀完整版&#xff1a;https://www.yuque.com/g/mingrun/embiys/dv3btw/collaborator/join?tokenzMBwPzSMfSGINLuv&sourcedoc_collaborator# 《MySQL優化高手筆記》MySQL優化高手一、MySQL架構01 天天寫CRUD,你知道你的系統是如何跟MySQL打交道的嗎通過驅動連接數據庫&am…

Git 詳解:從概念,常用命令,版本回退到工作流

本文將從 Git 的核心概念講起&#xff0c;詳細介紹常用命令、各階段版本回退、分支控制以及企業內常見的 Git 工作流。 Git 與 GitHub 簡介 Git 簡介 Git 是一個開源的分布式版本控制系統&#xff0c;由 Linus Torvalds 于 2005 年開發。它與集中式版本控制系統&#xff08;…

CMSIS(Cortex Microcontroller Software Interface Standard)ARM公司為 Cortex-M 系列處理器

CMSIS&#xff08;Cortex Microcontroller Software Interface Standard&#xff09;是ARM公司為 Cortex-M 系列處理器&#xff08;如 M0/M3/M4/M7/M23/M33 等&#xff09;定義的一套硬件抽象層標準&#xff0c;旨在簡化嵌入式開發&#xff0c;提高代碼的可移植性和復用性。 核…

[特殊字符] 掃描式處理:Python 自動提取 PDF 中關鍵詞相關表格并導出為 Excel

本文演示如何利用 pdfplumber 批量處理指定文件夾下 PDF 文檔&#xff1a;定位關鍵詞&#xff08;如“主要會計數據”&#xff09;出現的頁碼及下一頁&#xff0c;提取其中的表格并保存為獨立 Excel 文件。適用于財務報告、審計表格、統計報表等場景。 1?? 第一步&#xff1a…

python3的返回值能返回多個嗎?

在Python中&#xff0c;函數可以通過返回一個元組&#xff08;tuple&#xff09; 來間接實現返回多個值的效果。以下是具體說明&#xff1a; 實現方式&#xff1a;直接返回逗號分隔的值 Python會自動將這些值打包成一個元組&#xff1a; def multiple_return():a 1b "he…

UE5 Secondary Materials

首先放入材質A材質B放入Secondary Materials兩個效果就能融合到一起了動態設置secondary material

AUTOSAR進階圖解==>AUTOSAR_SWS_FlashTest

AUTOSAR Flash Test模塊詳解與分析 基于AUTOSAR標準的Flash Test模塊架構、功能與應用分析目錄 1. Flash Test模塊概述 1.1 模塊作用與功能1.2 適用范圍 2. Flash Test模塊架構 2.1 模塊位置2.2 組件關系 3. 狀態管理 3.1 狀態定義3.2 狀態轉換 4. 后臺測試執行流程 4.1 測試間…

msf復現永恒之藍

永恒之藍&#xff08;EternalBlue&#xff09;是利用 Windows 系統的 SMB 協議漏洞&#xff08;MS17-010&#xff09;來獲取系統最高權限的漏洞&#xff0c;利用 Metasploit 框架&#xff08;MSF&#xff09;復現該漏洞是一個復雜且具有一定風險的操作&#xff0c;必須在合法合…

格密碼--LWE,DLWE和ss-LWE

格密碼–LWE&#xff0c;DLWE和ss-LWE 0.數學符號數學符號含義備注Zq\mathbb{Z}_qZq?模qqq的整數集合&#xff0c;即{0,1,2,...,q?1}\{0,1,2,...,q-1\}{0,1,2,...,q?1}用于定義LWE、DLWE、ss-LWE等問題中矩陣和向量的元素取值范圍&#xff0c;是基礎整數環x∈RSx \in_R Sx∈…