国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32F1 IAP在線升級功能實現(xiàn)(使用串口)及心得

這篇具有很好參考價值的文章主要介紹了STM32F1 IAP在線升級功能實現(xiàn)(使用串口)及心得。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

公司產品要求,需要做一個能遠程升級程序的功能,找了很多例程,大多都是需要按鍵來完成操作的,而我需要的是通過串口發(fā)送指令來完成,于是東拼西湊最后還是用了四天的時間勉強做出來

整個功能需要的程序是兩個部分。一個是IAP程序,一個是APP程序。對于IAP程序和APP原理方面的內容就不再過多贅述。直接從操作開始吧。

IAP程序

寫IAP程序之前首先得配置程序的起始地址和大小。這里根據(jù)個人情況而定,我這里單片機flash大小是512k,所以IAP程序選擇分配的大小是64k。
stm32 串口升級程序,STM32F1,stm32,單片機,arm

點擊魔術棒,然后在選擇target,設置起始地址(start)和大小(size),IAP程序起始地址都是從0x8000000開始的,大小就是0x10000也就是64k啦。
在這里我參考了原子哥的源碼和一位大神的分享,原子的資料一搜一大堆,這里就僅貼出大佬的鏈接
stm32 IAP 程序編寫心得
有了前車之鑒,做起來也稍顯得心應手,這里的flash操作的函數(shù)和IAP功能函數(shù)都是拿來主義了,原子IAP例程里拿來就可以用。主要工作還是針對main函數(shù),這里直接貼出源碼:

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
 
