“智眸·家聯“項目開發(一)

嵌入式開發調試知識點總結(含操作流程)

我們今天解決問題的過程,就像是偵探破案,從最表面的線索(網絡不通)開始,一步步深入,最終找到了案件的核心(硬件不匹配),并成功破案。下面我們來復盤一下這個過程中的關鍵知識點和具體操作。

第一階段:解決網絡與 Git 克隆問題 —— 打通信息渠道

在開發的最開始,我們首先需要從網上獲取代碼,但您的網絡環境給這個過程帶來了一些挑戰。

1. 知識點講解

  • HTTPS vs. SSH:HTTPS 是一條公共高速路,方便但易被干擾;SSH 是一條私人加密隧道,需要用“鑰匙”配對,但連接更穩定。當 HTTPS 反復失敗時,切換到 SSH 是專業高效的解決方法。

  • 子模塊 (Submodule):大型項目中的“俄羅斯套娃”,通過 --recursive 參數可以一次性把主項目和所有依賴的子項目全部下載下來。

2. 具體操作流程

嘗試使用 HTTPS 克隆(失敗): 我們最開始嘗試的是標準的 HTTPS 克隆命令,但由于網絡問題失敗了。

git clone --recursive https://github.com/espressif/esp-adf.git

切換到 SSH 協議進行克隆: 為了繞過網絡干擾,我們為 Git 配置了全局規則,讓它自動將 HTTPS 地址替換為 SSH 地址,然后重新下載。

# 第一步:配置 Git,讓它自動將 github.com 的 https 鏈接轉為 ssh
git config --global url."git@github.com:".insteadOf "https://github.com/"# 第二步:使用原來的 https 地址進行克隆,Git 會自動轉換
# 注意:這一步需要您已經配置好本機的 SSH 密鑰并添加到了 GitHub 賬戶
git clone --recursive https://github.com/espressif/esp-adf.git

第二階段:處理 Git 本地配置 —— 獲得本地通行證

解決了網絡問題后,我們又遇到了一個本地的“攔路虎”。

1. 知識點講解

  • “可疑的所有權” (Dubious Ownership):這是新版 Git 的安全警報,它懷疑當前操作的用戶并非代碼文件夾的合法主人,尤其在 Windows 的非系統盤上容易觸發。

  • 解決方案:這不是一個真正的錯誤,而是 Git 過于“謹慎”。我們只需要給這個文件夾蓋上“安全認證”的章即可。

2. 具體操作流程

執行 Git 提示的安全授權命令: 當 Git 提示 fatal: detected dubious ownership... 時,我們完全按照它的指示,復制并執行了下面的命令。

# 將 G:/... 替換為您自己項目的實際路徑
git config --global --add safe.directory G:/Espressif/frameworks/esp-idf-v5.3.3/esp-adf

第三階段:診斷并修復硬件適配問題 —— 案件的核心

這是我們今天解決問題的核心和精華所在,也是嵌入式開發中最常見、最重要的一環。

1. 知識點講解

  • I2C 與“NACK”錯誤:I2C 就像主芯片和外部芯片之間的“電話線”。NACK 錯誤意味著“對方無人接聽”,根本原因是硬件連接或配置錯誤。

  • “默認配置”與“自定義配置”的優先級

    • 默認配置:官方示例內置的配置是為官方開發板(如 ESP32-LyraT)準備的“地圖”。當您不選擇任何配置直接編譯時,程序會拿著這張錯誤的地圖在您的硬件上找路,自然找不到音頻芯片。

    • 廠商配置(如 M5Stack):像 M5Stack 這樣的廠商,會提供自己的 menuconfig 選項(如 M5AtomS3R)。選擇它,會加載一個基礎模板,這個模板最大的作用是幫助您啟用了正確的芯片驅動(例如 ES8311 和 ES7210)。但它的引腳定義不一定能被通用示例正確調用。

    • 我們的最終方案:高優先級覆蓋:我們創建了一個自定義組件 my_board,并在其中放置了 board_pins_config.c 文件。這相當于我們自己畫了一張最精確的“施工圖紙”。然后通過 menuconfig 里的 Get pins from board_pins_config.c 選項,我們強制編譯系統必須使用我們這張圖紙,它的優先級是最高的,會覆蓋掉其他所有默認的引腳配置。這保證了即使示例代碼是通用的,它最終也會采用我們為 M5Stack 精心繪制的硬件引腳圖。

2. 具體操作流程

創建自定義板級組件: 在您的工程根目錄 play_mp3_control 下,創建如下的文件夾結構。

