SOC-ESP32S3部分:21-非易失性存儲庫

飛書文檔https://x509p6c8to.feishu.cn/wiki/QB0Zw7GLeio4l4kyaWQcuQT3nZS

非易失性存儲 (NVS) 庫主要用于在 flash 中存儲鍵值格式的數據。

它允許我們在芯片的閃存中存儲和讀取數據,即使在斷電后,這些數據也不會丟失。

NVS 是 ESP32 flash(flash就是板子上的一個存儲芯片)中的一個存儲分區,我們可以在其中存儲鍵值對(key-value pairs)。每個鍵值對都有一個唯一的鍵名(key name)和一個對應的值(value)。這種組合類似于哈希表的(key-value)對應結構。

初始化NVS

在開始使用NVS之前,需要先初始化整個NVS分區。通常在應用程序啟動階段完成這一操作

esp_err_t nvs_flash_init(void);
返回值
esp_err_t
表示函數執行的結果,通常為以下幾種情況:
ESP_OK: 成功初始化 NVS(Non-Volatile Storage)閃存。
ESP_ERR_NVS_NO_FREE_PAGES: NVS 分區沒有可用的頁。
ESP_ERR_NVS_NEW_VERSION_FOUND: NVS 分區版本更新,需要格式化。
ESP_ERR_NVS_NOT_INITIALIZED: NVS 未初始化。
ESP_ERR_NVS_INVALID_STATE: NVS 已經初始化。
其他可能的錯誤代碼,具體取決于底層實現。示例參考:
#include <nvs_flash.h>
void app_main()
{esp_err_t err = nvs_flash_init();if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {// 若由于分區版本更新或無可用頁,嘗試格式化并重新初始化ESP_ERROR_CHECK(nvs_flash_erase());err = nvs_flash_init();}ESP_ERROR_CHECK(err);
}

使用 NVS 存儲數據

我們可以使用 nvs_open nvs_set_*nvs_commit三個函數來存儲數據。

nvs_open 函數用于打開一個 NVS 命名空間,并返回一個句柄,通過該句柄可以進行后續的讀寫操作。
esp_err_t nvs_open(const char *name, nvs_open_mode_t open_mode, nvs_handle_t *out_handle);
參數
const char *name: NVS 命名空間的名稱。命名空間用于組織存儲的數據,類似于文件夾的概念。
nvs_open_mode_t open_mode: 打開命名空間的模式,可以是以下幾種:
NVS_READONLY: 只讀模式。
NVS_READWRITE: 讀寫模式。
nvs_handle_t *out_handle: 輸出參數,用于返回打開的命名空間的句柄。通過這個句柄可以進行后續的讀寫操作。nvs_set_i32 函數用于將一個 32 位整數值存儲到 NVS 中,使用指定的鍵名標識該數據。存儲的數據可以通過該鍵名在后續的讀取操作中檢索。
esp_err_t nvs_set_i32(nvs_handle_t handle, const char *key, int32_t value);
參數
nvs_handle_t handle: 通過 nvs_open 函數獲得的命名空間句柄。
const char *key: 要存儲的數據的鍵名。鍵名用于標識存儲的數據。
int32_t value: 要存儲的 32 位整數值。nvs_commit 函數用于將對 NVS 命名空間所做的更改(如設置、刪除鍵值對等)提交到閃存中。
在調用 nvs_set_i32 或其他設置函數后,必須調用 nvs_commit 以確保更改被持久化到 NVS 分區中。
如果不調用 nvs_commit,更改將不會保存到閃存中,下次讀取時將不會看到這些更改
esp_err_t nvs_commit(nvs_handle_t handle);
參數
nvs_handle_t handle: 通過 nvs_open 函數獲得的命名空間句柄。// 存儲數據
nvs_handle_t my_handle;
esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_handle);??????? //打開命名空間
if (err == ESP_OK) {err = nvs_set_i32(my_handle, "restart_counter", 1);if (err == ESP_OK) {err = nvs_commit(my_handle);}nvs_close(my_handle);
}

