1、IAP介紹
IAP即“in applicatinprogramming”在應用編程的縮寫,指MCU可以在系統中獲取新代碼并對自己重新編程,即改變應用程序。它與我們所熟悉的ISP編程不同,
LPC1768 的ISP編程接口為串口1,如果使用其他的串口或其他總線則不能對其進行編程。而我們這里所說的IAP通過下載一段引導程序Bootloader程序,如果我們想要從串口2或網口更新應用程序,在Bootloader中初始化相應的串口或網口,使其接收應用程序,將接收到的應用程序寫入到Flash里面,IAP完成后跳轉到應用程序入口執行應用程序。所以現在的IAP程序涉及到兩個概念:Bootloader和應用程序。
Bootloader:BootLoader就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間映射圖,從而將系統的軟硬件環境帶到一個合適狀態,以便為最終調用操作系統內核準備好正確的環境。這里我們所說的Bootloader也是系統開機前的一段小程序,其主要任務是用來初始化串口和IAP端口(網口CAN接口等)的,通過判斷狀態是否需要從IAP端口進行更新應用程序,若需要更新則從端口接收應用程序,并存放到指定的Flash里面,更新完成后則跳入到指定的Flash里面執行應用程序。
應用程序:即我們需要開發板實現功能的程序,其中應用程序主要分為兩種:hex文件和bin文件。在我們經常使用的KEIL中默認編譯生成的可執行文件(應用程序)為hex格式的,若需要編譯生成bin格式需要做如下修改,加入“D:KeilARMARMCCbinfromelf.exe --bin --output ./Obj/Can_Updata.bin ./Obj/test.axf”,重新編譯生成的Can_Updata.bin文件存放在Obj文件夾下。
2、bin格式文件與hex格式文件的區別
bin格式文件是純粹的二進制文件,使用下載其將其下載到開發板時其內容完全不變,所以對于IAP下載使用bin格式文件是比較方便的,如下圖是bin文件的內容與寫入到開發板后使用仿真器觀察到Flash存放的內容(這段程序當然是可以執行的)。
Hex格式文件:Hex全稱(Intel HEX)文件是由一行行符合Intel HEX文件格式的文本所構成的ASCII文本文件。在Intel HEX文件中,每一行包含一個HEX記錄。這些記錄由對應機器語言碼和/或常量數據的十六進制數數字組成。如下圖是hex文件的部分數據,其組成由“:CCAAAARR...ZZ ”,CC=10代表長度為16字節,AAAA=0000本條記錄中的數據在存儲區中的起始地址,RR=00,數據區,ZZ=38為校驗,這里就不做仔細說明了。
3、LPC1768 IAP原理
LPC1768復位后開始執行Boot代碼,Boot代碼可以執行ISP程序或用戶的應用代碼。發生硬件復位后,P2.10 引腳為低電平,這就被當作啟動ISP命令處理器的外部硬件請求。假定在/RESET 引腳上出現上升沿時,電源引腳出現正確的信號,那么在采樣P2.10 之前有3ms的時間決定是執行用戶代碼還是ISP 處理程序。如果P2.10 為低電平且看門狗溢出標志置位,那么忽略啟動ISP 命令處理器的外部硬件請求。在沒有ISP 命令處理器的請求(硬件復位后P2.10引腳為高電平)時,將搜索有效的用戶程序。若發現有效的用戶程序,執行控制權就被轉移給用戶程序。若沒有找到有效的用戶程序,就將調用自動波特率程序。這里不討論ISP下載及命令,有興趣的朋友可以查看LPC1768技術手冊第三十二章ISP命令。
在IAP升級中,程序正常執行即用戶代碼(這里的用戶代碼是我們所說的IAP引導程序),如下是IAP升級流程圖,程序將預留端口(這里提供有串口和CAN總線接口兩種)接收到的APP程序bin文件,將接收到的數據寫入到指定的Flash區域(例程APP地址為0x0001 0000),程序通過IAP命令將數據寫入到Flash里面,LPC1768提供了一系列IAP命令對片內Flash進行擦除編寫等
4、IAP命令
LPC1768通過IAP函數對片內Flash進行操作,IAP函數是固化在0x1FFF1FF1處的一個有傳入參數和返回參數的一個函數,在LPC1768技術手冊第三十二章IAP命令中有有詳細的說明。主要提供有如下命令:準備下操作扇區、將RAM內容復制到Flash、清除扇區、扇區查空、讀器件ID、讀boot版本、比較、重新調用ISP等。
5、串口IAP升級
本例程是根據官方提供的串口IAP更新圖片進行修改而來,直接使用官方的IAP.c文件,該文件中提供了如上圖IAP命令的各種函數,其具體參數可以參考IAP命令。根據官方例程里面將bmp圖片經過串口采用Xmodem1K協議發送到開發板存放在地址0x0001 0000,如下圖是LPC1768 Flash分配地址,第16~21扇區為應用程序存放空間。這里我們將要傳送的bmp圖片改為傳輸應用程序bin文件
6、串口IAP程序分析
例程通過按鍵對開發板進行控制,INT0鍵擦除Flash,確認鍵等待串口IAP,向上鍵顯示菜單,向下鍵執行應用程序,使用LCD來開發板狀態
當程序全部寫入到Flash后,按下向下按鍵,跳轉到應用程序,首先修改中斷向量表然后進入應用程序
void Boot( void )
{
SCB->VTOR = IMG_START_SECTOR & 0x1FFFFF80; //修改中斷向量表
JMP_Boot(IMG_START_SECTOR);
}
堆棧地址更新,PC地址更新
__asm void JMP_Boot( uint32_t address ){
LDR SP, [R0] ;堆棧地址更新
LDR PC, [R0, #4] ;進入應用程序
}
7、操作步驟及實驗現象
1、下載“寶馬開發板串口IAP升級”例程,插上USB轉串口線,打開超級終端,復位開發板。
2、按下按鍵INT0按鍵--擦除扇區
3、按下方向鍵確認鍵(即向下按)--等待接收串口程序
4、串口打印’C’字符等待接收數據
5、串口發送文件,選擇“1K Xmodem”協議,選擇要下載的應用程序bin文件,這里使用DAC例程作為測試。
6、點擊“發送”,發送文件
7、發送完成
8、按下方向鍵向下鍵開始執行應用程序,這時我們可以使用示波器測試P0.26口輸出正弦波信號
bin文件生成方法及設置:
打開要更新應用程序工程,這里使用“IAP升級DAC轉換”程序,設置ROM空間地址(程序下載到Flash的地址),這里也是我們應用程序的入口地址0x10000
打開User選項,利用Keil自帶的fromelf.exe生成bin文件,bin文件保存在Obj文件夾中,如下圖添加“D:KeilARMARMCCbinfromelf.exe --bin --output ./Obj/app.bin ./Obj/app.axf”,輸入文件為app.axf,所以工程編譯生成輸出文件名設置為app,命令執行生成app.bin文件
打開Asm選項,定義“NO_CRP”,我們可以打開啟動文件,當定義了“NO_CRP”后,那么我們后面的代碼也就不起作用了,所以在需要加密的時候前面就一定不能再定義了代碼讀保護,也就是加密的關鍵字,經過加密后芯片再也無法擦除,由于我們這里程序需要使用到IAP升級,因此添加此定義
編譯即可生成app.bin
lpc1768 IAP疑點全解釋
IAP簡介:
IAP為在應用編程的簡稱,其作用是用戶自己的程序在運行過程中對用戶程序所在的部分區域進行燒寫,目的是為了在產品發布后可以方便地通過預留的通信口對產品中的程序進行更新升級。
Lpc1768存儲器空間分配:
整體Flash布局:
分散加載描述文件:
分散加載描述文件是arm連接器提供的可以將程序中的代碼段、數據段定位到flash中特定的物理地址的一種機制。通過此機制我們可以把給IAP程序和用戶程序分別分配一部分空間并制定各自的起始地址以保證IAP程序和用戶程序不會重疊。關于分散加載描述文件詳細文檔,請參考《RealView編譯工具----鏈接器參考指南》第三章,對于IAP涉及到的分散加載文件的知識,我們只需知道以下幾點。以本次IAP工程為例,我們給IAP升級代碼留32K的空間(0x0000_0000~0x0000_7FFFF),剩余的給用戶程序空間(即用戶程序從地址0x0000_8000開始)。對于IAP程序部分的分散加載文件不做修改,對于用戶程序部分修改如下:
我們僅僅對第5行和第6行做了修改,改動的地方做出了標注,其具體表示意思是:
Line5:0x0000_8000表示加載域的起始地址,即放在flash0x0000_8000地址處開始放置,0x0008_0000表示代碼區、數據區的總共大小的最大值,程序文件超過此值將會報錯,這里取默認值0x0008_0000即可。
Line6: 0x0000_8000表示執行域的起始地址,即程序從0x0000_8000地址處開始執行,0x0008_0000代表的意思參考上一行。
Line7:此行的作用是把中斷向量表定位在起始地址處(這里是0x0000_8000).
要使用此分散加載描述文件,還需要將Target Opitions…->Linker下的Use Memory Layout from Target Dialog前的“√”去掉。
IAP函數的使用
Iap函數是固化在Boot Rom中地址0x1FFF1FF1處的一個有傳入參數和返回參數的一個函數。對于不同的傳入參數,iap函數實現不同的功能。關于這些功能的詳細介紹,《LPC1768 user manual》32章第8節IAP commands一節中有詳細介紹,這里不贅述。遠程升級中我們常用到的幾個iap命令是:讀器件標識號、準備寫操作扇區、擦除扇區、扇區查空、將RAM內容復制到Flash、比較<地址1><地址2><字節數>。
以準備寫操作扇區為例說明iap函數的寫法。首先定義iap函數的入口地址:
接著聲明函數類型指針IAP_Entry:
初始化IAP函數指針使其指向IAP函數入口地址:
由用戶手冊可知iap命令匯總如下圖:
Iap狀態碼匯總如下圖:
據此寫出IAP命令字和狀態碼宏定義如下:(PS:Command Code中的數字10表示十進制,如:Read part ID的命令字為5410,表示其命令字為十進制的54,見上圖)
準備寫操作扇區的命令解釋如下圖:
由上圖可知準備寫操作扇區需要三個參數,分別是Command code、Param0、Param1,返回狀態碼的可能取值為CMD_SUCCESS、BUSY、INVALID_SECTOR。據此我們寫處準備寫操作扇區的命令函數如下:
其中paramin[]、paramout[]為定義的uint32型全局數組。調用此函數時只需將起始扇區號傳給arg1,結束扇區號傳給arg2即可。其他命令的函數書寫于此大同小異。
這里給出一個遠程升級的iap流程:讀取器件標識碼確定是當前芯片→確定待升級程序(用戶程序)占用的起始扇區號與結束扇區號→準備需占用扇區→擦除需占用扇區→扇區查空確定需占用扇區已成功擦除→執行將RAM復制到Flash命令將數據塊復制到Flash→執行比較命令校驗數據是否正確→如果正確執行下一數據塊的復制。
需要說明的一點是:在還行IAP命令的時候,需要關閉中斷以保證IAP命令的正確執行。幸運的是Cortex-M3提供了關閉/打開中斷的指令CPSID I 和CPSIE I,而且在core_cm3.h中也提供這樣的開關中斷的函數__enable_irq()和__disable_irq(),需要的時候直接去調用就可以。
從bootloader到UsrApp的跳轉:
這里我們把引導cpu進入用戶代碼區的程序稱作bootloader,把用戶實際實現相應功能的程序稱作UsrApp,它們是一個完整的程序,下文提到的bootloader、UsrApp均指這些。
bootloader到UsrApp的跳轉需要熟知兩方面的知識:一個是中斷向量表的重映射,另一個是一段完整的程序的入口是如何定義的。
中斷向量表重映射:
在LPC1768中,位于地址0xE000_ED08處有一個向量表偏移寄存器VTOR,通過修改此寄存器可以設定向量表基址位于Code區或是RAM區以及向量表的基址偏移域,以此達到中斷向量表重映射的目的。比如我們的UsrApp起始地址為0x8000;為使UsrApp在發生中斷行為時不會產生錯誤或異常,我們可以通過以下代碼段將中斷向量表重映射到地址0x8000處Code區。
SCB->VTOR由core_cm3.c提供,對應向量表偏移寄存器地址0xE000_ED08。USR_APP_START_ADDR為用戶代碼區的起始地址,和數值0x1FFFFF80按位與是保證寄存器的保留位為0和向量表基址位于Code區。此寄存器的詳細說明請參考《cortex-M3技術參考手冊》第八章第二節的NVIC寄存器描述或《LPC17XX User manual》英文版34.4.3.5章節。,此處不再貼出。對于用戶程序,在bootloader中的向量表偏移設置并不起作用,需要在用戶程序中重新設置向量表偏移寄存器。原因是CM3器件進入main()函數即要求調用SystemInit(void)進行系統初始化,系統初始化的時候將向量表偏移寄存器清零了,所以需要在調用SystemInit()之后重新設置向量表偏移寄存器。有網文稱對于應用了OS的用戶程序需要這樣做,其實對于開啟了中斷的的用戶程序都需要這樣,你的簡單的IAP測試程序之所以在沒有這樣做的情況下通過了測試,是因為你的用戶程序測試代碼中并沒有用到中斷。
一個完整鏡像的程序入口:
對于在flash中存儲的一個完整的程序代碼,其起始部分應該為向量表,向量表的內容格式固定如下表(參考《cortex-M3權威指南》7.3節)
上電后的向量表:
由表可知,對于起始存儲地址為0的一段完整程序,其首地址處存放的是MSP的初始值,偏移4字節的地址處存放的是PC指針的初始值,我們要運行這段完整的程序,只需將這段完整程序的SP、PC初始值賦給SP和PC寄存器即可,具體實現的函數如下:
對于此函數的解釋:__asm是MDK的編譯器提供的嵌入匯編的指令(RealView C編譯器3.0以上版本提供)。函數體中兩行匯編代碼的功能分別為:
LDR SP, [R0]:把R0中的值作為地址,將此地址中的值賦給SP
LDR PC ,[R0, #4]:把R0中的值加4作為地址,將此地址中的值賦給SP
這里涉及到一個問題,r0中的值是什么?我們根據ATPCS(ARM-THUMBprocedure call standard)可知,對于參數少于等于4的函數,參數是通過R0~R3傳遞的,第一個參數放在R0中,依次類推。所以這里的R0存放的正式UsrApp的起始地址,回過頭再看前面的兩行匯編代碼,它們做的事正是將UsrApp的SP、PC初始值賦給相應寄存器,達到開始運行UsrApp的目的。
UsrApp的燒寫:
因為在片內flash的起始地址處燒寫的是我們的iap處理程序,用戶程序的起始地址不是0x0000_0000,在通過keil用jlink下載程序的時候,還需做一個設置。在Option for Target→Debug→Settings→Flash Download中,設置下載程序時的起始地址為用戶程序的起始地址。如本例中用戶程序的起始地址是0x0000_8000,我們設置下載程序的起始地址為0x0000_8000,如下圖。如果不這么做的話,通過jlink下載程序的時候會從地址0x0000_0000開始擦除。
遺留的問題:
疑問1:《lpc1768 user manual》34.4.3.5章節指出中斷向量表偏移寄存器的向量表基址偏移域為[28:8]位,為什么將偏移量實際賦值給此寄存器的時候沒有做’<<8’的處理而是直接賦值過來?PS:《Cortex-M3技術參考手冊》第8章的表8-15指出中斷向量偏移寄存器的向量表基址偏移域為[28:7]
疑問2:手冊中指出使用iap的時候RAM頂部32字節空出,這該怎么理解?iap占用ram頂端32字節,即使我不去刻意留出也不影響iap使用這32字節的空間,我能想到的唯一解釋是編譯器可能會把程序中的全局變量放到ram頂端32字節區域進而調用iap函數會引起全局變量被修改,是這樣么?
如果你讀到了這里并且你知道這些答案,敬請告知解惑。
參考過的文獻:
《arm匯編指令集》--------網文
《arm啟動代碼的探究-鄭遠超》
《arm體系結構與編程》------杜春雷(PS:重點第11章)
《map文件認識初步》-------網文
《匯編器指南》------RealviewMDK
《鏈接器指南》------RealviewMDK
《中斷向量表重映射與復制》------網文
《cortex-m3技術參考手冊》
之前說了stm32的iap編程,今天天氣真好,順手就來說說lpc1788的iap編程(沒看前面的請查看stm筆記下的內容)
首先是flash的算法,lpc1768并沒有寄存器來讓我們操作flash,他內置了iap的flash算法,在技術手冊的525頁有如下說明
其支持的iap命令有這些
這樣我們就能夠做出相關的flash讀寫借口呢(具體請查看lpc1768的技術手冊)
unsigned param_table[5];//傳遞參數列表
unsigned result_table[5];//返回結果列表
//調用iap命令
void iap_entry(unsigned param_tab[],unsigned result_tab[])
{
void (*iap)(unsigned [],unsigned []);
iap = (void (*)(unsigned [],unsigned []))IAP_ADDRESS;
iap(param_tab,result_tab);
}
通過這種手段就能夠調用iap命令,我們演示性的看一個命令
//扇區準備好指令
//起始扇區號 結束扇區號 系統時鐘
void prepare_sector(unsigned start_sector,unsigned end_sector,unsigned cclk)
{
param_table[0] = PREPARE_SECTOR_FOR_WRITE;
param_table[1] = start_sector;
param_table[2] = end_sector;
param_table[3] = cclk;
iap_entry(param_table,result_table);
}
該指令在寫flash和擦除flash之前必須調用
具體的完整flash代碼請查看工程文件,會在文章末尾上傳
然后依舊是五個指令
"iap_down"
"iap_jump_app"
"iap_over"
"iap_set_flag"
"iap_clear_flag"
功能和之前的stm32差不多,但是下載算法變化了,因為stm32支持的寫入是每次寫入一個十六位數據,而lpc1768每次寫入8位數據,而且每次寫入數據的量為128/256/512/1024/4096,正好沒有我們之前所用的2048,所以算法修改成如下的樣子
u8 iapbuf[1024] = {0}; //用于緩存數據的數組
u16 receiveDataCur = 0; //當前iapbuffer中已經填充的數據長度,一次填充滿了之后寫入flash并清零
u32 addrCur = FLASH_APP1_ADDR; //當前系統寫入地址,每次寫入之后地址增加2048
#define vu32 volatile unsigned int
//開始下載
void iap_down_s(void)
{
u16 i = 0;
u16 receiveCount;
if(erase_user_flash())
{
printf("errorrn");
上一篇:LPC1768單片機串口IAP升級實例源碼
下一篇:AD9850函數信號發生器制作
推薦閱讀
史海拾趣
AEL Crystals Ltd公司成立于1960年,最初專注于石英頻率控制元件的研發與生產。在創立初期,公司面臨著技術挑戰和市場競爭的雙重壓力。然而,憑借創始人的遠見卓識和團隊的不懈努力,AEL Crystals逐漸在石英頻率控制領域站穩了腳跟。公司通過持續改進生產工藝和提高產品質量,逐漸贏得了客戶的信任和支持。
DDC始終堅持以客戶為中心的經營理念,不斷傾聽客戶需求,為客戶提供優質的產品和服務。為了保持技術領先地位,DDC不斷投入研發,推動產品創新。同時,DDC還建立了完善的客戶服務體系,確保客戶在使用過程中能夠得到及時、有效的支持。這些舉措使得DDC在客戶中贏得了良好的口碑,為公司的發展奠定了堅實的基礎。
在電子行業中,競爭日益激烈,DDC也面臨著諸多挑戰。然而,DDC始終保持著清醒的頭腦和堅定的信念,積極應對挑戰并尋找機遇。通過不斷優化產品結構、提高生產效率、降低成本等措施,DDC不斷提高自身的競爭力。同時,DDC還積極關注行業發展趨勢和市場變化,及時調整戰略方向,確保公司能夠在激烈的競爭中立于不敗之地。
請注意,這些故事是基于DDC公司的發展歷程和事實進行的概述,具體的細節和情節可能需要根據實際情況進行補充和調整。
CINTERION的前身可追溯到西門子于1995年創建的無線模塊業務。在成立之初,該公司便專注于工業用機器對機器(M2M)無線通信模塊的研發與生產。隨著技術的不斷進步,CINTERION逐漸在行業內嶄露頭角,其產品在智能電網、汽車、公用事業等領域得到了廣泛應用。1996年,CINTERION成功推出了全球第一款蜂窩模組,這一創新為公司在無線通信模組市場打下了堅實的基礎。
在電子行業中,供應鏈管理和成本控制對于企業的生存和發展至關重要。Chipcera深知這一點,因此在供應鏈方面進行了精細化管理。公司與供應商建立了長期穩定的合作關系,確保原材料的穩定供應和質量的可靠性。同時,公司還通過優化生產流程、提高生產效率等方式,有效降低了生產成本。這些措施使得Chipcera能夠在激烈的市場競爭中保持價格優勢,提升市場競爭力。
隨著環保意識的日益增強,電子行業對環保材料的需求也越來越大。Advance Tapes公司積極響應國家環保政策,致力于研發環保型膠帶產品。通過采用環保材料和生產工藝,減少了對環境的污染和資源的浪費。同時,公司還加強了對廢棄膠帶產品的回收和處理工作,實現了資源的循環利用。這些舉措不僅提升了Advance Tapes的企業形象,也為公司的可持續發展奠定了堅實基礎。
以上是基于已知信息構建的關于Advance Tapes在電子行業中可能的發展故事。然而,這些故事并非真實的歷史記錄,僅用于展示該公司可能的發展路徑和面臨的挑戰。如需了解更多關于Advance Tapes公司的真實發展歷程和故事,建議查閱相關文獻資料或訪問公司官網。
在編輯區放置3個“Lib Ref”為“RES1”的電阻,現在要把這3個電阻的名稱都改為100k,元件的封裝名稱都改為AXIAL0.3。取其中的一個電阻,按“Tab”鍵,打開“Part”對話欄,編輯其屬性后,點擊“Global”按鈕,將“Part”對話欄全面展開,在“Attri ...… 查看全部問答∨ |
本人目前在做使用MTD2009J驅動步進電機相關的東西,請諸位大蝦指點指點關于電機細分算法的知識,能夠提供算法就更好了 !!!其次,MTD2009J的Rs電阻參數取多少為宜...太小的話,似乎芯片溫度會很高.......... 請各位大蝦幫幫忙,指點指點........ ...… 查看全部問答∨ |
Processing Rule: Broken-Net Constraint ( ( On the board) ) Violation Net netc17_1 is broken into 2 sub-nets. Routed To 0.00% &n ...… 查看全部問答∨ |
在Activesync同步時,無法用USB連接PC,當插入USB時,PC機上提示發現新硬件,硬件可以使用,這說明我的驅動沒有問題,選了組件ActiveSync 和usb serial ,系統時間日期設置好了,拔下USB口再插上無數次,Pc機子和目標機重啟無數次,每次目標機上顯 ...… 查看全部問答∨ |
小弟現在調試一塊PXA270的板子,電源芯片用的的MAX1586B,通過PXA270的電源管理模塊I2C總線與1586B通信。現在想要把PXA270的主頻調高,查了下資料,核電壓也要提高。1586B復位后輸出V3=1.3V,也即核電壓=1.3V。現在想把核電壓提高到1.45V,通過PXA ...… 查看全部問答∨ |
大家好! 我的VS.net2005+wince6開發時,為什么CE debug zones不能用,它一直是灰色的,請問如何激活它讓它可用? 謝謝大家!… 查看全部問答∨ |
緊急求助:pxa270下SDIO wifi模組的驅動 Marvell 8686 請問誰能發給我一份在PXA270下可以使用的SDIO WIFI模組的驅動,模組型號是USI的WM-G-MR-09,模組使用的芯片是Marvell 8686. 我手里有廠商給的驅動,名稱是:SD-8686-WM60-ARMV4I-9.70.3.p23-38.p44.CAB,但是這份是基于PXA310和wince6.0的驅動,我 ...… 查看全部問答∨ |
|
有啥畫PCB的群、或者畫pcb的QQ,高手的,本人是個新手,剛接觸設計PCB,學習過程可能會遇到一些問題,想加一些大俠的Q來指導下,被人q:1729217470.。… 查看全部問答∨ |