play_mp3_control/
└── components/└── my_board/  <-- 這是我們自定義的組件

創建并編寫引腳“施工圖紙”: 在 my_board 文件夾里,創建一個 board_pins_config.c 文件,并填入為您的 AtomS3 + Echo Base 定制的正確引腳信息。

// file: play_mp3_control/components/my_board/board_pins_config.c#include "board.h"
#include "driver/gpio.h"// I2C 引腳定義: SDA=2, SCL=1
esp_err_t get_i2c_pins(i2c_port_t port, i2c_config_t *i2c_config)
{if (port == I2C_NUM_0) {i2c_config->sda_io_num = GPIO_NUM_2;i2c_config->scl_io_num = GPIO_NUM_1;} else { /* 其他 I2C 端口我們不用 */i2c_config->sda_io_num = -1;i2c_config->scl_io_num = -1;}return ESP_OK;
}// I2S 引腳定義: BCLK=33, LRCK=25, DOUT=26, DIN=27
esp_err_t get_i2s_pins(i2s_port_t port, i2s_pin_config_t *i2s_pin_config)
{if (port == I2S_NUM_0) {i2s_pin_config->bck_io_num      = GPIO_NUM_33;i2s_pin_config->ws_io_num       = GPIO_NUM_25;i2s_pin_config->data_out_num    = GPIO_NUM_26;i2s_pin_config->data_in_num     = GPIO_NUM_27;i2s_pin_config->mck_io_num      = GPIO_NUM_NC; // MCLK (主時鐘) 沒有使用} else { /* 其他 I2S 端口我們不用 */i2s_pin_config->bck_io_num      = -1;i2s_pin_config->ws_io_num       = -1;i2s_pin_config->data_out_num    = -1;i2s_pin_config->data_in_num     = -1;}return ESP_OK;
}

為新組件創建 CMakeLists.txt: 在 my_board 文件夾里,創建一個 CMakeLists.txt 文件來注冊這個組件。

# file: play_mp3_control/components/my_board/CMakeLists.txt
idf_component_register(SRCS "board_pins_config.c"INCLUDE_DIRS ".")

使用 menuconfig 進行軟件配置: 在項目根目錄運行 idf.py menuconfig,然后進行以下設置:

  • Audio HAL -> Select target audio board -> 選擇 Get pins from board_pins_config.c (這步是告訴系統“用我自己的圖紙”,優先級最高)。

  • Audio HAL -> Codec Chip -> 勾選 Enable ES8311 codec (啟用播放芯片驅動)。

  • Audio HAL -> Codec Chip -> 勾選 Enable ES7210 codec (啟用錄音芯片驅動)。

  • Audio HAL -> Codec Chip -> 取消勾選 其他所有芯片(如 ES8388)。

  • 完成后保存并退出。

讓主程序依賴您的新組件: 打開 play_mp3_control/main/CMakeLists.txt,在 REQUIRES 列表中加入 my_board

# file: play_mp3_control/main/CMakeLists.txtidf_component_register(SRCS "play_mp3_control_example.c"INCLUDE_DIRS "."REQUIRES esp_peripherals my_board) # <== 在這里加上 my_board

第四階段:驗證成功 —— 案件告破

完成了所有配置后,我們進行了最后的操作并驗證了結果。

1. 知識點講解

  • 最后的日志分析:當日志中 I2C 錯誤消失,并順利打印出 Receive music info from mp3 decoder... 時,代表硬件通信成功,軟件管線也已建立,程序進入了正常的工作流程。

2. 具體操作流程

徹底清理項目: 因為我們對配置和組件結構做了大改動,需要用 fullclean 來刪除所有舊的編譯產物,確保新配置能完全生效。

idf.py fullclean

編譯、燒錄并監控: 執行最終的命令,將正確的程序燒錄到您的 AtomS3 中,并打開串口監視器查看日志。

# 將 COMx 替換為您的實際端口號
idf.py build flash monitor -p COMx

執行后,您看到了成功的日志,這標志著我們解決了所有問題。

第五階段:項目擴展 —— 如何添加新功能(組件)

現在您的項目已經能跑通了,更重要的一步是如何在上面添加您自己的功能。您完全說對了,這正是通過管理組件和 CMakeLists.txt 來實現的。

核心理念: 在 ESP-IDF 中,一切皆為組件。您的 main 文件夾本身就是一個組件。添加新功能,本質上就是添加新的源文件到現有組件,或者創建一個全新的組件。

1. 方法一:在 main 組件內簡單添加(適用于簡單功能)

如果您的新功能不復雜,可以直接把代碼文件加到 main 里面。

  • 存放源文件 (.c):將您的 my_feature.c 文件直接放在 main 文件夾下。

  • 存放頭文件 (.h)最佳實踐是在 main 文件夾里新建一個 include 文件夾,然后把您的 my_feature.h 放在這個 main/include/ 里面。

文件結構示例:

play_mp3_control/
└── main/├── CMakeLists.txt├── main.c├── my_feature.c       <-- 新增的源文件└── include/└── my_feature.h   <-- 新增的頭文件
  • 如何包含頭文件?不需要手動修改 CMakeLists.txt!系統會自動把 include 目錄加入搜索路徑。因此,在 main.c 里,您可以直接這樣寫:

    #include "my_feature.h"

2. 方法二:創建獨立的組件(推薦用于復雜、可復用的功能)

如果您的功能比較獨立(比如一個特定傳感器的驅動),最好為它創建一個全新的組件。

  • 創建組件目錄:在項目根目錄的 components 文件夾下,創建一個新文件夾,比如 my_sensor

  • 組織文件:和 main 組件一樣,源文件放根目錄,頭文件放 include 子目錄。

  • 編寫組件的 CMakeLists.txt:這是最關鍵的一步。在 my_sensor 文件夾里創建一個 CMakeLists.txt,內容如下:

    # file: components/my_sensor/CMakeLists.txt# 列出這個組件包含的所有源文件
    set(SRCS "my_sensor.c") # 聲明這個組件的公共頭文件目錄
    set(INCLUDE_DIRS "include")# 注冊組件,并聲明它依賴哪些其他組件(例如 esp_log)
    idf_component_register(SRCS ${SRCS}INCLUDE_DIRS ${INCLUDE_DIRS}REQUIRES esp_log)
  • 如何使用新組件?使用方(比如 main 組件)的 CMakeLists.txt 里,聲明對它的依賴。

    # file: main/CMakeLists.txt
    idf_component_register(...REQUIRES esp_peripherals my_board my_sensor) # <== 在這里加上新組件

    完成之后,您就可以在 main.c 里直接 #include "my_sensor.h" 了。

總結:對于您“頭文件路徑應該放哪里”的核心問題,答案是:您不需要手動管理全局的頭文件路徑。您只需要遵循組件化的結構,將頭文件放在對應組件的 include 目錄里,然后在 CMakeLists.txt 中聲明好依賴關系(REQUIRES),ESP-IDF 的構建系統就會自動處理好一切。

【附錄】今日提問類型回顧

我們今天的互動非常有成效,您的提問清晰地展現了解決一個復雜技術問題的完整思路。我們可以把這些提問分為以下幾類:

類型一:錯誤日志分析與故障排除 這是我們互動的主線,也是所有調試工作的起點。您通過直接粘貼錯誤日志,讓我們能夠快速定位問題。

  • 具體提問:粘貼 fatal: unable to access...Empty reply from serverdubious ownershipI2C transaction unexpected nack detected 等錯誤日志。

  • 重要性:這是最高效的溝通方式,它提供了最直接的“案發現場”證據,幫助我們從網絡、配置、再到硬件層面逐一排查。

類型二:概念理解與知識擴展 在解決問題的過程中,您沒有滿足于“知其然”,而是進一步探究“所以然”,這對于構建穩固的知識體系至關重要。

  • 具體提問:“Audio HAL這是什么?”、“如果這個例程跑通我應該怎么添加其他的組件來實現更多的功能呢?”

  • 重要性:這類問題幫助我們從簡單的“復制代碼”提升到“理解架構”的層面,是成為一名優秀開發者的必經之路。

類型三:流程確認與狀態解讀 在面對不確定的過程時,您能及時提出疑問來確認當前的狀態是否正常,避免了因誤判而進行的不必要操作。

  • 具體提問:“他不動了不知道是不是好消息?”、“可是我剛剛還是按照你說的改了...那豈不是沖突,怎么辦呢?”

  • 重要性:在漫長的編譯或下載過程中,這類提問可以幫助判斷程序是在正常工作還是已經卡死。在修改復雜配置時,這類提問能澄清各個配置之間的關系,避免邏輯混淆。

類型四:總結與反思 在解決所有問題后,您主動要求進行總結和歸類,這是一個非常好的學習習慣。

  • 具體提問:“總結一下今天問答”、“幫我以上述回答的為大綱,詳細且通俗易懂的里面的知識點”、“今天我的提問分類型都要寫進去”。

  • 重要性:學習不僅僅是解決眼前的問題,更重要的是在事后進行復盤和歸納,將一次性的解決方案,沉淀為永久的、可復用的經驗和知識。

總而言之,您今天掌握了從解決基礎環境問題,到最終為非標準硬件進行底層驅動適配的全過程。這在嵌入式開發領域是一項非常核心且寶貴的技能。恭喜您!

參考:ESP32學習筆記(37)——搭建ESP-ADF(樂鑫音頻開發框架)_esp32 dlna-CSDN博客

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

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

相關文章

展開說說Android之Retrofit詳解_使用篇

Retrofit是由Square公司開發的類型安全HTTP客戶端框架&#xff0c;借助動態代理在運行時生成接口實現類&#xff0c;將注解轉化為OkHttp請求配置&#xff1b;節省成本通過轉換器(Gson/Moshi)自動序列化JSON/XML&#xff0c;內部處理網絡請求在主線程返回報文。Retrofit 直譯是封…

復古美學淺綠色文藝風格Lr調色教程,手機濾鏡PS+Lightroom預設下載!

調色介紹 復古美學淺綠色文藝風格 Lr 調色&#xff0c;是基于 Adobe Lightroom&#xff08;Lr&#xff09;軟件&#xff0c;為攝影作品賦予特定藝術氛圍的調色方式。通過合理設置軟件中的各項參數與工具&#xff0c;把照片調整為以淺綠色為主調&#xff0c;融合復古元素與文藝氣…

力扣網C語言編程題:缺失的第一個正數第三種解題方法

一. 簡介 前面文章學習了對該題目的兩種解題思路&#xff0c;文章如下&#xff1a; 力扣網C語言編程題&#xff1a;缺失的第一個正數-CSDN博客 但是前面的實現上在空間復雜度上沒有滿足要求。本文學習一種在空間復雜度上為 O(1)的思路。 二. 力扣網C語言編程題&#xff1a;缺…

PyTorch 實現 MNIST 手寫數字識別

PyTorch 實現 MNIST 手寫數字識別 MNIST 是一個經典的手寫數字數據集&#xff0c;包含 60000 張訓練圖像和 10000 張測試圖像。使用 PyTorch 實現 MNIST 分類通常包括數據加載、模型構建、訓練和評估幾個部分。 數據加載與預處理 使用 torchvision 加載 MNIST 數據集&#x…

Python內存互斥與共享深度探索:從GIL到分布式內存的實戰之旅

引言&#xff1a;并發編程的內存困局 在開發高性能Python應用時&#xff0c;我遭遇了這樣的困境&#xff1a;多進程間需要共享百萬級數據&#xff0c;而多線程間又需保證數據一致性。傳統解決方案要么性能低下&#xff0c;要么引發競態條件。本文將深入探討Python內存互斥與共…

【Unity】使用 C# SerialPort 進行串口通信

索引 一、SerialPort串口通信二、使用SerialPort1.創建SerialPort對象&#xff0c;進行基本配置2.寫入串口數據①.寫入串口數據的方法②.封裝數據 3.讀取串口數據①.讀取串口數據的方法②.解析數據 4.讀取串口數據的時機①.DataReceived事件②.多線程接收數據 5.粘包問題處理 一…

如何寫好單元測試:Mock 脫離數據庫,告別 @SpringBootTest 的重型啟動

如何寫好單元測試&#xff1a;Mock 脫離數據庫&#xff0c;告別 SpringBootTest 的重型啟動 作者&#xff1a;Killian&#xff08;重慶&#xff09; — 歡迎各位架構獵頭、技術布道者聯系我&#xff0c;項目實戰豐富&#xff0c;代碼穩健&#xff0c;Mock測試愛好者。 技術棧&a…

【DNS】在 Windows 下修改 `hosts` 文件

在 Windows 下修改 hosts 文件&#xff0c;一般用于本地 DNS 覆蓋。操作步驟如下&#xff08;以 Windows 10/11 為例&#xff09;&#xff1a; 1. 以管理員權限打開記事本 點擊 開始 → 輸入 “記事本”在“記事本”圖標上右鍵 → 選擇 以管理員身份運行 如果提示“是否允許此…

共享內存實現進程通信

目錄 system V共享內存 共享內存示意圖 共享內存函數 shmget函數 shmat函數 shmdt函數 shmctl函數 代碼示例 shm頭文件 構造函數 獲取key值 創建者的構造方式 GetShmHelper 函數 GetShmUseCreate 函數 使用者的構造方式 GetShmForUse 函數 分離附加操作 DetachShm 函數 AttachS…

6月15日星期日早報簡報微語報早讀

6月15日星期日&#xff0c;農歷五月二十&#xff0c;早報#微語早讀。 1、證監會擬修訂期貨公司分類評價&#xff1a;明確扣分標準&#xff0c;優化加分標準&#xff1b; 2、國家考古遺址公園再添10家&#xff0c;全國已評定65家&#xff1b; 3、北京多所高校禁用羅馬仕充電寶…

破解關鍵領域軟件測試“三重難題”:安全、復雜性、保密性

在國家關鍵領域&#xff0c;軟件系統正成為核心戰斗力的一部分。相比通用軟件&#xff0c;關鍵領域軟件在 安全性、復雜性、實時性、保密性 等方面要求極高。如何保障安全合規前提下提升測試效率&#xff0c;確保系統穩定&#xff0c;已成為軟件質量保障的核心挑戰。 關鍵領域…

記錄一次 Oracle DG 異常停庫問題解決過程

記錄一次 Oracle DG 異常停庫問題解決過程 某醫院有以下架構的雙節點 Oracle 集群&#xff1a; 節點1:172.16.20.2 節點2:172.16.20.3 SCAN IP&#xff1a;172.16.20.1 DG&#xff1a;172.16.20.1206月12日&#xff0c;醫院信息科用戶反映無法連接 DG 服務器。 登錄 DG 服務…

MySQL使用EXPLAIN命令查看SQL的執行計劃

1?、EXPLAIN 的語法 MySQL 中的 EXPLAIN 命令是用于分析 SQL 查詢執行計劃的關鍵工具,它能幫助開發者理解查詢的執行方式并找出性能瓶頸??。 語法格式: EXPLAIN <sql語句> 【示例】查詢學生表關聯班級表的執行計劃。 (1)創建班級信息表和學生信息表,并創建索…

Go語言2個協程交替打印

WaitGroup 無緩沖channel waitgroup 用來控制2個協程 Add() 、Done()、Wait() channel用來實現信號的傳遞和信號的打印 ch1: 用來記錄打印的信號 ch2:用來實現信號的傳遞&#xff0c;實現2個協程的順序打印 package mainimport ("fmt""sync" )func ma…

微信小程序 路由跳轉

路由方式 官方參考文檔 wx.switchTab 實現底部導航欄 1.配置信息 app.json"tabBar": {"custom": true,"list": [{"pagePath": "pages/home/index","text": "首頁"},{"pagePath": "p…

[Java 基礎]正則表達式

正則表達式是一種強大的文本模式匹配工具&#xff0c;它使用一種特殊的語法來描述要搜索或操作的字符串模式。在 Java 中&#xff0c;我們可以使用 java.util.regex包提供的類來處理正則表達式。 :::color3 正則表達式不止 Java 語言提供了相應的功能&#xff0c;很多其他語言…

ArcGIS安裝出現1606錯誤解決辦法

問題背景&#xff1a; 由于最近Arcgis10.2打是有些功能不正常退出&#xff0c;比如arctoolbox中的&#xff0c;table to excel 功能&#xff0c;只要一點擊&#xff0c;arcgis就報錯退出&#xff0c;平常在使用過程中&#xff0c;也經常出現一些莫名其妙的崩潰現象&#xff0c…

wpf 解決DataGridTemplateColumn中width綁定失效問題

感謝酪酪烤奶 提供的Solution 文章目錄 感謝酪酪烤奶 提供的Solution使用示例示例代碼分析各類交互流程 WPF DataGrid 列寬綁定機制分析整體架構數據流分析1. ViewModel到Slider的綁定2. ViewModel到DataGrid列的綁定a. 綁定代理(BindingProxy)b. 列寬綁定c. 數據流 關鍵機制詳…

語音轉文本ASR、文本轉語音TTS

ASR Automatic Speech Recognition&#xff0c;語音轉文本。 技術難點&#xff1a; 聲學多樣性 口音、方言、語速、背景噪聲會影響識別準確性&#xff1b;多人對話場景&#xff08;如會議錄音&#xff09;需要區分說話人并分離語音。 語言模型適配 專業術語或網絡新詞需要動…

通用embedding模型和通用reranker模型,觀測調研

調研Qwen3-Embedding和Qwen3-Reranker 現在有一個的問答庫&#xff0c;包括150個QA-pair&#xff0c;用10個query去同時檢索問答庫的300個questionanswer Embedding模型&#xff0c;query-question的匹配分數 普遍高于 query-answer的匹配分數。比如對于10個query&#xff0c…