#define ADDR_CodeWriteFlag  0X08070000		//設置跳轉標志位保存地址
#define ADDR_JumpToIAPFlag  0X08070001
int main(void)
{	
	u16 IAPFlagBuf[2];
	u16 RxDataCount=0;				//串口接收到的數(shù)據(jù)計數(shù)
	u16 RxDataLength=0;				//串口接收到的數(shù)據(jù)長度
	u16 AppCodeLength = 0;		//接收到的app代碼長度
	u8  RxCmdFlag = 0;				
	u8  AppRunFlag = 0;				//應用程序運行標志
	u16 JumpToAPPFlag;									//跳轉至APP程序標志位
	u16 JumpToIAPFlag;									//跳轉回IAP標志位
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應優(yōu)先級
	JumpToAPPFlag = STMFLASH_ReadHalfWord(ADDR_CodeWriteFlag); //讀取APP寫入標志位,判斷是否已有程序
	JumpToIAPFlag = STMFLASH_ReadHalfWord(ADDR_JumpToIAPFlag);
	uart_init(9600);					//串口初始化為9600
	delay_init();	   	 				//延時初始化 
	IAPFlagBuf[0] = 0x11;
	IAPFlagBuf[1] = 0x00;
	
	printf("提示:輸入send發(fā)送bin文件!\r\n");
	while(1)
	{
		if(JumpToAPPFlag != 0x11)			//判斷是否已有APP程序,如果已有,跳轉至APP程序運行
		{
			if(JumpToIAPFlag == 0x11)		//判斷是否從APP程序跳轉回來,如果是擦除已有APP程序
			{			
				JumpToIAPFlag = 0x00;		
			}
			if(USART_RX_CNT)			//如果有數(shù)據(jù)進來
			{
				if(RxDataCount == USART_RX_CNT)				//串口沒有再收到新數(shù)據(jù)
				{
					RxDataLength = USART_RX_CNT;
					if(RxCmdFlag == 0 && RxDataLength == 4)	//接收到IAP指令
					{
						if(USART_RX_BUF[0] == 's' && USART_RX_BUF[1] == 'e' && USART_RX_BUF[2] == 'n' && USART_RX_BUF[3] == 'd')//判斷是否為IAP指令
						{
							RxCmdFlag = 1;							//接收到更新APP代碼指令,標志位置1
							RxDataLength = 0;						//清空指令長度,防止影響后面計算APP代碼大小
							printf("準備接收app程序,請?zhí)砑觔in文件!\r\n"); //準備好接收bin文件,等待用戶添加
						}
						else
						{
							CodeUpdateFlag = 0;
							AppCodeLength = 0;
							printf("指令錯誤!\r\n");	//未接收到IAP更新指令,其他任何串口發(fā)送數(shù)據(jù)都認為指令錯誤
						}
					}
					
					else if(RxCmdFlag == 1 && RxDataLength > 10)//接收APP程序
					{
						CodeUpdateFlag = 1;												//代碼更新標志位置位,用于應用程序代碼接收完成后寫FLASH
						RxCmdFlag = 0;
						AppCodeLength = USART_RX_CNT;
						printf("APP程序接收完成!\r\n");
						printf("程序大小:%dBytes\r\n",AppCodeLength);
					}
					
					else
					{
						RxDataLength = 0;
						printf("文件或指令錯誤!\r\n"); //如果代碼大小不足10Bytes,認為沒有正確添加bin文件
					}
					RxDataCount = 0;
					USART_RX_CNT = 0;
				}
				else 
				{
					RxDataCount = USART_RX_CNT;
				}
			}
			
			delay_ms(10);											//給以串口中斷的時間,判斷是否接收完成
			
			if(CodeUpdateFlag)								//代碼更新標志位置位
			{
				CodeUpdateFlag = 0;
				if(AppCodeLength)
				{
					printf("程序更新中...\r\n");
					if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)					//判斷代碼合法性
					{	
						printf("正在下載程序!\r\n");
						iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,AppCodeLength);	//新代碼寫入FLASH  
						AppRunFlag = 1;
					}
					else 
					{
						printf("程序更新失敗,請檢查bin文件是否正確!\r\n");
						printf("跳轉到原有應用程序!\r\n");
						iap_load_app(FLASH_APP1_ADDR);								         //執(zhí)行FLASH APP代碼
					}
				}
				else 
				{
					printf("沒有程序可以更新!\r\n");
				}								 
			}
			
			if(AppRunFlag)																//App運行標志置位
			{
				printf("開始運行程序!\r\n");
				delay_ms(10);                        
				if(((*(vu32*)(FLASH_APP1_ADDR + 4)) & 0xFF000000) == 0x08000000)		//判斷代碼合法性
				{	 
					AppRunFlag = 0;
					STMFLASH_Write(ADDR_CodeWriteFlag,IAPFlagBuf,2);		   //寫入APP代碼標志
					//RCC_DeInit(); //關閉外設
					//__disable_irq();
					iap_load_app(FLASH_APP1_ADDR);								         //執(zhí)行FLASH APP代碼
				}
				else 
				{
					printf("應用程序錯誤!\r\n");  
				}									   
			}
		}
		else
		{
			printf("已有一個應用程序!\r\n");
			printf("開始運行程序!\r\n");
			delay_ms(10);
			iap_load_app(FLASH_APP1_ADDR);										//執(zhí)行FLASH APP代碼
		}
	}
} 

  1. main函數(shù)中,選擇一塊不使用的flash區(qū)域來保存跳轉標志位。
    stm32 串口升級程序,STM32F1,stm32,單片機,arm
    我選擇的是0x8070000開始的區(qū)域,整個flash大小是512k也就是0x8080000,所以最后我又留了64k的大小來存放,所以留給APP程序的就是0x08010000到0x08070000的地址,也是就384k大小空間,記住這個0x08010000到0x08070000,后面APP程序要考。

  2. 每次進入main函數(shù)都要先讀這個地址的值,若等于0x11則直接跳轉到APP,因為在跳轉APP之前是要對這個地址進行寫0x11的,所以跳轉到APP后這個地址是0x11,開機啟動會自動進入APP。
    stm32 串口升級程序,STM32F1,stm32,單片機,arm
    到此似乎思路就清晰了,原子通過按鍵來操作接收,下載。我這里通過指令來接收下載,其他的判斷棧頂?shù)刂返暮戏ㄐ?,看兩遍代碼也能明白了。

APP程序