在這個例子中,我們首先打開了一個名為 “storage” 的 NVS 名稱空間,然后在其中存儲了一個鍵名為 “restart_counter”、值為1的鍵值對。

而nvs_commit()函數的主要作用是將所有掛起的更改寫入NVS。當你在NVS中設置一個鍵值對后,這個更改首先被存儲在內存中。只有當你調用nvs_commit()函數時,這些更改才會被寫入閃存。

所以,如果你在調用nvs_commit()函數之前重啟了設備,那么你在NVS中設置的所有鍵值對都將丟失。因此,每次在NVS中設置鍵值對后,都應該調用nvs_commit()函數,以確保這些更改在設備重啟后仍然存在。

當然,還有其它不同類型的數據存儲接口

nvs_set_i8
功能: 存儲 8 位整數。
esp_err_t nvs_set_i8(nvs_handle_t handle, const char *key, int8_t value);nvs_set_u8
功能: 存儲 8 位無符號整數。
esp_err_t nvs_set_u8(nvs_handle_t handle, const char *key, uint8_t value);nvs_set_i16
功能: 存儲 16 位整數。
esp_err_t nvs_set_i16(nvs_handle_t handle, const char *key, int16_t value);nvs_set_u16
功能: 存儲 16 位無符號整數。
esp_err_t nvs_set_u16(nvs_handle_t handle, const char *key, uint16_t value);nvs_set_u32
功能: 存儲 32 位無符號整數。
esp_err_t nvs_set_u32(nvs_handle_t handle, const char *key, uint32_t value);nvs_set_i64
功能: 存儲 64 位整數。
esp_err_t nvs_set_i64(nvs_handle_t handle, const char *key, int64_t value);nvs_set_u64
功能: 存儲 64 位無符號整數。
esp_err_t nvs_set_u64(nvs_handle_t handle, const char *key, uint64_t value);nvs_set_str
功能: 存儲字符串。
esp_err_t nvs_set_str(nvs_handle_t handle, const char *key, const char *value);
參數:
handle: NVS 命名空間句柄。
key: 鍵名。
value: 要存儲的字符串。nvs_set_blob
功能: 存儲二進制數據塊。
esp_err_t nvs_set_blob(nvs_handle_t handle, const char *key, const void *value, size_t length);
參數:
handle: NVS 命名空間句柄。
key: 鍵名。
value: 要存儲的二進制數據塊。
length: 數據塊的長度(以字節為單位)。使用示例:// 存儲不同類型的數據err = nvs_set_i8(my_handle, "int8_key", 10);ESP_ERROR_CHECK(err);err = nvs_set_u8(my_handle, "uint8_key", 20);ESP_ERROR_CHECK(err);err = nvs_set_i16(my_handle, "int16_key", 300);ESP_ERROR_CHECK(err);err = nvs_set_u16(my_handle, "uint16_key", 400);ESP_ERROR_CHECK(err);err = nvs_set_u32(my_handle, "uint32_key", 5000);ESP_ERROR_CHECK(err);err = nvs_set_i64(my_handle, "int64_key", 60000);ESP_ERROR_CHECK(err);err = nvs_set_u64(my_handle, "uint64_key", 70000);ESP_ERROR_CHECK(err);const char *str_value = "Hello, NVS!";err = nvs_set_str(my_handle, "str_key", str_value);ESP_ERROR_CHECK(err);uint8_t blob_value[] = {0x01, 0x02, 0x03, 0x04};size_t blob_length = sizeof(blob_value);err = nvs_set_blob(my_handle, "blob_key", blob_value, blob_length);ESP_ERROR_CHECK(err);

使用 NVS 讀取數據

我們可以使用 nvs_get_* 函數來讀取數據。例如,我們可以使用 nvs_get_i32 函數來讀取一個整數:

