stm32Flash操作

//G0B0 flash大小 0x08000000-0x0807FFFF 512K(0400 1K)//2k 1頁
//初始化標記數據地址 放最前面 脫機燒寫器可擦除掉
#define     CONST_INITMARKDATA_ADDRESS      (0x0807D000UL) //2k 1頁
//射頻數據地址
#define     CONST_FREQDATA_ADDRESS          (0x0807F000UL)  //2k 1頁
//本振數據地址
#define     CONST_BWLODATA_ADDRESS          (0x0807F800UL)//用戶數據標記
#define     CONST_USERDATA_ACTIVECOOKIE     (0xFEDCCDEF) 

========================================================================
__align(8) static uint8_t flashWriteBuf[2048];

  1. __align(8): 用于指定存儲在內存中的變量的對齊方式為 8 字節。對齊的目的是為了優化內存訪問,確保變量在內存中的地址是某個值的倍數(這里是 8 字節)。這通常對于某些硬件和特定的數據結構是必要的。
  2. static: 用于指示該變量的存儲持續時間為整個程序的執行期間。在這里,flashWriteBuf 是一個靜態變量,它在程序的整個執行期間都存在,并且其生命周期延伸到整個程序的運行時間。

這行代碼定義了一個靜態的、對齊為 8 字節的、包含 2048 個無符號8位整數的數組 flashWriteBuf

=========================================================================

為什么要使用 __align(8),以及對齊方式在內存中的表現是什么樣的?

在C語言中,對齊方式是指變量在內存中的存儲起始位置相對于地址的偏移量。
對齊的主要目的是優化內存訪問速度,特別是對于一些體系結構或硬件,它們可能要求某些數據類型的變量從特定地址開始。

  1. 訪問速度: 在某些架構中,對齊的數據訪問速度更快。例如,某些處理器可能要求訪問 4 字節整數從4字節對齊的地址開始,否則可能會引發性能損失或錯誤。

  2. 緩存行: 許多處理器以緩存行為單位加載數據到緩存中。如果變量的首地址是緩存行對齊的,那么對該變量的訪問可能會更加高效。

  3. 硬件限制: 某些硬件要求特定數據類型從特定對齊方式的地址開始。如果不滿足這些要求,可能會導致硬件異常或性能下降。

在具體的應用場景中,選擇對齊方式通常是為了優化性能或者滿足硬件的要求。然而,過度的對齊可能會導致內存空間的浪費。在實際開發中,對齊的選擇需要根據具體的硬件和性能需求進行權衡。

=========================================================================
1. 實現邏輯:

uint8_t* coreFlashAcquireWriteBuffer(void)
{return flashWriteBuf;
}

該函數返回一個 uint8_t 類型的指針。函數體內只有一條語句,即返回名為 flashWriteBuf 的靜態數組的首地址。

主要目的是獲取可用于寫入的緩沖區。由于返回的是指向 uint8_t 的指針,可以將這個指針用于寫入字節數據。

2. 主要目的和適用場景:
這段代碼的主要目的是提供一個接口,允許外部模塊或函數獲取一個可用于寫入的緩沖區。

這種模式常見于需要進行數據寫入或者數據緩沖的情境,例如將數據寫入到 Flash 存儲器中。

適用場景可能包括需要向 Flash 存儲器寫入數據的任務。通過調用 coreFlashAcquireWriteBuffer 函數,程序可以獲取一個緩沖區,然后將待寫入的數據寫入該緩沖區。
這種設計允許程序靈活地控制數據的寫入,同時提供了一種有效的機制來管理數據的寫入操作。

====================================================================
1. 實現邏輯:

static uint32_t getPage(uint32_t addr)
{uint32_t page = 0;/* Bank 1 */page = (addr - FLASH_BASE) / FLASH_PAGE_SIZE;return page;
}

? 這段代碼定義了一個靜態函數 getPage,接受一個 uint32_t 類型的地址參數,計算并返回與該地址相關的頁面號(page number)。在這個實現中,頁面號被計算為地址相對于基地址 FLASH_BASE 的偏移量除以頁面大小 FLASH_PAGE_SIZE

