STM32單片機實現串口IAP升級

一.概述

1.要實現串口IAP升級,首先要編寫一個bootloader程序,然后再寫支持IAP的app程序;

2.keil下bootloader的程序rom和ram設置

3.app程序要用bin文件

注:本文以STM32H743舉例,其他stm32單片機IAP升級原理類似。

二.實現

1.bootloder程序實現

(1)基本知識

?????stm32的flash地址起始于0x0800 0000,結束地址是0x0800 0000加上芯片實際的flash大小,不同的芯片flash大小不同。

?????RAM起始地址是0x2000 0000,結束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。

(2)STM32H743 bootloader設置

說明:由于 STM32H7 的扇區大小固定為 128KB 一個,最小擦除單位也是以扇區為單位的,因此,至少分配一個扇區給 Bootloader,否則后續擦寫 APP 的時候,可能把 Bootloader 也給擦了!所以,我們使用 128K(0X20000)字節來存放 Bootloader。

(3)代碼實現

int main(void)

{

u8 t;

u16 wait_s = 0;

u8 key;

u32 applenth=0; ????????//接收到的app代碼長度

u8 clearflag=0; ?

u32 Buffer[4];

Cache_Enable(); ??????????????//打開L1-Cache

HAL_Init(); ???????? //初始化HAL庫

Stm32_Clock_Init(160,5,2,4); ? ????//設置時鐘,400Mhz

delay_init(400); //延時初始化

uart_init(115200); //串口初始化

LED_Init(); //初始化LED

KEY_Init(); //初始化按鍵

SDRAM_Init(); ????????????//初始化SDRAM

while(1)

{

? if(USART_RX_STA&0x8000)

{

????????USART_RX_STA=0; ??? //清空 ??

applenth=USART_RX_CNT; ???// ?applenth

USART_RX_CNT=0;

printf("用戶程序接收完成!\r\n");

printf("代碼長度:%dBytes\r\n",applenth);

}

else

{

??if(wait_s >= 500)

{

??wait_s = 0;

??printf("等待用法發送程序... ?\r\n");

}

}

t++;

wait_s ++;

delay_ms(10);

if(t==30)

{

LED0_Toggle;

t=0;

if(clearflag)

{

clearflag--;

}

} ?? ?

key=KEY_Scan(0);

if(key==WKUP_PRES) //WK_UP按鍵按下

{

if(applenth)

{

printf("開始更新固件...\r\n");

? if(((*(vu32*)(0x24001000+4))&0xFF000000)==0x08000000)//判斷是否為0X08XXXXXX.

{ ?

iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代碼 ??#define FLASH_APP1_ADDR 0x08020000

printf("固件更新完成!\r\n");

}else

{

printf("非FLASH應用程序!\r\n");

}

? }else

{

printf("沒有可以更新的固件!\r\n");

}

clearflag=7;//標志更新了顯示,并且設置7*300ms后清除顯示 ?

}

if(key==KEY1_PRES) //KEY1按下

{

if(applenth)

{ ?

printf("固件清除完成!\r\n"); ???

applenth=0;

}else ?

{

printf("沒有可以清除的固件!\r\n");

}

clearflag=7;//標志更新了顯示,并且設置7*300ms后清除顯示 ?

}

if(key==KEY2_PRES) //KEY2按下

{

printf("開始執行FLASH用戶代碼!!\r\n");

if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判斷是否為0X08XXXXXX.

{ ?

iap_load_app(FLASH_APP1_ADDR);//執行FLASH APP代碼 ?

}else

{

printf("非FLASH應用程序,無法執行!\r\n"); ??

} ?

clearflag=7;//標志更新了顯示,并且設置7*300ms后清除顯示 ??

}

} ?????

}

(4)代碼功能邏輯:

需要先按下 KEY_UP 按鍵,將串口接收到的 APP 程序存放到 STM32 的內部 FLASH;

再按 KEY2 既可以執行這個 FLASH APP 程序。

通過 KEY1 按鍵,可以手動清除串口接收到的APP 程序。

DS0 用于指示程序運行狀態。

2.app程序及邏輯

(1)IAP流程邏輯

(2)keil設置

(3)代碼實現

int main(void)