接下來就是APP程序的操作部分了。
要從IAP跳轉到APP,APP的程序也需要修改。首先就是程序的起始地址和大小。
stm32 串口升級程序,STM32F1,stm32,單片機,arm
前面的IAP從0x8000000到0x8010000,所以我們的APP程序只能從0x8010000開始,而0x8070000到0x8080000又要保存跳轉標志位,那么APP的地址就只能是0x8010000到0x8070000了,既然這樣,那就拉滿吧,所以大小設置我選擇0x60000。
然后就是輸出bin文件了,要用串口傳輸不能用hex文件,所以在USER界面
選擇如圖所示操作,方框里填的是E:\keil5\ARM\ARMCC\bin\fromelf.exe --bin -o …\output\Project.bin …\output\Project.axf 注意有空格,當然這個也得根據(jù)自己的文件位置更改。
stm32 串口升級程序,STM32F1,stm32,單片機,arm
下一步就是更改偏移地址了,這里只需要在主函數(shù)里加
SCB->VTOR=FLASH_BASE|0x10000; 即可,我這里偏移0x10000
stm32 串口升級程序,STM32F1,stm32,單片機,arm
到此就能編譯生成bin文件,通過IAP程序,使用串口來完成升級了。
但是后續(xù)要升級怎么辦,我們還得從APP跳轉到IAP來。所以在APP程序中還需要接收指令來跳轉到IAP去。
stm32 串口升級程序,STM32F1,stm32,單片機,arm
這里Receive_Data_Point3是接收到的字節(jié)長度,我設置的跳轉指令是APPTOIAP!共9位。
然后就是跳轉前還需將存放標志位得地址寫入0x00,前面IAP中會對該地址得值進行判斷是否是0x11,是的話就又跳回來了。然后有大佬踩坑后,得知跳轉到IAP直接用NVIC_SystemReset(); 即可。
stm32 串口升級程序,STM32F1,stm32,單片機,arm
到此就基本完成了。
第一次寫博客,也是為了記錄和學習。語言不通順還請多諒解,如有錯誤的地方也請多加指正。同時有疑問的同學也可以評論留言,歡迎討論交流。

可能出現(xiàn)的問題解決方法:
在后續(xù)的測試中發(fā)現(xiàn),串口接收bin文件時還沒接收完就進入到了寫入flash的動作,導致有很大的概率程序升級失敗。分析了半天原因可能是,接收緩存在10ms內沒收到數(shù)據(jù)就默認接收完畢進入寫入跳轉了,我使用的9600波特率,在將下圖中的延時增加到100ms后,沒有再出現(xiàn)問題了。
stm32 串口升級程序,STM32F1,stm32,單片機,arm文章來源地址http://www.zghlxwxcb.cn/news/detail-686537.html