2. 主要目的和適用場景:

? 主要目的是根據給定的地址計算出相應的頁面號。

? 在嵌入式系統中,Flash存儲器通常分為多個頁面,每個頁面存儲一定量的數據。

? 獲取地址對應的頁面號可以用于確定數據在Flash中的位置。

? 適用場景可能包括在程序中管理Flash存儲器的情況,比如需要存儲和檢索數據到Flash中的特定頁面。通過調用 getPage 函數,程序可以獲得給定地址所在的頁面號,然后使用這個頁面號進行相應的操作,例如擦除或寫入數據。

總體而言,這個函數是一個用于獲取地址對應頁面號的工具函數,可以用于在嵌入式系統中管理Flash存儲器中的數據。

========================================================================
1. 實現邏輯:

int32_t coreFlashWrite(void* dstAddr, const void* srcAddr, const uint32_t size)
{//...(變量定義和初始化)//初始化FLASH_EraseInitTypeDefFLASH_EraseInitTypeDef eraseInitStruct = {0x00};int32_t ret = ERR_FLASHOP_OK;  // 返回值//判斷入參正確if (!srcAddr || !dstAddr || 0 == size){return ERR_FLASHOP_PARAM_INVAL;}if (0 != ((uint32_t)srcAddr & 0x00000007)){return ERR_FLASHOP_SRCADDR_UNALIGN;}if (0 != ((uint32_t)dstAddr & 0x00000007)){return ERR_FLASHOP_DSTADDR_UNALIGN;}//獲取要擦除的第一頁firstPage = getPage((uint32_t)dstAddr);//獲取要從第一頁擦除的頁數nbOfPages = size / FLASH_PAGE_SIZE + (size % FLASH_PAGE_SIZE ? 1 : 0);eraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;eraseInitStruct.Page        = firstPage;  // 擦除起始頁eraseInitStruct.NbPages     = nbOfPages;  // 擦除頁數HAL_FLASH_Unlock();  // Flash解鎖__disable_irq();  // 擦除前需要關閉中斷if (HAL_FLASHEx_Erase(&eraseInitStruct, &pageError) != HAL_OK){__enable_irq();ret = -ERR_FLASHOP_FAIL_ERASE;goto exit;}__enable_irq();//開始寫入FlashflashAddress = (uint32_t)dstAddr;nWriteAll = size;while (nHasWrite < nWriteAll){// 以64位為單位寫入數據srcDW = *(uint64_t*)((uint32_t)srcAddr + nHasWrite);if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flashAddress, srcDW) == HAL_OK){flashAddress += 8;nHasWrite += 8;}else{ret = ERR_FLASHOP_FAIL_PROG;goto exit;}}exit:HAL_FLASH_Lock();  // Flash加鎖return ret;
}

2. 主要目的和適用場景:

? 這段代碼的主要目的是實現Flash存儲器的寫入操作。該函數接受目標地址 dstAddr、源地址 srcAddr 和寫入大小 size 作為參數,首先擦除目標地址所在的Flash頁面,然后將數據從源地址寫入到目標地址。

? 適用場景可能涉及到需要在嵌入式系統中進行Flash存儲器的寫入操作,例如在固件更新或配置保存等場景。

3. 使用的關鍵字和修飾符:

  • static: 該函數沒有使用 static 關鍵字,因此在其他文件中可以訪問。
  • uint32_t, void, const: 這些是數據類型,用于聲明參數和變量的類型。
  • FLASH_EraseInitTypeDef: 這是一個結構體類型,用于配置Flash擦除的初始化參數。
  • HAL_FLASH_Unlock(), HAL_FLASH_Lock(): 這些是由HAL(Hardware Abstraction Layer)提供的函數,用于解鎖和鎖定Flash。

總體而言,這是一個用于在嵌入式系統中進行Flash存儲器寫入的函數,包括擦除和寫入兩個步驟。============================================================================
1. 實現邏輯:

bool initMarkDataIsActive(void)
{const volatile initMarkDataFlash_t* rawPtr = (const volatile initMarkDataFlash_t*)CONST_INITMARKDATA_ADDRESS;return (rawPtr->active == CONST_USERDATA_ACTIVECOOKIE);
}

這段代碼定義了一個函數 initMarkDataIsActive,該函數返回一個布爾值。函數內部首先聲明了一個指向 initMarkDataFlash_t 結構體類型的 volatile 常量指針 rawPtr,然后將其初始化為指向一個特定地址 CONST_INITMARKDATA_ADDRESS

函數最后通過比較 rawPtr->activeCONST_USERDATA_ACTIVECOOKIE 的值來確定初始化標記數據是否處于激活狀態。

2. 主要目的和適用場景:

? 主要目的是檢查初始化標記數據是否處于激活狀態。在嵌入式系統中,可能會有一些標記數據用于指示系統的初始化狀態,這個函數就是用于檢查這些標記數據是否處于激活狀態。

? 適用場景可能包括在系統啟動時檢查某些初始化數據,以確保系統處于已初始化的狀態。

3. 使用的關鍵字和修飾符:

  • const, volatile: 這些關鍵字用于修飾指針 rawPtr,指明該指針指向的數據是常量且易變的,這通常用于防止編譯器進行一些優化,確保每次訪問都會從內存中讀取最新的值。

總體而言,這個函數用于檢查初始化標記數據是否處于激活狀態,返回一個布爾值表示檢查結果。

=========================================================================
1. 實現邏輯:

void initMarkDataReadFlash(void)
{const volatile initMarkDataFlash_t *rawPtr = (const volatile initMarkDataFlash_t*)CONST_INITMARKDATA_ADDRESS;if (initMarkDataIsActive()){memcpy(&initMarkDataFlash, (void*)rawPtr, sizeof(initMarkDataFlash_t));}
}

函數內部首先聲明了一個指向 initMarkDataFlash_t 結構體類型的 volatile 常量指針 rawPtr,然后將其初始化為指向一個特定地址 CONST_INITMARKDATA_ADDRESS

接著,通過調用 initMarkDataIsActive 函數檢查初始化標記數據是否處于激活狀態。如果激活,那么通過 memcpy 函數將 Flash 中的數據復制到一個全局變量 initMarkDataFlash 中。

2. 主要目的和適用場景:

? 主要目的是在系統啟動時從 Flash 中讀取初始化標記數據。在嵌入式系統中,初始化標記數據可能包含一些配置信息或者系統狀態,該函數的目的是將這些數據讀取到內存中,以便系統可以使用這些數據進行初始化。

? 適用場景可能包括在系統啟動時加載先前保存的配置或狀態信息,以確保系統處于正確的狀態。

總體而言,這個函數用于從 Flash 中讀取初始化標記數據,如果數據處于激活狀態,則將其復制到全局變量中。

=======================================================================
1. 實現邏輯:

int32_t initMarkDataSyncFlash(void)
{int32_t ret = 0;//用戶數據寫入ret = coreFlashWrite((void*)CONST_INITMARKDATA_ADDRESS, (void*)&initMarkDataFlash, sizeof(initMarkDataFlash_t));return ret;
}

函數內部首先聲明了一個整數變量 ret,用于存儲函數執行的結果。

接著,通過調用 coreFlashWrite 函數將全局變量 initMarkDataFlash 中的數據寫入到 Flash 中的指定地址 CONST_INITMARKDATA_ADDRESS

最后,函數返回執行的結果。

2. 主要目的和適用場景:

? 主要目的是將全局變量 initMarkDataFlash 中的數據同步到 Flash 中的指定地址。在嵌入式系統中,這可能用于將配置或狀態信息保存到 Flash 中,以便在系統重新啟動時恢復狀態。

? 適用場景可能包括在系統運行時修改了一些配置或狀態信息,希望將這些更改保存到持久性存儲中。