{

??SCB->VTOR = FLASH_BASE|0x20000;//設置偏移量 ?FLASH_BASE : ?(uint32_t)0x08000000

RTC_TimeTypeDef RTC_TimeStruct;

??RTC_DateTypeDef RTC_DateStruct;

??u8 tbuf[40];

u8 t=0;

HAL_Init(); ???????? //初始化HAL庫

Stm32_Clock_Init(160,5,2,4); ? ????//設置時鐘,400Mhz

delay_init(400); ????//延時初始化

uart_init(115200); //串口初始化

usmart_dev.init(200); ???? //初始化USMART

????printf("RTC APP running\r\n");

LED_Init(); //初始化LED

KEY_Init(); //初始化按鍵

SDRAM_Init(); ?????????????????? //初始化SDRAM

????RTC_Init(); ??????????????????? //初始化RTC

????RTC_Set_WakeUp(RTC_WAKEUPCLOCK_CK_SPRE_16BITS,0); //配置WAKE UP中斷,1秒鐘中斷一次 ?

????while(1)

????{

t++;

if((t%100)==0) //每100ms更新一次顯示數據

{

????????????HAL_RTC_GetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN);

sprintf((char*)tbuf,"Time:%02d:%02d:%02d",RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds);

??????printf("RTC time=%s\r\n",tbuf);

????????????HAL_RTC_GetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN);

sprintf((char*)tbuf,"Date:20%02d-%02d-%02d",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date);

printf("RTC date=%s\r\n",tbuf);

sprintf((char*)tbuf,"Week:%d",RTC_DateStruct.WeekDay);

printf("RTC week=%s\r\n",tbuf);

}

if((t%20)==0)LED0_Toggle; //每200ms,翻轉一次LED0

????????delay_ms(10);

} ?

}

說明:重點是程序開始要有語句:SCB->VTOR = FLASH_BASE|0x20000;后面代碼和普通app程序無區別

3.app生成bin文件

通過在 User 選項卡,設置編譯后調用 fromelf.exe,根據.axf 文件生成.bin 文件,用于

IAP 更新。?

具體見之前文章:

STM32多種開發環境及生成hex及bin文件介紹_stm32 cubeide fromelf-CSDN博客文章瀏覽閱讀758次,點贊29次,收藏23次。STM32多種開發環境及生成hex及bin文件介紹keil5 STM32CubeIDE EWARM如果不考慮商業應用keil的比較好,如果考慮商業付費用STM32CubeIDE更好一些,畢竟是免費的。_stm32 cubeide fromelfhttps://blog.csdn.net/xieliru/article/details/139849283?spm=1001.2014.3001.5501

4.串口升級app

(1)首先用keil把bootloader程序用燒寫器燒寫到單片機中

(2)通過串口IAP升級app程序

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

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

相關文章

達夢數據庫的系統視圖v$database