nvs_get_i32 函數用于從 NVS 中讀取一個 32 位整數值,使用指定的鍵名標識該數據。讀取的數據存儲在輸出參數中,可以通過該參數訪問。
esp_err_t nvs_get_i32(nvs_handle_t handle, const char *key, int32_t *out_value);
參數
nvs_handle_t handle: 通過 nvs_open 函數獲得的命名空間句柄。const char *key: 要讀取的數據的鍵名。鍵名用于標識存儲的數據。int32_t *out_value: 輸出參數,用于存儲從 NVS 中讀取的 32 位整數值。使用參考
// 檢索數據
nvs_handle_t my_handle;
esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_handle);
if (err == ESP_OK) {int32_t value;err = nvs_get_i32(my_handle, "restart_counter", &value);if (err == ESP_OK) {printf("Value = %d\n", value);}nvs_close(my_handle);
}

刪掉NVS上的數據

esp_err_t nvs_flash_erase(void);
返回值
esp_err_t
表示函數執行的結果,通常為以下幾種情況:
ESP_OK: 成功擦除 NVS 分區。
ESP_ERR_NVS_NOT_INITIALIZED: NVS 未初始化。
ESP_ERR_NVS_INVALID_STATE: NVS 處于無效狀態。
其他可能的錯誤代碼,具體取決于底層實現

最終參考程序:

#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_log.h"static const char *TAG = "NVS"; // 定義日志標簽void app_main(void)
{// 初始化 NVSesp_err_t err = nvs_flash_init();if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {// NVS 分區被截斷,需要擦除// 重新初始化 nvs_flashESP_ERROR_CHECK(nvs_flash_erase());err = nvs_flash_init();}ESP_ERROR_CHECK(err);// 打開命名空間ESP_LOGI(TAG, "打開非易失性存儲 (NVS) 句柄...");nvs_handle_t my_handle;err = nvs_open("storage", NVS_READWRITE, &my_handle);if (err != ESP_OK) {ESP_LOGI(TAG, "打開 NVS 句柄時出錯 (%s)!\n", esp_err_to_name(err));} else {// 讀取重啟計數器ESP_LOGI(TAG, "從 NVS 讀取重啟計數器 ... ");int32_t restart_counter = 0; // 如果 NVS 中未設置值,則默認為 0err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);ESP_LOGI(TAG, "重啟計數器 = %" PRIu32 "\n", restart_counter);// 更新重啟計數器ESP_LOGI(TAG, "更新 NVS 中的重啟計數器 ... ");restart_counter++;err = nvs_set_i32(my_handle, "restart_counter", restart_counter);// 提交寫入的值。設置任何值后,必須調用 nvs_commit() 以確保更改寫入閃存存儲。ESP_LOGI(TAG, "提交 NVS 中的更改 ... ");err = nvs_commit(my_handle);// 關閉命名空間nvs_close(my_handle);}ESP_LOGI(TAG, "\n");// 重啟模塊for (int i = 10; i >= 0; i--) {ESP_LOGI(TAG, "將在 %d 秒后重啟...\n", i);vTaskDelay(1000 / portTICK_PERIOD_MS);}ESP_LOGI(TAG, "現在重啟。\n");fflush(stdout);esp_restart();
}

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

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

相關文章

讓大模型看得見自己的推理 — KnowTrace結構化知識追蹤

讓大模型“看得見”自己的推理 —— KnowTrace 結構化知識追蹤式 RAG 全解析 一句話概括:把檢索-推理“改造”成 動態知識圖構建任務,再讓 LLM 只關注這張不斷精煉的小圖 —— 這就是顯式知識追蹤的核心價值。 1. 背景:為什么 RAG 仍難以搞定多跳推理? 長上下文負擔 傳統 I…

新版智慧景區信息化系統解決方案

