【esp32s3】2 - 第一個組件

下面的內容編寫時間跨度有點大,亂了得一團,也沒ai整理。食之無味,棄之可惜。

推薦筆記:ESP32 之 ESP-IDF 教學(十八)—— 組件配置(KConfig)
推薦筆記:Kconfig 拓展
樂鑫組件庫,網頁在線。

一、準備工程

  • 先重新弄一個工程,也算是復習一下上一節課的內容。這次換一種方式創建。

在這里插入圖片描述

  • 選擇模板

在這里插入圖片描述

  • 最后結果如下圖. 編譯下載監聽調試都沒有問題。再開始下一步。

在這里插入圖片描述

二、添加或創建組件

1) 添加組件

  • 樂鑫官方有一個在線庫,可以方便 添加組件 ,使用以下指令打開主頁。
ESP-IDF: 樂鑫組件注冊表 
ESP-IDF: Show ESP Component Registry
  • 添加 點燈組件 led_strip 和 按鈕組件 button ,注意版本,不同版本直接差別可能較大!!!
  • 兩個組件的官方介紹頁面為:LED 指示燈 和 按鍵 。

在這里插入圖片描述

  • 官方組件添加很方便,直接下載即可。編譯沒有問題。
  • 雖然只添加了兩個組件,但是下載了三個,其中一個應該是依賴,被一同下載了。
  • 官方組件是不允許修改的,每次編譯都會檢查和確保哈希值。一般創建自己的組件,然后依賴,在其基礎上實現功能或改動。應該是不建議直接復制一份然后修改

在這里插入圖片描述

2) 創建組件

  • 下面使用vscode的一鍵 創建組件 功能,快速弄兩個模板組件。

在這里插入圖片描述

  • 如何就可以看到大致結構如下,創建兩個組件實現對提示燈和按鍵的測試或調用。
  • 創建多一些測試文件,最后結構如下:

在這里插入圖片描述

自動創建的 .h 頭文件居然沒有 ifndef 宏定義保護。我個人還是喜歡加保護。這樣以防萬一。在個人工程里,嵌套調用還是很頻繁的。

  • 往代碼里填寫一些測試內容,按鈕的測試內容如下,閃燈的內容類似。
  • 注意 CMakeLists.txt 簡單理解,添加編譯路徑,指定參與編譯的文件。
/* 以下是 CMakeLists.txt 內容 */
idf_component_register(SRCS "button_test.c" "examples/button_examples.c" INCLUDE_DIRS "include") 
// 因為 CMakeLists.txt 中沒有添加 examples 文件路徑, 所以下面使用相對路徑/* 以下是 button_examples.c 內容 */
#include <stdio.h>
#include "button_examples.h"
#include "esp_log.h"static const char *TAG = "button_examples.c";void button_examples_func(void)
{ESP_LOGI(TAG, "button_examples_func Start!");}/* 以下是 button_test.c 內容 */
#include <stdio.h>
#include "button_test.h"
#include "examples/button_examples.h" // 注意這里是使用了相對路徑 
#include "esp_log.h" // 組件默認包含了 esp-idf 庫, 直接引用static const char *TAG = "button_test.c";void button_test_func(void)
{ESP_LOGI(TAG, "button_test_func Start!");button_examples_func();
}/* 以下是 main.c 內容 */
#include <stdio.h>
#include "esp_log.h"#include "led_test.h"
#include "button_test.h"
// #include "examples/button_examples.h" 無法導入 button_examples.h 文件,起到隔離保護作用const char *TAG = "main.c";void app_main(void)
{ESP_LOGI(TAG, "app_main Start!");led_test_func();button_test_func();
}/* 編譯運行監聽內容如下 */
I (236) main_task: Started on CPU0
I (246) main_task: Calling app_main()
I (246) main.c: app_main Start!
I (246) led_test.c: led_test_func Start!
I (246) led_examples.c: led_examples_func Start!
I (256) button_test.c: button_test_func Start!
I (256) button_examples.c: button_examples_func Start!
I (266) main_task: Returned from app_main()