達夢數據庫的系統視圖v$database 基礎信息 OS版本: Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本: DM Database Server 64 V8 DB Version: 0x7000c 03134284132-20240115-215128-20081在達夢數據庫(Dameng Database&#xf…

Java——Lambda表達式

1. 背景 Lambda表達式是JavaSE 8中一個重要的新特性。Lambda表達式允許你通過表達式來代替功能接口。 Lambda表達式就和方法一樣,它提供了一個正常的參數列表和一個使用這些參數的主體(body,可以是一個表達式或一個代碼塊)。 Lambda 表達式(…

C# YoloV8 模型效果驗證工具(OnnxRuntime+ByteTrack推理)

C# YoloV8 模型效果驗證工具(OnnxRuntimeByteTrack推理) 目錄 效果 項目 代碼 下載 效果 模型效果驗證工具 項目 代碼 using ByteTrack; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using Sys…

遠程服務器配置(堡壘機samba/ssh等)

分配了新的服務器后,要下載代碼首先要配置ssh。有以下兩種方式: 拷貝原本服務器的在本地的重新生成ssh,再跟服務器密鑰配對(如未備份.gitconfig,還需重新配置git賬號郵箱。) ssh配置 如果是拷貝過來的.ss…

【win11】Mouse without Borders安裝問題以管理員權限安裝msi文件

【win11】Mouse without Borders安裝問題&以管理員權限安裝msi文件 Mouse without Borders安裝問題解決&以管理員權限安裝msi文件啟動Windows Installer服務以管理員權限安裝msi文件 參考文獻 Mouse without Borders安裝問題 在win11下我雙擊MouseWithoutBorders2.2.1…

nodejs使用mysql模塊自動斷開

背景 第二天早上來的時候,發現接口返回異常Cannot enqueue Query after fatal error 從日志看上去,接口是正常運行的,搜索一下之后發現是數據庫的問題,連接斷開了 原因 MySQL中有一個名叫wait_timeout的變量,表示操…

由監官要求下架docker hub鏡像導致無法正常拉取鏡像

問題:下載docker鏡像超時 error pulling image configuration: download failed after attempts6: dial tcp 202.160.128.205:443: i/o timeout解決辦法:配置daemon.json [rootbogon aihuidi]# cat /etc/docker/daemon.json {"registry-mirrors&qu…

java springboot過濾器

在Spring Boot應用中添加自定義過濾器,可以通過實現Filter接口或繼承OncePerRequestFilter類來創建過濾器,并使用FilterRegistrationBean將其注冊到Spring容器中。 以下是一個簡單的示例: 1. 創建過濾器類 首先,創建一個實現Fil…

C++基礎語法:類構造函數

前言 "打牢基礎,萬事不愁" .C的基礎語法的學習 引入 類是實現面向對象思想的主要方法.前面提到:類是函數的變種,類可以通過調用靜態方法或者成員函數來實現邏輯.多數情況下使用成員函數.構造函數是生成類對象成員的必須條件,對此做一些構造函數的歸納 構造函數的目…

【日志消息類的編寫】

日志消息類編寫 由于上篇的代碼比較簡單,今天就多寫兩段代碼順便把日志消息類編寫完成。 這個類的實現就是:什么時間,哪個線程,哪個文件的哪一行,發生了什么等級的日志,日志機器名字是什么,日…

20240628 每日AI必讀資訊

📚 Hugging Face 推出新版開源大模型排行榜,中國模型 Qwen-72B 奪冠 - 阿里Qwen-2-72B指令微調版本問鼎全球開源大模型排行榜榜首 - Llama-3-70B 微調版本排名第二,而 Mixtral-8x22B 微調版本位居第四。 - 另外,微軟的 Phi-3-M…

三種分布式鎖實現方式

目錄 1、數據庫自增 2、Redis自增 3、Zookeeper 4、其他 4.1、雪花算法 4.2、Tinyid 4.3、Leaf 4.4、數據庫號段 1、數據庫自增 利用數據庫表的自增特性,或主鍵唯一性,實現分布式ID REPLACE INTO id_table (stub) values (’a‘) ; SELECT LA…

社交App廣告優化新篇章:Xinstall引領用戶體驗升級,助力買量效果提升

隨著移動互聯網的快速發展,社交App已經成為人們生活中不可或缺的一部分。然而,在競爭激烈的市場環境下,如何有效地進行廣告投放,吸引并留住用戶,成為了每個社交App運營者面臨的重大挑戰。今天,我們就來談談…

自費5K,測評安德邁、小米、希喂三款寵物空氣凈化器誰才是高性價比之王

最近,家里的貓咪掉毛嚴重,簡直成了一個活生生的蒲公英,家中、空氣中各處都彌漫著貓浮毛甚至所有衣物都覆蓋著一層厚厚的貓毛。令人難以置信的是,有時我甚至在摳出的眼屎中都能發現夾雜著幾根貓毛。真的超級困擾了。但其實最空氣中…

Packer-Fuzzer一款好用的前端高效安全掃描工具

★★免責聲明★★ 文章中涉及的程序(方法)可能帶有攻擊性,僅供安全研究與學習之用,讀者將信息做其他用途,由Ta承擔全部法律及連帶責任,文章作者不承擔任何法律及連帶責任。 1、Packer Fuzzer介紹 Packer Fuzzer是一款針對Webpack…

4.if 條件判斷

1.if-else語句 if #判斷條件 :pass else:pass2.if - elif- else if #判斷條件 :pass elif #判斷條件:pass else:pass3.if語句可以嵌套 if #判斷條件 :passif #判斷條件 :pass 4.邏輯運算符 and 兩個都為真,才是真 or 一個為真 即是真 not 取反 and從左到右,所有值為真,返回…

麒麟系統安裝MySQL

搞了一整天,終于搞定了,記錄一下。 一、背景 項目的原因,基于JeecgBoot開發的系統需要國產化支持,這就需要在電腦上安裝MySQL等支撐軟件。 國產化項目的操作系統多是麒麟系統,我的系統如下: arm64架構。…

C#快速開發OPCUA服務器

為方便演示,此時創建一個控制臺應用程序。第三方dll(C編寫的庫opcsrv.dll,他人實現)。 拷貝dll到運行目錄下: 拷貝二次封裝后的文件到項目目錄下: 第一步:創建OpcUa服務器 //第一步:創建OpcUa服務器 OPCSr…

java.util.Optional類介紹

java.util.Optional 是 Java 8 引入的一個容器類,用于表示可能包含或不包含非空值的對象。它的設計初衷是為了減少程序中的空指針異常(NullPointerException),并使代碼更加簡潔和易讀。 Optional 類的介紹 1. 特點 避免顯式的 null 檢查:使用 Optional 可以避免顯式的 n…

基于ssh框架的個人博客源碼

基于ssh的個人博客源碼,頁面清爽簡潔,原先有部分bug,運行不了,現已修復 1.博客首頁 (本地訪問地址 :localhost:8080/Blog/index/index) 2.關于我 3.慢生活 4.留言板 5.我的相冊 微信掃碼下載源碼