總體而言,這個函數用于將全局變量中的數據寫入到 Flash 中的指定地址,返回一個表示執行結果的整數值。

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

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

相關文章

大數據技術4:Lambda和Kappa架構區別

前言&#xff1a;在大數據處理領域&#xff0c;兩種突出的數據架構已成為處理大量數據的流行選擇&#xff1a;Lambda 架構和 Kappa 架構。這些架構為實時處理和批處理提供了強大的技術解決方案&#xff0c;使組織能夠從其數據中獲得有價值的見解。隨著互聯網時代來臨&#xff0…

Python VSCode 配置固定的腳本入口

Python VSCode 配置固定的腳本入口 打開或者新建一個啟動配置 選擇 .vscode目錄下 launch.json文件 將 “program”: “${file}” 替換成 “program”: “mian.py”, //完成你自己的入口.py文件名即可 json啟動配置文件 {// Use IntelliSense to learn about possible attrib…

4-redis高級-redis持久化(RDB 持久化方案、AOF持久化、RDB和AOF混合持久化)、redis主從復制

1 redis持久化 1.1 RDB 持久化方案 1.2 AOF持久化 1.3 混合持久化 2 redis主從復制 1 redis持久化 # 把redis數據從內存保存到硬盤上的過程稱之為持久化# 所有的數據庫&#xff0c;持久化方案快照&#xff1a;某時某刻數據的一個完成備份-mysql的Dump&#xff1a; mysqldump …

【ELK03】ES 索引的Mapping映射詳解、數據類型和settings屬性設置

一、ES 索引的映射和設置 1.MAPPING 映射(MAPPING)就是es中一個決定了文檔如何存儲,如何生成索引,字段各種類型定義的過程.類似于我們在關系型數據庫中創建一個表格數據之前先定義表格有哪些字段,每個字段是什么類型,然后數據會按照這個配置寫入表格,ES中同樣是這個過程,它由…

數據結構:順序表——相關習題2

【2018統考】給定一個含n個整數的數組&#xff0c;設計一個時間上盡可能高效的算法&#xff0c;找到數組中未出現的最小正整數。 void find_min_intnum(int A[],int n){int B[5*n]{0};int i;for (i 0; i < n; i){if(A[i]>0){B[A[i]];}}for(i1;i<5*n;i){if(B[i]0){pr…

面向對象中的單例模式

1、什么是設計模式 設計模式就是前人根據實際的問題提出的問題解決方案&#xff0c;我們把這種就稱之為設計模式。 2、單例模式 單例模式是一種常見的設計模式&#xff01; 所謂的設計模式&#xff0c;不是一種新的語法&#xff0c;而是人們在實際的應用中&#xff0c;面對…

【銀行測試】金融項目+測試方法范圍分析,功能/接口/性能/安全...

目錄&#xff1a;導讀 前言一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 1、金融行業軟件特…

3GPP標準查看、下載和幾個UE相關系列標準

由于一直做終端側協議。最近以UE為核心重新下載了一系列文檔。 總結并舉例一下分類標準。 如何查看3GPP標準列表 實際上在3GPP網站如下鏈接&#xff1a;Specifications by Series&#xff0c;每個系列以及分類都說的很清楚。 幾個系列分類舉例 和終端協議層工作比較關系密切…

如何使用Java Websocket實現實時數據監控功能?

隨著互聯網應用的不斷發展&#xff0c;實時數據監控功能成為了許多應用的必備功能之一。本文將介紹如何使用Java WebSocket實現實時數據監控功能&#xff0c;并提供具體的代碼示例。 關鍵詞&#xff1a;Java WebSocket、實時數據監控、代碼示例 一、什么是WebSocket&#xff…

ModuleNotFoundError: No module named ‘dlib‘

解決&#xff1a;ModuleNotFoundError: No module named ‘dlib’ 文章目錄 解決&#xff1a;ModuleNotFoundError: No module named dlib背景報錯問題報錯翻譯報錯位置代碼報錯原因解決方法方法一&#xff0c;直接安裝方法二&#xff0c;手動下載安裝方法三&#xff0c;編譯安…