四、組件路徑依賴

本文只介紹 ESP-IDF 推薦的規范格式,有一些非規范的操作也可以靈活實現目的,并不推薦也不介紹

1) 組件路徑/目錄

  • ESP-IDF 默認僅從以下位置查找組件:

    • $IDF_PATH/components/(ESP-IDF 內置組件,如 driveresp_wifi 等)
    • $PROJECT_PATH/components/(當前項目的 components 目錄)
    • $PROJECT_PATH/managed_components/(當前項目的 managed_components 目錄)
  • 有一些第三方組件(開發板的驅動),不合適重復放在工程中,也不能放在 ESP-IDF安裝目錄里,就可以在 CMakeLists.txt 中顯式設置 EXTRA_COMPONENT_DIRS ,該定義默認是空,不會添加任何額外的組件目錄。

# ? 必須在 項目根目錄的 CMakeLists.txt 中設置
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)  # 必須放在 set 之前list(APPEND EXTRA_COMPONENT_DIRS     	# 額外組件路徑(可以是絕對路徑或相對于項目目錄的路徑)# "../shared_components"         	# 上級目錄的共享組件# "C:/your/custom_components"   	# 絕對路徑組件目錄
)# ? EXTRA_COMPONENT_DIRS 必須在這里設置(在 project() 之前)
project(hello_component)  # 初始化 ESP-IDF 項目
  • 重名組件會被替換,優先級從小到大,和局部變量類似。
  • 初始編譯時所有組件都會被編譯,所以需要很久

2) 組件依賴

  • 重點:永遠通過組件名而非路徑建立依賴關系,這是 ESP-IDF 模塊化設計的核心原則!
  • 組件之間的依賴通過 CMakeLists.txt 修改。
  • 例如上例中,按鈕組件依賴閃燈組件,就可以導入閃燈組件的頭文件,調用函數。
