第四章 認(rèn)識(shí)ESP-IDF
ESP-IDF是樂(lè)鑫科技為其ESP32系列芯片提供的官方開發(fā)框架。這個(gè)框架主要用于開發(fā)柏卤、構(gòu)建和部署基于ESP32的物聯(lián)網(wǎng)(IoT)應(yīng)用。我們要寫程序控制ESP32芯片匀油,其實(shí)最終就是控制它的寄存器缘缚,使之工作在我們需要的模式下,ESP-IDF庫(kù)將大部分寄存器的操作封裝成了函數(shù)敌蚜,我們只需要學(xué)習(xí)和掌握ESP-IDF庫(kù)函數(shù)的結(jié)構(gòu)和用法桥滨,就能方便地驅(qū)動(dòng)ESP32工作,以節(jié)省開發(fā)時(shí)間弛车。
本章將分為如下幾個(gè)小節(jié):
4.1 ESP-IDF簡(jiǎn)介
4.2 ESP-IDF庫(kù)框架結(jié)構(gòu)解析
4.3 ESP-IDF與樂(lè)鑫芯片
4.4 IDF工程簡(jiǎn)介
4.1 ESP-IDF簡(jiǎn)介
ESP-IDF(Espressif IoT Development Framework)是樂(lè)鑫(Espressif Systems)為ESP系列芯片開發(fā)的物聯(lián)網(wǎng)開發(fā)框架齐媒。它支持ESP32、ESP32-S纷跛、ESP32-C和ESP32-H系列SoC喻括,基于C/C++語(yǔ)言提供了一個(gè)自給自足的SDK,方便用戶在這些平臺(tái)上開發(fā)通用應(yīng)用程序贫奠。
一唬血、ESP-IDF特點(diǎn):
(1)免費(fèi)開源:ESP-IDF 相關(guān)資源已在 GitHub 上免費(fèi)開放。
(2)專業(yè)穩(wěn)定:ESP-IDF發(fā)布的版本均經(jīng)過(guò)嚴(yán)格的測(cè)試流程唤崭,以確保版本穩(wěn)定拷恨,客戶可快速實(shí)現(xiàn)量產(chǎn)。
(3)功能豐富的軟件組件:ESP-IDF 集成了大量的軟件組件谢肾,包括 RTOS腕侄、外設(shè)驅(qū)動(dòng)程序、網(wǎng)絡(luò)棧芦疏、多種協(xié)議實(shí)現(xiàn)技術(shù)以及常見應(yīng)用程序的使用助手兜挨。
(4)支持多種IDE開發(fā):Eclipse 和 VSCode 等 IDE,確保其易于開發(fā)人員使用眯分。
(5)豐富的文檔和示例資源:ESP-IDF 提供詳盡的軟件組件使用和設(shè)計(jì)文檔拌汇,有助于開發(fā)人員充分理解 ESP-IDF功能,并從中挑選最適合構(gòu)建其應(yīng)用程序的模塊弊决。
(6)支持Windows噪舀、Linux 和 macOS 系統(tǒng)平臺(tái)上開發(fā) ESP32 應(yīng)用程序提供工具鏈、API飘诗、組件和工作流程(本教程選擇Windows系統(tǒng)下開發(fā))与倡。
二、自動(dòng)化構(gòu)建系統(tǒng):
開發(fā)者只需要通過(guò)簡(jiǎn)單的命令即可觸發(fā)整個(gè)編譯流程昆稿。下圖為ESP-IDF編譯系統(tǒng)流程:
從上述圖示可見纺座,項(xiàng)目的工程文件通過(guò)集成C項(xiàng)目、中間組件以及工具鏈溉潭,共同編譯生成可執(zhí)行文件净响。隨后少欺,這個(gè)可執(zhí)行文件被下載到ESP32芯片中。ESP32芯片能夠通過(guò)其監(jiān)控器功能馋贤,向開發(fā)者提供實(shí)時(shí)的反饋信息赞别。這一流程使得開發(fā)者能夠更有效地監(jiān)控和管理ESP32芯片的運(yùn)行狀態(tài),從而優(yōu)化項(xiàng)目的開發(fā)過(guò)程配乓。
ESP-IDF的編譯過(guò)程主要基于Make或CMake構(gòu)建系統(tǒng)仿滔,它自動(dòng)化地處理源代碼的編譯、鏈接和生成最終的可執(zhí)行文件或固件鏡像犹芹。簡(jiǎn)單來(lái)講崎页,ESP-IDF可以使用命令的形式進(jìn)行配置、編譯腰埂、鏈接和構(gòu)建項(xiàng)目飒焦,類似于linux的開發(fā)方式。整個(gè)編譯過(guò)程通過(guò)構(gòu)建系統(tǒng)自動(dòng)化完成盐固,開發(fā)者只需要通過(guò)簡(jiǎn)單的命令即可觸發(fā)整個(gè)編譯流程。
ESP-IDF雖然提供了強(qiáng)大的功能和靈活性丈挟,但使用命令編譯和構(gòu)造等操作也存在一些缺點(diǎn)刁卜。
①:學(xué)習(xí)曲線陡峭。對(duì)于初學(xué)者來(lái)說(shuō)曙咽,ESP-IDF可能具有一定的學(xué)習(xí)難度蛔趴。它需要一定的時(shí)間來(lái)理解其目錄結(jié)構(gòu)、編譯系統(tǒng)例朱、配置文件以及API等
②:編譯過(guò)程繁瑣孝情。雖然ESP-IDF提供了命令來(lái)編譯和構(gòu)造項(xiàng)目,但編譯過(guò)程可能會(huì)相對(duì)繁瑣洒嗤。特別是當(dāng)項(xiàng)目規(guī)模較大或者依賴多個(gè)組件時(shí)箫荡,編譯時(shí)間可能會(huì)延長(zhǎng),這可能會(huì)影響開發(fā)效率渔隶。
③:缺乏圖形化界面羔挡。雖然ESP-IDF提供了命令行工具來(lái)進(jìn)行項(xiàng)目構(gòu)建和調(diào)試,但缺乏圖形化界面的支持可能會(huì)使得某些操作相對(duì)不便间唉。對(duì)于一些開發(fā)者來(lái)說(shuō)绞灼,圖形化界面可以提供更直觀和易于使用的操作體驗(yàn)。
④:配置復(fù)雜呈野。ESP-IDF的配置文件(如sdkconfig)可能相對(duì)復(fù)雜低矮,特別是對(duì)于初學(xué)者來(lái)說(shuō)。需要正確配置各種選項(xiàng)和參數(shù)被冒,以確保項(xiàng)目能夠正確編譯和運(yùn)行军掂。配置錯(cuò)誤可能導(dǎo)致編譯失敗或運(yùn)行時(shí)問(wèn)題孵构。
對(duì)于上述的問(wèn)題,樂(lè)鑫科技提供了一個(gè)解決方案鲫懒,那就是在集成開發(fā)環(huán)境下開發(fā)ESP-IDF遭居,使得開發(fā)者更加快速的開發(fā)ESP32芯片。下面是樂(lè)鑫官方ESP-IDF支持的集成開發(fā)環(huán)境玛追。
下圖為VS Code/Eclipse/Espressif-IDE等IDE的開發(fā)ESP-IDF程序流程圖税课。
不難發(fā)現(xiàn),圖4.1.1的流程和圖4.1.3的流程極為相似痊剖,唯一不同的是圖4.1.3是基于IDE集成開發(fā)環(huán)境下開發(fā)的韩玩,但是它們的編譯流程是一致的。
本教程中的所有例程都是基于VS Code IDE進(jìn)行開發(fā)的陆馁。雖然并未提供基于Eclipse IDE的開發(fā)例程找颓,但上圖中展示的開發(fā)應(yīng)用程序流程同樣適用于VS Code IDE的開發(fā)流程。這意味著叮贩,無(wú)論使用哪種IDE開發(fā)ESP-IDF击狮,開發(fā)者都可以遵循這一流程來(lái)有效地進(jìn)行應(yīng)用程序的開發(fā)。
三益老、ESP-IDF在VS Code集成開發(fā)環(huán)境開發(fā)具備那些特點(diǎn)
①:代碼編輯與智能提示彪蓬。安裝了ESP-IDF擴(kuò)展插件后,VSCode將提供代碼高亮捺萌、語(yǔ)法檢查档冬、自動(dòng)補(bǔ)全等IDE功能,極大地提高了代碼編輯的效率和準(zhǔn)確性桃纯。插件還提供了對(duì)ESP-IDF特定函數(shù)和API的智能提示酷誓,幫助開發(fā)者更快地編寫和調(diào)試代碼。
②:構(gòu)建與調(diào)試态坦。ESP-IDF擴(kuò)展插件集成了構(gòu)建和調(diào)試功能盐数,開發(fā)者可以直接在VSCode中執(zhí)行idf.py build等命令來(lái)構(gòu)建項(xiàng)目。還可以通過(guò)配置launch.json文件伞梯,開發(fā)者還可以在VSCode中設(shè)置斷點(diǎn)娘扩、單步執(zhí)行、查看變量值等調(diào)試功能壮锻,從而方便地進(jìn)行程序調(diào)試琐旁。
③:項(xiàng)目管理與配置。VSCode支持多項(xiàng)目管理猜绣,開發(fā)者可以方便地切換和管理不同的ESP-IDF項(xiàng)目灰殴。還通過(guò)VSCode中的配置文件(如.vscode/settings.json),開發(fā)者可以針對(duì)每個(gè)項(xiàng)目設(shè)置特定的構(gòu)建和調(diào)試選項(xiàng)。
④:集成終端與日志查看牺陶。VSCode內(nèi)置了終端功能伟阔,開發(fā)者可以直接在VSCode中打開終端并執(zhí)行ESP-IDF相關(guān)的命令。還可以通過(guò)集成終端掰伸,開發(fā)者可以方便地查看構(gòu)建日志皱炉、調(diào)試輸出等信息,從而快速定位和解決問(wèn)題狮鸭。
VSCode與ESP-IDF之間的關(guān)系主要體現(xiàn)在VSCode為ESP-IDF提供了一個(gè)功能強(qiáng)大的集成開發(fā)環(huán)境合搅,通過(guò)安裝和使用ESP-IDF擴(kuò)展插件,開發(fā)者可以更加高效地在VSCode中編寫歧蕉、構(gòu)建灾部、調(diào)試和部署ESP32等Espressif芯片的應(yīng)用程序。
4.2 ESP-IDF庫(kù)框架結(jié)構(gòu)解析
下面我們從gitee倉(cāng)庫(kù)下克隆ESP-IDF物聯(lián)網(wǎng)開發(fā)框架的源代碼惯退,并在此分析各個(gè)文件的作用赌髓。克隆ESP-IDF源碼庫(kù)流程如下圖所示催跪。
克隆成功后锁蠕,在上圖路徑下找到esp-idf文件夾,此文件夾就是ESP-IDF物聯(lián)網(wǎng)開發(fā)框架的源碼庫(kù)懊蒸,如下圖所示荣倾。
下面作者來(lái)講解一下這些文件夾的作用及特點(diǎn),如下表所示:
正如圖4.1.1所示那樣榛鼎,在編譯ESP32的例程時(shí)逃呼,確保components和tools目錄的完整性是非常重要的鳖孤。components目錄包含了項(xiàng)目所需的所有源代碼和庫(kù)文件者娱,而tools目錄則提供了編譯和鏈接這些代碼所需的工具鏈,這樣才能做到自給自足的構(gòu)建項(xiàng)目苏揣。
4.3 ESP-IDF與樂(lè)鑫芯片
每款樂(lè)鑫芯片都可能有不同版本黄鳍,下表總結(jié)了樂(lè)鑫芯片在 ESP-IDF 各版本中的支持狀態(tài),其中“P” 代表已支持平匈,“預(yù)覽”代表目前處于預(yù)覽支持狀態(tài)框沟。預(yù)覽支持狀態(tài)通常有時(shí)間限制,而且僅適用于測(cè)試版芯片增炭。請(qǐng)確保使用與芯片相匹配的 ESP-IDF 版本忍燥。
從上表可知:每款樂(lè)鑫芯片都可能有不同版本。建議參考[ESP-IDF 版本與樂(lè)鑫芯片版本兼容性]隙姿,了解 ESP-IDF 版本與各芯片版本之間的兼容性梅垄,作者建議讀者最好找到合適的ESP-IDF版本來(lái)開發(fā)自己的SoC芯片。
對(duì)于 2016 年之前發(fā)布的樂(lè)鑫芯片(包括 ESP8266 和 ESP8285)输玷,請(qǐng)參考[RTOS SDK]队丝。
4.4 IDF工程簡(jiǎn)介
ESP-IDF工程靡馁,特別是ESP-IDF項(xiàng)目,可以看作是由多個(gè)不同組件集合而成的工程机久。這些組件包括ESP-IDF基礎(chǔ)庫(kù)(如libc臭墨、ROM bindings等)、Wi-Fi驅(qū)動(dòng)膘盖、TCP/IP協(xié)議棧胧弛、FreeRTOS操作系統(tǒng)、網(wǎng)頁(yè)服務(wù)器衔憨、各種傳感器驅(qū)動(dòng)(如濕度傳感器驅(qū)動(dòng))以及負(fù)責(zé)將上述組件整合到一起的主程序等叶圃。
ESP-IDF工程借助CMake的可自定義性,創(chuàng)新地采用了“組件”式的設(shè)計(jì)践图。整個(gè)工程由多個(gè)組件組成掺冠,每個(gè)組件都像是一塊積木,共同構(gòu)建起完整的工程結(jié)構(gòu)码党。在這些組件中德崭,有一個(gè)特殊的組件被稱為“main”組件,它包含了用戶應(yīng)用程序的入口函數(shù)揖盘。
組件之間的關(guān)系主要以依賴關(guān)系為主眉厨,確保了它們之間的有序協(xié)作。每個(gè)組件都可以擁有單獨(dú)的配置兽狭,這進(jìn)一步增加了工程的靈活性和可定制性憾股。在ESP-IDF中,用戶可以明確地指定和配置每個(gè)組件箕慧。構(gòu)建系統(tǒng)會(huì)在ESP-IDF目錄服球、項(xiàng)目目錄以及用戶自定義的組件目錄(如存在)中查找所有的組件。這一過(guò)程允許用戶通過(guò)文本菜單系統(tǒng)對(duì)ESP-IDF項(xiàng)目中使用的每個(gè)組件進(jìn)行配置颠焦。當(dāng)所有組件的配置完成后斩熊,構(gòu)建系統(tǒng)便會(huì)開始編譯整個(gè)項(xiàng)目,確保所有組件能夠按照預(yù)期的方式協(xié)同工作伐庭,從而生成最終的工程成果粉渠。這種設(shè)計(jì)不僅簡(jiǎn)化了工程的開發(fā)和維護(hù),也提高了開發(fā)效率圾另。
1霸株,ESP32工程有如下重要概念:
①:項(xiàng)目(Project)特指一個(gè)目錄,其中包含了構(gòu)建可執(zhí)行應(yīng)用程序所需的全部文件和配置集乔,以及其他支持型文件去件,例如分區(qū)表、數(shù)據(jù)/文件系統(tǒng)分區(qū)和引導(dǎo)程序。
②:項(xiàng)目配置 保存在項(xiàng)目根目錄下名為sdkconfig的文件中箫攀,可以通過(guò) idf.py menuconfig 進(jìn)行修改肠牲,且一個(gè)項(xiàng)目只能包含一個(gè)項(xiàng)目配置。
③:應(yīng)用程序是由ESP-IDF構(gòu)建得到的可執(zhí)行文件靴跛。一個(gè)項(xiàng)目通常會(huì)構(gòu)建兩個(gè)應(yīng)用程序:項(xiàng)目應(yīng)用程序(可執(zhí)行的主文件缀雳,即用戶自定義的固件)和引導(dǎo)程序(啟動(dòng)并初始化項(xiàng)目應(yīng)用程序)。
④:組件(Components)是模塊化且獨(dú)立的代碼梢睛,會(huì)被編譯成靜態(tài)庫(kù)(.a 文件)并鏈接到應(yīng)用程序肥印。部分組件由 ESP-IDF 官方提供,其他組件則來(lái)源于其它開源項(xiàng)目绝葡。
⑤:目標(biāo)(Target)特指運(yùn)行構(gòu)建后應(yīng)用程序的硬件設(shè)備深碱。ESP-IDF 當(dāng)前僅支持 esp32 和 esp32s2 以及 esp32s3 這三個(gè)硬件目標(biāo)。
請(qǐng)注意藏畅,以下內(nèi)容并不屬于項(xiàng)目的組成部分:
①:ESP-IDF 并不是項(xiàng)目的一部分敷硅,它獨(dú)立于項(xiàng)目,通過(guò) IDF_PATH 環(huán)境變量(保存 esp-idf 目錄的路徑)鏈接到項(xiàng)目愉阎,從而將 IDF 框架與項(xiàng)目分離绞蹦。
②:交叉編譯工具鏈并不是項(xiàng)目的組成部分,它應(yīng)該被安裝在系統(tǒng) PATH 環(huán)境變量中榜旦。
2幽七,ESP32項(xiàng)目工程分析
下面作者以sample_project示例(D:\ESP32\Espressif\frameworks\esp-idf-v5.1.2\examples\get-started\sample_project路徑下找到)為例,來(lái)講解基礎(chǔ)工程的構(gòu)建項(xiàng)目原理溅呢。sample_project工程目錄如下圖所示:
①:頂層項(xiàng)目 CMakeLists.txt 文件澡屡,這是 CMake 用于學(xué)習(xí)如何構(gòu)建項(xiàng)目的主要文件,可以在這個(gè)文件中設(shè)置項(xiàng)目全局的 CMake 變量咐旧。頂層項(xiàng)目 CMakeLists.txt 文件會(huì)導(dǎo)入 /tools/cmake/project.cmake 文件驶鹉,由它負(fù)責(zé)實(shí)現(xiàn)構(gòu)建系統(tǒng)的其余部分。該文件最后會(huì)設(shè)置項(xiàng)目的名稱休偶,并定義該項(xiàng)目梁厉。每個(gè)項(xiàng)目都有一個(gè)頂層 CMakeLists.txt 文件辜羊,包含整個(gè)項(xiàng)目的構(gòu)建設(shè)置踏兜。默認(rèn)情況下,項(xiàng)目 CMakeLists八秃。 文件會(huì)非常小碱妆,如下代碼所示:
/* 必須放在 CMakeLists.txt 文件的第一行,
它會(huì)告訴 CMake 構(gòu)建該項(xiàng)目所需要的最小版本號(hào)昔驱。ESP-IDF 支持 CMake 3.16 或更高的版本 */
cmake_minimum_required(VERSION 3.16)
/* 會(huì)導(dǎo)入 CMake 的其余功能來(lái)完成配置項(xiàng)目疹尾、檢索組件等任務(wù) */
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
/* 會(huì)創(chuàng)建項(xiàng)目本身,并指定項(xiàng)目名稱 */
project(myProject)
②:main目錄是一個(gè)特殊的組件,它包含兩個(gè)文件纳本,它們分別為CMakeLists.txt和mian.c文件窍蓝。其中main.c定義了程序入口函數(shù)app_main(),而CMakeLists.txt文件是將組件添加到構(gòu)建系統(tǒng)中繁成,如下圖所示:
idf_component_register(SRCS "main.c"
? ?? ?? ?? ?? ?? ?? ? INCLUDE_DIRS ".")
通過(guò)調(diào)用 idf_component_register函數(shù)吓笙,開發(fā)者可以將組件添加到構(gòu)建系統(tǒng)中。在此過(guò)程中巾腕,SRCS 代表源文件列表面睛,其中包括 .c、.cpp尊搬、.cc叁鉴、.S 等類型的文件,這些源文件都將被編譯并整合進(jìn)組件庫(kù)中佛寿。另外幌墓,INCLUDE_DIRS 指的是目錄列表,這些目錄中的路徑將被添加到所有需要該組件(包括主組件)的全局 include 搜索路徑中冀泻,確保在編譯過(guò)程中能夠正確找到相關(guān)的頭文件克锣。注意:若該組件需要依賴其他的驅(qū)動(dòng)代碼,可使用REQUIRES設(shè)置依賴庫(kù)腔长,具體內(nèi)容請(qǐng)參考ESP-IDF編程指南的組件依賴章節(jié)袭祟。
③:“sdkconfig” 項(xiàng)目配置文件,執(zhí)行 idf.py menuconfig 時(shí)會(huì)創(chuàng)建或更新此文件捞附,文件中保存了項(xiàng)目中所有組件(包括 ESP-IDF 本身)的配置信息巾乳。 sdkconfig 文件可能會(huì)也可能不會(huì)被添加到項(xiàng)目的源碼管理系統(tǒng)中。
從上述內(nèi)容可以得知以下總結(jié):子層的CMakeLists.txt文件負(fù)責(zé)將對(duì)應(yīng)層的組件整合進(jìn)構(gòu)建系統(tǒng)當(dāng)中鸟召,而sdkconfig文件則用于設(shè)置構(gòu)建過(guò)程中所需的多種配置選項(xiàng)(該編譯哪些代碼胆绊,不該編譯哪些代碼)。同時(shí)欧募,頂層的CMakeLists.txt文件不僅指定了CMake的版本压状,還通過(guò)引用ESP-IDF路徑下的project.cmake文件來(lái)指導(dǎo)整個(gè)項(xiàng)目的構(gòu)建流程。這些文件共同協(xié)作跟继,確保項(xiàng)目能夠順利構(gòu)建和配置种冬。最終,項(xiàng)目構(gòu)建完成后會(huì)生成一個(gè)build文件夾舔糖,其中包含了臨時(shí)目標(biāo)文件娱两、庫(kù)文件以及最終輸出的二進(jìn)制文件。