setuid 的風險及開發過程中的避免方式

使用setuid&#xff08;Set User ID&#xff09;功能將執行程序的有效用戶 ID 設置為文件所有者的用戶 ID。這意味著執行程序將以文件所有者的特權運行&#xff0c;而不是以執行者自己的特權運行。 盡管setuid是一個有用的功能&#xff0c;但它也會帶來一些安全風險。下面是幾…

Linux C語言 37- 進程間通信IPC

Linux C語言 37-進程間通信IPC 本節關鍵字&#xff1a;C語言 進程間通信 信號 管道 消息隊列 共享內存 網絡通信&#xff08;套接字&#xff09; 相關庫函數&#xff1a; 提示&#xff1a;先做內容框架梳理&#xff0c;后期進行完善補充&#xff01; 什么是進程間通信&#…

blender 數字鍵盤上的快捷鍵

數字0可以切換到相機視角&#xff0c;即從相機的位置和角度查看場景。數字1、3、7分別可以切換到正交的前視圖、右視圖和頂視圖&#xff0c;即沿著X、Y、Z軸的垂直投影。數字5可以切換正交視圖和透視視圖&#xff0c;即是否考慮遠近的視覺差異。數字2、4、6、8分別可以順時針或…

SD之lora訓練

目錄 為什么要訓練自己的模型 SD模型微調方法 準備素材 1 確定要訓練的LoRA類型 2 圖片收集 3 圖片預處理 4 圖片標注 安裝Koyha_ss 訓練lora 1.準備參數和環境 2.啟動訓練 使用模型 1 拷貝訓練過的lora模型 2 啟動SD WebUI進行圖像生成 為什么要訓練自己的模型 …

webpack該如何打包

1.我們先創建一個空的大文件夾 2.打開該文件夾的終端 輸入npm init -y 2.1.打開該文件夾的終端 2.2在該終端運行 npm init -y 3.安裝webpack 3.1打開webpack網址 點擊“中文文檔” 3.2點擊“指南”在點擊“起步” 3.3復制基本安裝圖片畫線的代碼 4.在一開始的文件夾下在創建一…

【Android】使用Netty庫來實現Socket接收

在Android中使用Netty來實現Socket接收是可行的。Netty是一個高性能的網絡通信框架&#xff0c;支持多種協議&#xff0c;包括原生的Socket通信。 以下是一個簡單的示例代碼&#xff0c;演示如何使用Netty在Android中實現Socket接收&#xff1a; 首先&#xff0c;在你的Andro…

案例061:基于微信小程序的互助學習系統

文末獲取源碼 開發語言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 數據庫&#xff1a;mysql 5.7 開發軟件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序開發軟件&#xff1a;HBuilder X 小程序…

Flask template中使用iframe

Flaks template中使用iframe嵌套新的網頁&#xff08;new_page.html&#xff09;的網頁到歷史網頁&#xff08;old_page.html&#xff09;中&#xff08;減少新網頁的入口&#xff09; 1,增加iframe tag 在old_page.html中適當位置增加iframe入口標簽&#xff1a; <ifram…

django與數據庫交互關于當前時間的坑

背景 在線上服務中使用時間進行數據庫操作時發現異常&#xff0c;而在本地環境無法成功復現此問題&#xff0c;導致難以進行故障排查。 核心問題 view.py class XxxViewSet(viewsets.ModelViewSet):queryset Xxx.objects.with_status().order_by("status", &quo…

【數據結構】插入排序,希爾排序,選擇排序,堆排序,冒泡排序

1.插入排序 思路&#xff1a;插入排序將一個數插入一個有序的數組里面&#xff0c;將這個數和數組元素挨著比較&#xff0c;直到他插入到合適的位置。 動畫演示&#xff1a; 步驟&#xff1a;1.定義一個變量tmp保存要插入的數據 2.在循環中用tmp和有序數組中的元素比較&#…