idf_component_register(SRCS "led_test.c" // 單獨指定每一個參與編譯的 .cINCLUDE_DIRS "include" // 只限定對外開放 這個文件夾內的頭文件# REQUIRES # button_test  # 明確依賴的組件名(非路徑)PRIV_REQUIRES button_test  # 僅當前組件內部使用,對外不可見# "$($ENV{IDF_TARGET})"  # 根據目標芯片選擇依賴,相當于可配置更改)            
  • 頭文件不添加在 INCLUDE_DIRS : 用相對路徑,作用域僅限于當前組件內部。
  • 頭文件添加在 INCLUDE_DIRS : 將路徑變為公共 API,允許跨組件直接引用。
  • 黃金法則最小化暴露原則——僅將必要的頭文件路徑加入 INCLUDE_DIRS,內部實現細節用相對路徑隔離
  • 為什么 .c 文件需要逐個指定? .c 文件在編譯時會經歷以下過程:
    • 編譯(Compile):每個 .c 文件都會獨立編譯成對象文件(.o)。
    • 鏈接(Link):所有 .o 文件合并生成最終的庫或固件。
  • 因此需要 顯式列出每個 .c 文件;
    • 避免誤編譯:確保只編譯需要參與構建的源文件(而不是目錄下所有文件)。
    • 精確控制依賴:可以針對特定 .c 文件設置編譯選項(如 CFLAGS)。
    • 構建系統優化:僅重新編譯修改過的 .c 文件。

五、菜單配置項

問DS:為什么esp中,有Kconfig和Kconfig.projbuild兩種不同的格式?

在 ESP-IDF 開發框架中,KconfigKconfig.projbuild 是兩種不同用途的配置文件格式,它們的主要區別在于 作用范圍設計目的。以下是詳細解釋:


1. Kconfig(組件級配置)

  • 作用對象:用于 單個組件(Component) 內部的配置。
  • 功能:定義組件自身需要的可配置選項(如硬件參數、功能開關等)。
  • 文件位置:位于組件的根目錄(如 components/your_component/Kconfig)。
  • 特點
    • 僅在組件的編譯過程中生效。
    • 選項對其他組件不可見(除非顯式暴露)。
    • 遵循 ESP-IDF 的組件隔離原則,保證模塊化。

示例場景
比如一個 SPI 驅動組件可能需要配置默認時鐘頻率,此時會在 Kconfig 中定義:

   config SPI_CLOCK_SPEEDint "SPI clock speed (Hz)"default 1000000helpSet the SPI master clock frequency.

2. Kconfig.projbuild(項目級全局配置)

  • 作用對象:影響 整個項目多個組件 的全局配置。
  • 功能:覆蓋或擴展項目范圍的配置(如 SDK 工具鏈選項、系統級參數)。
  • 文件位置:可存在于組件目錄或項目根目錄(優先級高于普通 Kconfig)。
  • 特點
    • 配置選項會直接出現在頂層 menuconfig 菜單中。
    • 可能破壞組件隔離性,需謹慎使用。
    • 通常用于硬件適配或特殊需求(如切換目標芯片型號)。

示例場景
項目需要強制指定所有組件的日志級別,可以在 Kconfig.projbuild 中:

   config LOG_DEFAULT_LEVELint "Global log level"default 3range 0 4

關鍵區別總結

特性KconfigKconfig.projbuild
作用范圍組件內部整個項目全局
使用場景組件私有配置跨組件或系統級配置
隔離性嚴格隔離可能影響其他組件
推薦使用頻率高頻(標準做法)低頻(特殊需求)

為什么設計兩種格式?

  1. 模塊化需求
    ESP-IDF 強調組件化開發,Kconfig 確保每個組件的配置獨立,避免命名沖突。

  2. 靈活性的平衡
    Kconfig.projbuild 為特殊場景(如硬件適配、全局優化)提供“后門”,但需手動啟用。

  3. 優先級控制
    當兩者沖突時,Kconfig.projbuild 的配置會覆蓋普通 Kconfig,方便項目定制。


最佳實踐建議

  • 優先使用 Kconfig:保持組件解耦。
  • 慎用 Kconfig.projbuild:僅在需要全局覆蓋時使用,并添加詳細注釋說明。
  • 命名約定:在組件中避免定義全局選項(如以 CONFIG_ 開頭的選項應謹慎)。

通過這種設計,ESP-IDF 實現了配置的靈活性和模塊化的平衡。


  • 修改 Kconfig 文件,一定要刪除 build 文件才會同步 sdkmenuconfig 菜單,否則最多只是刷新了宏定義,不會刷新菜單選項。
  • 嘗試修改例程,添加以下測試代碼。分別添加全局和組件配置,然后刷新菜單。就能看到宏定義被創建,菜單也出現選項。
/* main/Kconfig.projbuild 文件內容 */
menu "Example Configuration main.c"config MAIN_TESTint "main.c test"range 10 3600000default 1000helpDefine the main test.endmenu/* components/button_test/Kconfig 文件內容 */
menu "Example Configuration button.c"config BUTTON_TESTint "button.c test"range 10 3600000default 1000helpDefine the button test.endmenu/* components/led_test/Kconfig 文件內容 */
menu "Example Configuration led.c"config LED_TESTint "led.c test"range 10 3600000default 1000helpDefine the led test.endmenu
  • main 配置菜單出現在一級菜單,而組件配置菜單位于 Component config 下面的二級菜單。
  • 如果希望本地組件的菜單在 main 菜單下面,可以修改為以下內容。可以輸入中文,但終端顯示錯位,VSCode 中就能顯示正常。
menu "Example Configuration main.c"rsource "../components/button_test/Kconfig" # 相對路徑rsource "../components/led_test/Kconfig"config MAIN_TESTint "main.c test 中文" # 名字 range 10 3600000default 1000helpmain.c test 中文. # 幫助endmenu

在這里插入圖片描述

在這里插入圖片描述


問 DS:sourcersourceorsource 的區別?
以下內容貌似瞎說的,我試了而一下覺得路徑沒成功,相對路徑成功了。而另一個工程使用source搭配相對路徑也成功了。所以有點疑惑。

在 Kconfig 系統中,sourcersourceorsource 是用于導入其他 Kconfig 文件的命令,但它們的行為和用途有所不同。以下是它們的詳細解釋和區別:


1. source

  • 功能:從指定的路徑導入另一個 Kconfig 文件。
  • 路徑解析規則
    • 絕對路徑:直接使用給定的路徑(如 source "/path/to/Kconfig")。
    • 相對路徑:路徑是**相對于 $srctree(源碼根目錄)**解析的,而不是當前文件所在目錄。
  • 典型用途
    用于導入項目中或 ESP-IDF 內置的組件 Kconfig 文件。
  • 失敗行為
    如果文件不存在,會報錯并終止解析(如你遇到的問題)。

2. rsource

  • 功能相對路徑導入(Relative-source),路徑是相對于當前 Kconfig 文件所在目錄解析的。
  • 路徑解析規則
    相對路徑基于當前文件的位置,而非 $srctree
    (這是與 source 的關鍵區別!)
  • 典型用途
    當需要從當前組件目錄中導入子模塊的 Kconfig 文件時。
  • 失敗行為
    文件不存在時會報錯。

3. orsource

  • 功能可選導入(Optional-source),如果文件不存在,則靜默忽略,不會報錯。
  • 路徑解析規則
    source 相同(相對于 $srctree)。
  • 典型用途
    導入可能不存在的可選配置文件,避免因文件缺失導致構建失敗。
  • 失敗行為
    文件不存在時不會報錯。

三者的對比總結

命令路徑解析基準文件不存在時的行為典型場景
source$srctree報錯并終止強制依賴的組件或核心配置
rsource當前文件目錄報錯并終止組件內部的子模塊配置
orsource$srctree靜默忽略可選的自定義或平臺特定配置

  • 最后,如果修改了配置文件,為了避免每次重復配置,可以使用指令 idf.py save-defconfig
    保 存當前的已修改配置,留作下次使用。
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.4.1 Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_BUTTON_TEST=999
CONFIG_LED_TEST=666
CONFIG_MAIN_TEST=555

六、實戰

  • 將組件的示例內容實現,路徑類似:managed_components\espressif__button\test_apps\main。里面有多個例子,拷貝出來進行仿制,然后對組件進行二次打包,作為個人組件方便調用。搭配 Kconfig 配置就更加規范了。

在這里插入圖片描述

  • 提一句按鈕的使用,單個按鍵沒啥好講的,主要是adc按鍵,使用 excel 表格方便計算,舉例3000mV,分成5個按鈕。
  • 參考例程給的思路,分成 n+1,已知所需電壓,假設上拉電阻R0,計算理論R1~R5,然后查電阻本尋找合適的電阻,然后再計算實際觸發電壓,然后編寫注冊按鈕的程序。

在這里插入圖片描述

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

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

相關文章

【Java_EE】單例模式、阻塞隊列、線程池、定時器

目錄 單例模式 餓漢模式<代碼> 懶漢模式<代碼> 阻塞隊列 阻塞隊列概念 阻塞隊列解決的問題 阻塞隊列工作原理 阻塞隊列的優/缺點 優點 缺點 模擬實現阻塞隊列<代碼> 線程池 線程池概念 線程池解決的問題 線程池參數 四種拒絕策略 線程池工作…

Redis初識第七期---ZSet的命令和應用場景

ZSet相較于Set來說&#xff0c;它又是有序的&#xff0c;這個有序指的就是我們通常意義上的有序了&#xff0c;ZSet內部中是按照升序來排序的。 排序規則&#xff1a;ZSet相較于Set來說&#xff0c;它內部引入了一個新的屬性&#xff1a;分數&#xff08;Score&#xff09;&am…

Wps開放平臺v5升級v7上傳實體文件踩坑(Java使用restTemplate)

背景&#xff1a; 最近接到一個老項目需求&#xff0c;之前開發的WPS開放平臺文件&#xff08;商密集成&#xff09;預覽功能因為升級需要重新對接api&#xff0c;新的上傳文件接口踩坑特意記錄一下。 這里出問題的是第二步&#xff0c;請求文件上傳信息 踩坑代碼 調用后403 p…

啥時候上RAG?啥時候上微調?丨實戰筆記

哈嘍&#xff0c;大家好&#x1f44f; 我是阿星&#xff01; 現在很多AI科普文章都會提到微調&#xff0c;RAG。 但是沒有實戰的過的同學可能會問&#x1f914;—— 啥時候用RAG&#xff1f;啥時候用微調呢&#xff1f;有啥區別&#xff1f;不都是讓模型增加知識面的嗎&…

RabbitMQ-基礎篇

前言&#xff1a; 今天開始學RabbitMQ,還是跟著黑馬的課程。 今日所學&#xff1a; RabbitMQ介紹RabbitMQ入門Java客戶端中的MQ 1.RabbitMQ介紹 1.1 什么是RabbitMQ RabbitMQ 是一個開源的消息代理軟件&#xff08;消息隊列中間件&#xff09;&#xff0c;實現了高級消息…

docker-compose配置redis哨兵詳細步驟和配置文件

docker-compose配置redis哨兵詳細步驟和配置文件 目錄結構調整 redis-cluster/ ├── config/ │ ├── master.conf # 主節點配置 │ ├── slave1.conf # 從節點1配置 │ ├── slave2.conf # 從節點2配置 │ ├── sentinel1.…

多模態大語言模型arxiv論文略讀(146)

Exploring Response Uncertainty in MLLMs: An Empirical Evaluation under Misleading Scenarios ?? 論文標題&#xff1a;Exploring Response Uncertainty in MLLMs: An Empirical Evaluation under Misleading Scenarios ?? 論文作者&#xff1a;Yunkai Dang, Mengxi G…

【教程】Linux中限制用戶可以使用的GPU數量 | 附腳本

轉載請注明出處&#xff1a;小鋒學長生活大爆炸[xfxuezhagn.cn] 如果本文幫助到了你&#xff0c;歡迎[點贊、收藏、關注]哦~ 目錄 背景說明 設置方法 管理腳本 進階限制 恢復默認組 注意事項 背景說明 比較簡單的方式是使用group來管理權限&#xff0c;這種方式能限制哪些…

90.xilinx復位低電平(一般使用低電平復位)

Xilinx FPGA 中的寄存器&#xff08;Flip-Flop&#xff09;**確實支持異步復位**&#xff0c;但具體實現方式取決于你使用的設計方法&#xff08;HDL 代碼風格或原語實例化&#xff09;。以下是詳細說明&#xff1a; --- ### 1. **Xilinx 寄存器的復位特性** - **同步復位…

NVMe高速傳輸之擺脫XDMA設計10: DMA 控制單元設計

DMA 控制單元負責控制 DMA 傳輸事務&#xff0c; 該單元承擔了 DMA 事務到 NVMe 事務的轉換任務&#xff0c; 使用戶對數據傳輸事務的控制更加簡單快捷。 DMA 控制功能由 DMA寄存器組實現。 DMA 寄存器組包含 DMA 操作寄存器、 DMA 長度寄存器、 DMA 源目的地址寄存器和 DMA 狀…

如何設置電腦定時休眠?操作指南詳解

長時間運行電腦會導致硬件過熱&#xff0c;縮短其使用壽命。定時關機有助于讓硬件得到休息&#xff0c;降低因長時間高負荷工作導致損壞的風險。 它的界面簡潔直觀&#xff0c;功能卻十分實用&#xff0c;涵蓋了定時關機、重啟、注銷、休眠、待機以及鎖定等多種操作。 以設置“…

LeetCode[617]合并二叉樹

思路&#xff1a; 我們合并左右子樹&#xff0c;在遞歸左右子樹的時候&#xff0c;一定要保證左右子樹不為空&#xff0c;如果左子樹為空&#xff0c;那么直接返回右子樹就行了&#xff0c;即使右子樹為空。如果右子樹為空那么直接返回左子樹就行了&#xff0c;這樣判斷完就正常…

Redis 常用五大數據類型

1、Redis 關鍵字&#xff08;Key&#xff09; keys * 查看當前庫所有keyexists [key] 判斷某個key是否存在type [key] 查看當前key的數據類型del [key] 刪除指定的key數據unlink [key] 根據value選擇非阻塞刪除&#xff0c;僅將keys從keyspace元數據中刪除&#xff0c;真正的刪…

大語言模型(LLM)專業術語匯總

1. 訓練與部署 1.1 預訓練 專業&#xff1a;在海量無標注文本&#xff08;如Common Crawl、Wikipedia&#xff09;上通過自監督學習訓練基礎語言模型&#xff0c;學習通用語言表征&#xff08;如GPT-3訓練數據達45TB&#xff09;。通俗&#xff1a;AI的“通識教育階段”&…

【Java Swing 圖形界面編程】JList 列表組件 ① ( JList 組件簡介 | 核心作用 | 關鍵特性 | 基礎用法示例 )

文章目錄 一、JList 組件簡介1、JList 概念簡介2、JList 核心作用3、JList 關鍵特性 二、JList 組件基礎用法示例1、使用 String 數組構建列表項2、使用 Vector 集合構建列表項3、使用 DefaultListModel 構建列表項 一、JList 組件簡介 1、JList 概念簡介 基本概念 : JList 組件…

【小技巧】Python+PyCharm IDE 配置解釋器出錯,環境配置不完整或不兼容。(小智AI、MCP、聚合數據、實時新聞查詢、NBA賽事查詢)

報錯信息如下&#xff1a; [unsupported] Python 3.1 (mcp-calculator-main) (3) C:\Users(xsshu\AppData\Local\Programs\Python\Python313\python.exe [unsupported] Python 3.1 C:\Users\xsshu\AppData\Local\Programs\Python\Python311\python.exe 這條輸出顯示了兩個 Pyth…

Ragflow 前后端登錄邏輯

前端登錄邏輯 路由配置&#xff1a; /login 路由指向 /pages/login 組件。登錄表單使用 Ant Design 的 Form, Input, 和 Button 組件。 登錄表單處理&#xff1a; 使用 useLogin鉤子來處理登錄請求。密碼通過 RSA 加密后再發送到服務器。成功登錄后導航至 /knowledge 頁面。 …

基于圖神經網絡的ALS候選藥物預測模型設計與實現

基于圖神經網絡的ALS候選藥物預測模型設計與實現 一、任務背景與意義 肌萎縮側索硬化癥(ALS)是一種致命的神經退行性疾病,目前尚無有效治愈方法。傳統藥物發現流程耗時長、成本高,而人工智能技術為加速藥物發現提供了新途徑。本文設計并實現了一個基于圖神經網絡(GNN)的…

運維打鐵: 數據加密與備份恢復策略制定

文章目錄 思維導圖一、數據加密1. 加密算法選擇AES 加密示例&#xff08;Python&#xff09;RSA 加密示例&#xff08;Python&#xff09; 2. 密鑰管理3. 加密范圍 二、數據備份1. 備份類型全量備份增量備份差異備份 2. 備份頻率3. 備份存儲位置 三、數據恢復1. 恢復測試2. 恢復…

AIbase MCP服務庫上線:集成服務器、客戶端、案例教程等服務

在當今數字化時代&#xff0c;人工智能技術正以前所未有的速度發展&#xff0c;深刻地改變著我們的生活和工作方式。而要充分發揮AI的強大能力&#xff0c;離不開高效的工具和服務支持。今天&#xff0c;就讓我們來了解一下一個專注于MCP&#xff08;Model Context Protocol&am…