到了這里,關于STM32F1 IAP在線升級功能實現(xiàn)(使用串口)及心得的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • STM32F407串口IAP遠程升級程序

    STM32F407串口IAP遠程升級程序

    相關代碼和工程文件鏈接:https://pan.baidu.com/s/1wN4THWJwqzjjIe7e2TENBA?pwd=o86o 提取碼:o86o ????????STM32代碼燒錄主要有三種:ICP、ISP、IAP。 ????????ICP(In Circuit Programing),在電路編程,通過JTAG或者SWD接口進行程序的燒錄,就是平時利用ST-Link或者J-Link燒錄程序; ??????

    2024年02月10日
    瀏覽(59)
  • GD32單片機遠程升級下載,手機在線升級下載程序,GD32在線固件下載升級,手機下載程序固件方法

    GD32單片機遠程升級下載,手機在線升級下載程序,GD32在線固件下載升級,手機下載程序固件方法

    ? ? ? ? GD32、STM32單片機,是我們最常見的一種MCU。通常我們在使用STM32單片機都會遇到程序在線升級下載的問題。 ? ? ? ? GD32/STM32單片機的在線下載通常需要以下幾種方式完成: ? ? ? 1、使用ST/GD提供的串口下載工具,本地完成固件的升級下載。 ? ? ? ?2、自行完成系統(tǒng)

    2024年02月02日
    瀏覽(28)
  • 在線升級:OTA升級的原理和實現(xiàn)方式

    在線升級:OTA升級的原理和實現(xiàn)方式

    目錄 1、OTA 在線升級 2、實現(xiàn)方式 3、操作方式 3.1、后臺式升級 3.2、非后臺式式更新 4、STM32 的在線升級 4.1、劃分 Flash 區(qū)域 4.2、實操1 - Flash空間地址的劃分 4.3、實操2 - 設置工程 4.4、實操3 - 接收固件更新包 4.5、實操4 - 拷貝程序至Flash 4.6、實操5 - 跳轉至 App 應用程序 4.7、特

    2024年02月01日
    瀏覽(23)
  • 【STM32 IAP技術實現(xiàn)】適合小白“食用”(以STM32F103C8T6為例)

    【STM32 IAP技術實現(xiàn)】適合小白“食用”(以STM32F103C8T6為例)

    ??想必大家對 單片機燒錄 一詞都不陌生,就是將程序下載到我們的板子(MCU)里面。常見的燒錄方法有用Keil下載,或者是編譯出Hex文件通過燒錄軟件(上位機例如:muisp、flymcu)、燒錄器軟件(例如:J-LINK、ST-LINK)燒錄,從程序的角度來看通過燒錄,它被“更新”了。

    2024年02月03日
    瀏覽(21)
  • STM32 IAP應用開發(fā)——通過USB實現(xiàn)固件升級

    STM32 IAP應用開發(fā)——通過USB實現(xiàn)固件升級

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系統(tǒng)中獲取新代碼并對自己重新編程,即可用程序來改變程序。在應用編程(IAP)是用戶的應用代碼對片內Flash存儲器進行擦除/編程的方法。這種方式的典型應用就是用一小段代碼來實現(xiàn)程序的下載,實際上單片機的ISP功能就

    2024年02月12日
    瀏覽(19)
  • 【STM32】IAP升級01 bootloader實現(xiàn)以及APP配置(主要)

    【STM32】IAP升級01 bootloader實現(xiàn)以及APP配置(主要)

    通過之前的了解 之前的了解,我們知道實現(xiàn)IAP升級需要兩個條件: 1.APP程序必須在 IAP 程序之后的某個偏移量為 x 的地址開始; 2.APP程序的中斷向量表相應的移動,移動的偏移量為 x; 默認條件下的起始地址 默認的條件下,圖中 IROM1 的起始地址(Start)一般為 0x08000000,大小

    2024年02月03日
    瀏覽(47)
  • GD32F4XX IAP升級

    GD32F4XX IAP升級

    這里使用的是GD32F405RG,flash 為1M(0x08000000 - 0x080FFFFF),具體參考官方手冊 因為每個芯片的falsh大小不一樣,地址劃分根據(jù)實際flash大小和自己的設計去分配就好,?自己的址劃分如下 : BOOT_ADDRESS:0x08000000 - 0x08003FFF? ? ?16k(扇區(qū)0) APP_ADDRESS:0x08004000 - 0x0807FFFF? ? ?512k-16

    2024年02月12日
    瀏覽(21)
  • 基于STM32F1以及STM32CubeMx實現(xiàn)串口中斷通訊(字符串發(fā)送與接收)

    基于STM32F1以及STM32CubeMx實現(xiàn)串口中斷通訊(字符串發(fā)送與接收)

    首先選好自己的板子并打開軟件設置,本實驗基于STM32F103ZET6實現(xiàn),打開軟件后如圖: 打開外部高速晶振,然后接著配置時鐘: 將時鐘頻率修改為72MHz,接著設置接線方式為SW 接下來需要使用串口中斷通訊,打開我們的串口設置并打開中斷 這里波特率設置為115200,數(shù)據(jù)位為

    2024年02月09日
    瀏覽(25)
  • STM32 IAP應用開發(fā)——通過串口/RS485實現(xiàn)固件升級(方式2)

    STM32 IAP應用開發(fā)——通過串口/RS485實現(xiàn)固件升級(方式2)

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系統(tǒng)中獲取新代碼并對自己重新編程,即可用程序來改變程序。在應用編程(IAP)是用戶的應用代碼對片內Flash存儲器進行擦除/編程的方法。這種方式的典型應用就是用一小段代碼來實現(xiàn)程序的下載,實際上單片機的ISP功能就

    2024年02月14日
    瀏覽(24)
  • STM32 IAP應用開發(fā)——通過串口/RS485實現(xiàn)固件升級(方式1)

    STM32 IAP應用開發(fā)——通過串口/RS485實現(xiàn)固件升級(方式1)

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系統(tǒng)中獲取新代碼并對自己重新編程,即可用程序來改變程序。在應用編程(IAP)是用戶的應用代碼對片內Flash存儲器進行擦除/編程的方法。這種方式的典型應用就是用一小段代碼來實現(xiàn)程序的下載,實際上單片機的ISP功能就

    2024年02月10日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包