該智慧景區信息化系統解決方案以云 + 大數據 + 物聯網技術為核心,秉持 “匯聚聯合,突顯數據隱性價值” 理念,通過數據融合、業務融合、技術融合,構建 “營銷、服務、管理” 三位一體模式。方案涵蓋智慧票務、智能入園、精準營銷、景區管理(如用電安全監測、森林防火、客流…

人工智能在智能健康監測中的創新應用與未來趨勢

隨著人們健康意識的不斷提高和醫療資源的日益緊張&#xff0c;智能健康監測作為一種新興的健康管理方式&#xff0c;正在迅速發展。人工智能&#xff08;AI&#xff09;技術通過其強大的數據分析和預測能力&#xff0c;為智能健康監測提供了重要的技術支持。本文將探討人工智能…

python打卡day40

知識點回顧&#xff1a; 彩色和灰度圖片測試和訓練的規范寫法&#xff1a;封裝在函數中展平操作&#xff1a;除第一個維度batchsize外全部展平dropout操作&#xff1a;訓練階段隨機丟棄神經元&#xff0c;測試階段eval模式關閉dropout 導入包 # 先繼續之前的代碼 import torch …

系統性學習C語言-第十二講-深入理解指針(2)

系統性學習C語言-第十二講-深入理解指針&#xff08;2&#xff09; 1. const 修飾指針1.1 const 修飾變量1.2 const 修飾指針變量 2. 野指針2.1 野指針成因2.2 如何規避野指針2.2.1 指針初始化2.2.2 小心指針越界2.2.3 指針變量不再使用時&#xff0c;及時置 NULL &…

《高等數學》(同濟大學·第7版) 第一節《映射與函數》超詳細解析

集合&#xff08;Set&#xff09;—— 最基礎的數學容器 定義&#xff1a; 集合是由確定的、互不相同的對象&#xff08;稱為元素&#xff09;組成的整體。 表示方法&#xff1a; 列舉法&#xff1a;A {1, 2, 3} 描述法&#xff1a;B {x | x > 0}&#xff08;表示所有大于…

Spring Boot整活指南:從Helo World到“真香”定律

&#x1f4cc; 一、Spring Boot的"真香"本質&#xff08;不是996的福報&#xff09; 你以為Spring Boot只是個簡化配置的工具&#xff1f;Too young&#xff01;它其實是程序員的??摸魚加速器??。 ??經典場景還原??&#xff1a; 產品經理&#xff1a;“這個…

打字練習:平臺推薦

1.打字練習 . 1&#xff09;平臺推薦 下面推薦兩個打字練習平臺 Keybr&#xff1a;https://www.keybr.com/ TypingClub&#xff1a;https://www.edclub.com/sportal/ . 2&#xff09;平臺對比 特性KeybrTypingClub核心優勢AI智能弱項訓練結構化課程體系適合人群開發者/…

ASP.NET Core 中JWT的基本使用

文章目錄 前言一、JWT與RBAC二、JWT 的作用三、RBAC 的核心思想四、使用1、配置文件 (appsettings.json)2、JWT配置模型 (Entity/JwtSettings.cs)3、服務擴展類&#xff0c;JWT配置 (Extensions/ServiceExtensions.cs)4、用戶倉庫接口服務5、認證服務 (Interface/IAuthService.…

(19)java在區塊鏈中的應用

&#x1f517; Java在區塊鏈中的應用&#xff1a;智能合約開發全攻略 TL;DR: Java在區塊鏈領域主要通過Hyperledger Fabric、Web3j和專用JVM實現智能合約開發&#xff0c;相比Solidity具有更強的企業級支持和開發效率&#xff0c;但在執行效率和Gas消耗方面存在差異&#xff0c…

深入理解設計模式之訪問者模式

深入理解設計模式之訪問者模式&#xff08;Visitor Pattern&#xff09; 一、什么是訪問者模式&#xff1f; 訪問者模式&#xff08;Visitor Pattern&#xff09;是一種行為型設計模式。它的主要作用是將數據結構與數據操作分離&#xff0c;使得在不改變數據結構的前提下&…

div或button一些好看實用的 CSS 樣式示例

1&#xff1a;現代漸變按鈕 .count {width: 800px;background: linear-gradient(135deg, #72EDF2 0%, #5151E5 100%);padding: 12px 24px;border-radius: 10px;box-shadow: 0 4px 15px rgba(81, 81, 229, 0.3);color: white;font-weight: bold;border: none;cursor: pointer;t…

【基于STM32的新能源汽車智能循跡系統開發全解析】

基于STM32的新能源汽車智能循跡系統開發全解析&#xff08;附完整工程代碼&#xff09; 作者聲明 作者&#xff1a; 某新能源車企資深嵌入式工程師&#xff08;專家認證&#xff09; 技術方向&#xff1a; 智能駕駛底層控制 | 車規級嵌入式開發 原創聲明&#xff1a; 本文已申…

HTML Day02

Day02 0. 引言1. 文本格式化1.1 HTML文本格式化標簽1.2 HTML"計算機輸出"標簽1.3 HTML 引文&#xff0c;引用及標簽定義 2. HTML鏈接2.1鏈接跳轉原理&#xff08;有點亂可跳過&#xff09;2.2 HTML超鏈接2.3 target屬性2.4 id屬性2.4.1 id屬性在頁面內和不同頁面的定…

MIT 6.S081 2020 Lab6 Copy-on-Write Fork for xv6 個人全流程

文章目錄 零、寫在前面一、Implement copy-on write1.1 說明1.2 實現1.2.1 延遲復制與釋放1.2.2 寫時復制 零、寫在前面 可以閱讀下 《xv6 book》 的第五章中斷和設備驅動。 問題 在 xv6 中&#xff0c;fork() 系統調用會將父進程的整個用戶空間內存復制到子進程中。**如果父…

xhr、fetch和axios

XMLHttpRequest (XHR) XMLHttpRequest 是最早用于在瀏覽器中進行異步網絡請求的 API。它允許網頁在不刷新整個頁面的情況下與服務器交換數據。 // 創建 XHR 對象 const xhr new XMLHttpRequest();// 初始化請求 xhr.open(GET, https://api.example.com/data, true);// 設置請…

電腦驅動程序更新工具, 3DP Chip 中文綠色版,一鍵更新驅動!

介紹 3DP Chip 是一款免費的驅動程序更新工具&#xff0c;可以幫助用戶快速、方便地識別和更新計算機硬件驅動程序。 驅動程序更新工具下載 https://pan.quark.cn/s/98895d47f57c 軟件截圖 軟件特點 簡單易用&#xff1a;用戶界面簡潔明了&#xff0c;操作方便&#xff0c;…

機器學習與深度學習06-決策樹02

目錄 前文回顧5.決策樹中的熵和信息增益6.什么是基尼不純度7.決策樹與回歸問題8.隨機森林是什么 前文回顧 上一篇文章地址&#xff1a;鏈接 5.決策樹中的熵和信息增益 熵和信息增益是在決策樹中用于特征選擇的重要概念&#xff0c;它們幫助選擇最佳特征進行劃分。 熵&#…

【Kotlin】數字字符串數組集合

【Kotlin】簡介&變量&類&接口 【Kotlin】數字&字符串&數組&集合 文章目錄 Kotlin_數字&字符串&數組&集合數字字面常量顯式轉換數值類型轉換背后發生了什么 運算字符串字符串模板字符串判等修飾符數組集合通過序列提高效率惰性求值序列的操…

oscp練習PG Monster靶機復現

端口掃描 nmap -A -p- -T4 -Pn 192.168.134.180 PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.41 ((Win64) OpenSSL/1.1.1c PHP/7.3.10) |_http-server-header: Apache/2.4.41 (Win64) OpenSSL/1.1.1c PHP/7.3.10 | http-methods:…