基于飛思卡爾的Bootloader程序下載更新_第1頁
基于飛思卡爾的Bootloader程序下載更新_第2頁
基于飛思卡爾的Bootloader程序下載更新_第3頁
基于飛思卡爾的Bootloader程序下載更新_第4頁
基于飛思卡爾的Bootloader程序下載更新_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

基于飛思卡爾的Bootloader程序下載更新前言寫這篇文檔是因為大三暑假時在一家公司實習(xí),做一個基于飛思卡爾的bootloader遠程更新工程,剛開始定的技術(shù)指標是基于MC9S12XS128單片機的Bootloader程序、遠程〔基于GSM網(wǎng)絡(luò)〕和CAN總線通信。但因為我只是一個本科實習(xí)生而且實習(xí)時間只有一個多月,所以只完成了基于SCI的本地寫入.S19文件的更新。這大概也就是這篇文檔所包含的內(nèi)容啦。整個程序是存在瑕疵甚至根本上可以說是不成功的,但是我覺得自己在做這個工程的過程中確實也解決了網(wǎng)上沒有提到或者沒有答案的一些問題,特寫此文檔,希望大家各取所需,如果有什么高見或者發(fā)現(xiàn)了我明顯錯誤的地方,也非常歡送大家給我指出。歡送大家前來指教。小目錄一、Bootloader的含義---------------------------------------------------------2二、SCI串口的使用------------------------------------------------------------3三、Flash的擦除和寫入--------------------------------------------------------5四、.S19文件的寫入-----------------------------------------------------------13五、心得體會-----------------------------------------------------------------14一、Bootloader的意義與作用關(guān)于Bootloader的意義網(wǎng)上非常之多,這里針對單片機的Bootloader程序進行說明。Bootloader是在單片機上電啟動時執(zhí)行的一小段程序。也稱作固件,通過這段程序,可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個適宜的狀態(tài),以便為最終調(diào)用應(yīng)用程序準備好正確的環(huán)境。Boot代碼由MCU啟動時執(zhí)行的指令組成。這里的loader指向MCU的Flash中寫入新的應(yīng)用程序。因此,Bootloader是依賴于特定的硬件而實現(xiàn)的,因此,在眾多嵌入式產(chǎn)品中目前還不可能實現(xiàn)通用Bootloader。Bootloader的最大優(yōu)點是:在不需要外部編程器的情況下,對嵌入式產(chǎn)品的應(yīng)用代碼進行更新升級。它使得通過局域網(wǎng)或者Intemet遠程更新程序成為可能。例如,如果有5000個基于MCU的電能表應(yīng)用程序需要更新,電能表制造商的技術(shù)人員就可以防止從事對每一個電能表重新編程的巨大工作量,通過使用Bootloader的功能,由控制中心通過電能表抄表系統(tǒng)網(wǎng)絡(luò),遠程對5

000個電表重新編程??梢姡珺ootloader功能對于嵌入式系統(tǒng)的廣泛應(yīng)用具有十分重要的意義。再舉一個例子。就拿我自己做這個程序的目的來說,我所在的公司將自己的產(chǎn)品賣到全國各地,如果哪一天公司的底層軟件工程師〔單片機工程師〕想要升級底層軟件,就可以借助GSM網(wǎng)絡(luò)直接通過單片機中的Bootloader程序進行底層軟件的自我更新,而不是派出售后人員一臺一臺的進行更新,節(jié)省了大量的人力物力。注意點:平時我們最常用到的下載程序的方法是通過USB數(shù)據(jù)線或其他數(shù)據(jù)線進行程序的燒寫,這個方式是通過外界提供應(yīng)單片機高電壓來對flash擦除和寫入完成的。而Bootloader不需要外界提供高電壓僅靠正常工作電壓便可完成對flash的擦除和寫入,從而到達更新程序的目的。二、SCI串口的使用前面也提到,我做的是通過SCI串口的本地更新。SCI(SerialCommunicationInterface,串行通信接口)是最常用、最經(jīng)典的串行通信接口方式。通信雙方除了要按照約定的真?zhèn)€是進行數(shù)據(jù)通信外,還要約定相同的通信速率,在SCI通信中使用波特率來表示。串行通信的波特率被定義為每秒內(nèi)傳送的位數(shù),單位為b/s或bps,常用的波特率有1200bps,4800bps,9600bps,19200bps,38400bps等。SCI的使用主要注意兩點:波特率的設(shè)置和工作方式的選擇,我選擇的是中斷工作方式。波特率:設(shè)置波特率的主要目的是使單片機和上位機〔上位機在這里就指將信息發(fā)給單片機的PC端〕保持同步。MC9S12XS128的波特率存放器是SCIBDH和SCIBDL,總共16位但是只有13位可以寫入。SBR[12:0]:波特率常數(shù),取值1~8191.波特率發(fā)生器的時鐘輸出是由MCU內(nèi)部總線時鐘BUSCLK分頻而來,SBR[12:0]就是分頻系數(shù),而SCI模塊需要的工作時鐘為波特率的16倍。SCI的波特率計算公式如下:SCI=fBUS/(16*SBR[12:0])波特率的計算數(shù)結(jié)果些許誤差可以忽略,以約等于常見通用的串行通信波特率數(shù)值。說了一大堆,到底如何設(shè)置不同的波特率呢,通過具體的程序代碼來表達一下。#defineSCIBusClock8000000//MC9S12XS128的總線時鐘是8MHz#defineSCI38400bps(unsignedint)((unsignedlong)(SCIBusClock)/(unsignedlong)(614400))//38400*1638400波特率#defineSCI19200bps(unsignedint)((unsignedlong)(SCIBusClock)/(unsignedlong)(307200))//19200*1619200波特率#defineSCI9600bps(unsignedint)((unsignedlong)(SCIBusClock)/(unsignedlong)(153600))//9600*169600波特率#defineSCI4800bps(unsignedint)((unsignedlong)(SCIBusClock)/(unsignedlong)(76800))//4800*164800波特率#defineSCIBaudRateSCI9600bps//大多數(shù)情況下用9600波特率中斷工作方式:選擇中斷的工作方式,一有數(shù)據(jù)從SCI串口輸出,單片機便立馬進行接收處理。主要對SCI0CR1和SCI0CR2進行操作。SCI0CR2=0x2C;//00101100RIE=1,TE=1,RE=1//RIE=1接收數(shù)據(jù)存放器滿和重疊中斷請求使能//TE=1發(fā)送器使能//RE=1接收器使能具體的數(shù)據(jù)接收代碼為://SCIReceiveN:串行接收N個字節(jié)數(shù)據(jù)------------------------------------------*byteSCIReceiveN(void){while(!SCI0SR1_RDRF);//如果SCI0SR1_RDRF為1那么表示數(shù)據(jù)起存器接收到的數(shù)據(jù)有效returnSCI0DRL;//返回接收到的值,即SCI數(shù)據(jù)存放器SCIDRL中的數(shù)據(jù)}溫馨提醒:SCI程序到底對不對,有沒有正常的工作,還是要通過上位機來觀察。這就牽扯到用什么軟件來作為單片機和上位機的接口。網(wǎng)上很多資料推薦一款很經(jīng)典的軟件“超級終端〞,但是我個人認為這款軟件太“經(jīng)典〞啦,太老啦,導(dǎo)致我一直不知道怎么用的。如果大家也遇到了這個問題,那么我向大家推薦“友善串口調(diào)試〞,完全的免費,而且界面簡潔,使用簡單,英文名為“SerialPortUtility〞。三、Flash的擦除和寫入關(guān)于Flash的擦除和寫入,真的是讓我最費力的一局部,網(wǎng)上的相關(guān)資料很少,好不容易找到了一點相關(guān)代碼,卻發(fā)現(xiàn)程序不能正常的運行,而且更令人無解的是程序本身怎么檢查都檢查不出錯誤。好啦,一點一點的說說我的辛酸史。首先,如果你在尋找飛思卡爾的flash擦除寫入操作,很遺憾的告訴你,如果你用的不是MC9S12XS系列,那么很有可能,你所需要的flash擦除寫入操作和我接下來將要說明的擦除寫入操作根本上不沾邊〔除了原理上〕,因為飛思卡爾不同系列的單片機對flash的擦除寫入操作的定義差異很大,不注意型號的話反而會被誤導(dǎo)。至于擦除和寫入的原理是什么,這個不是我們關(guān)心的,我也不去贅述,我主要說明一下相關(guān)的具體操作。我們主要是對飛思卡爾Flash中的PFlash即存放程序段的Flash進行操作。如圖,步驟大概分為:1、設(shè)置Flash分頻存放器:Flash的操作對頻率有一定的要求,過低擦除不成功,過高會損毀Flash如圖為MC9S12XS128的FCLKDIV存放器,所有位都是可讀的但是只有7位可寫入。至于應(yīng)該如何設(shè)置分頻數(shù),有一張表格可以參考:如表格說明,分頻數(shù)是根據(jù)外部時鐘來定的,MC9S12XS128的外部時鐘是16MHz,所以我選擇了0x10作為分頻數(shù)。給出一一些具體的代碼:/*************************************************************名稱:voidPFlash_Init(void)**功能:PFlash初始化**入口參數(shù):無**出口參數(shù):無**使用說明:無************************************************************/voidPFlash_Init(void){while(FSTAT_CCIF==0);//等待正在處理的Flash操作,即CCIF=1時,操作完成FCLKDIV=0x10;//外部晶振為16MHz,F(xiàn)lash時鐘設(shè)置為1MHzFCNFG=0x00;//禁止中斷while(FCLKDIV_FDIVLD==0);//等待時鐘設(shè)置成功,即FDIVLD為1時設(shè)置成功}這里補充一下對FCLKDIV_FDIVLD的說明:說明很簡單,一看就看懂。2、FSTAT狀態(tài)存放器在上面的代碼中出現(xiàn)了一行,這就涉及到一個很重要的存放器,就是Flash操作的狀態(tài)存放器,就像是Flash操作步驟中的“紅綠燈〞一樣,告訴程序什么時候可以執(zhí)行什么操作,什么時候必須要等待一下。如圖:其中我們比擬關(guān)心的是CCIF位、ACCERR位和FPVIOL位,這三位也都是可讀可寫的。CCIF:指令完成標志位,當CCIF位為1時,表示上一個Flash操作完成了。注意圖中的高亮局部,如果想要使當前操作的指令完成,需要手動將CCIF清零〔標志位置位就是令標志位為0,但具體操作是令標志位等于1〕,才能觸發(fā)指令,令指令完成,也就是前面流程圖中說明的,才能launch指令。ACCERR和FPVIOL:這兩位主要標志是否有錯誤操作發(fā)生,當為1時,說明檢測到錯誤。那檢測到作物怎么辦呢?解決方法也比擬奇葩,將兩個標志位清零〔清零操作如上〕就行,,,,,至于什么原理,我也不太明白。數(shù)據(jù)手冊如圖,強烈建議還是自己讀一下原文,很有好處。再給出一些具體的代碼:CCIF的操作代碼:FSTAT_CCIF=1;//啟動執(zhí)行命令,即launch指令while(FSTAT_CCIF==0);//等待執(zhí)行完成ACCERR和FPVIOL的操作代碼:if(FSTAT_ACCERR)//判斷并去除標志位;FSTAT_ACCERR=1;//將標志位清零if(FSTAT_FPVIOL)//判斷并去除標志位;FSTAT_FPVIOL=1;//將標志位清零注意點:說實話,當時我自己寫程序的時候,就對標志位清零操作感到非常的疑惑,說好的清零操作呢,為什么是令標志位為等于1?后來才想明白,對于標志位,寫0等效于沒有操作,寫1代表清零。原因主要有兩點:標志位為1一般表示有什么事情發(fā)生啦,對于標志位什么時候為1,應(yīng)該是單片機根據(jù)具體的情況作出自己的判斷,是根據(jù)實際情況來置1的,而不應(yīng)該是人為的置1。如果某次操作我們只想對狀態(tài)存放器中的某一位或某幾位進行操作,那么對其余位就必須沒有任何的影響,如果規(guī)定寫0時等效于無操作。3、執(zhí)行具體的指令將分頻和狀態(tài)存放器弄好后,就可以開開心心的執(zhí)行具體的指令啦。指令具體的指令主要涉及到FCCOBIX存放器和FCCOB存放器:FCCOBIX存放器和FCCOB存放器必須要配合使用。FCCOBIX進行選擇,然后往FCCOB中寫入具體的指令、地址和數(shù)據(jù)。Flash操作命令表如圖:這里我們只關(guān)心P-Flash的擦除和寫入操作。P-Flash的擦除操作:如圖,;令CCOBIX為000,往FCCOB中寫入0x0A和高地址位,對照指令表,0X0A表示擦除操作,高地址位就是Globaladdress模式下地址的高八位。然后令CCOBIX為001,往FCCOB寫入Globaladdress模式下地址的第八位,就可以擦除你想要的擦除的地址片區(qū)。/*************************************************************名稱:voidPFlash_Erase(wordADDR16)**功能:擦除P-FLASH的一個分區(qū)**入口參數(shù):無**出口參數(shù):無**使用說明:無************************************************************/voidPFlash_Erase(wordADDR16){while(FSTAT_CCIF==0);if(FSTAT_ACCERR)//判斷并去除標志位;FSTAT_ACCERR=1;if(FSTAT_FPVIOL)//判斷并去除標志位;FSTAT_FPVIOL=1;FCCOBIX_CCOBIX=0x00;FCCOB=0x0A7E;//寫入擦除命令和高位地址,0A是指令,7E是高地址位FCCOBIX_CCOBIX=0x01;FCCOB=ADDR16;//寫入低16位的地址FSTAT_CCIF=1;//啟動執(zhí)行命令while(FSTAT_CCIF==0);//等待執(zhí)行完成}P-Flash的寫入操作:寫入操作和擦除操作是差不多的,模式是不是和擦除操作很像。CCOBIX為000和001時的含義和擦除操作是完全一樣的。主要講一下CCOBIX為010~101時的含義。因為MC9S12XS128規(guī)定Flash寫入時,必須一次性寫入8個字節(jié),,,是的就是這么蛋疼。不多說啦,直接來一些具體的代碼,就很好理解啦。/*************************************************************名稱:voidPFlash_Write(uint16ADDR16)**功能:向PFLASH寫入數(shù)據(jù)**入口參數(shù):無**出口參數(shù):無**使用說明:無************************************************************/voidPFlash_Write(wordADDR16){bytei,j;//i為Buffer的下標,j為string的下標for(i=0,j=0;i<4;i++,j++){Buffer[i]=0x0000;Buffer[i]=Buffer[i]|(string[j]<<8);j++;Buffer[i]=Buffer[i]|string[j];}while(FSTAT_CCIF==0);if(FSTAT_ACCERR)//判斷并去除標志位;FSTAT_ACCERR=1;if(FSTAT_FPVIOL)//判斷并去除標志位;FSTAT_FPVIOL=1;FCCOBIX_CCOBIX=0x00;FCCOB=0x067E;//寫入命令和高位地址(06是對P-Flash進行固化的指令)FCCOBIX_CCOBIX=0x01;//地址后16位FCCOB=ADDR16;//寫入低16位地址FCCOBIX_CCOBIX=0x02;//寫入第一個數(shù)據(jù)FCCOB=Buffer[0];FCCOBIX_CCOBIX=0x03;//寫入第二個數(shù)據(jù)FCCOB=Buffer[1];FCCOBIX_CCOBIX=0x04;//寫入第三個數(shù)據(jù)FCCOB=Buffer[2];FCCOBIX_CCOBIX=0x05;//寫入第四個數(shù)據(jù)FCCOB=Buffer[3];FSTAT_CCIF=1;//寫入執(zhí)行命令while(FSTAT_CCIF==0);//等待執(zhí)行完畢}這段程序理解起來應(yīng)該沒有問題吧。4、最后一步:好啦,看到這里是不是想要自己寫一個Flash操作代碼嘗試一下,然后你單步調(diào)制的時候會發(fā)現(xiàn)太好啦,終于擦除和寫入啦,然后開始全速運行,咦,發(fā)現(xiàn)程序跑飛啦,不放棄,接著嘗試,然后怎么檢查都檢查不出錯誤來,單步運行就是可以,全速運行就是不可以,反復(fù)屢次,你會感到抓狂,會感到。好啦好啦,不瞎扯啦,其實這個問題也困擾了我很久,因為我沒有系統(tǒng)的學(xué)習(xí)過單片機,終于,在TI的論壇上,沒錯,你沒有看錯,一個飛思卡爾的問題最終在TI論壇上找到了解決方法〔吐槽一下,飛思卡爾真是奇葩,資料超少,軟件也超貴,相關(guān)的論壇也超冷淡。相比來說,TI做的就很好,資料很多,軟件免費而且好用,論壇也很火〕。其實原因是,F(xiàn)lash不能對本身就行操作,也就是說在Flash中的代碼不能對Flash進行操作,必須轉(zhuǎn)移到RAM中才可以。怎么解決這個問題呢,我自己用的是#pragma關(guān)鍵字,再配合上codewarrior的.prm文件,就可以啦,全速運行下沒有問題。#pragmaCODE_SEGFLASH_RAM//在.prm文件中將FLASH_RAM定義在RAM區(qū)中//對flash進行操作的代碼#pragmaCODE_SEGDEFAULF關(guān)于#pragma和.prm怎么用,又是另一個主題啦,在這里就不贅述。除此之外還有一個方法,就是利用RELOCATE_TO,至于RELOCATE_TO怎么用,也是另外一個話題,在這里給出一些資料,要用到的同學(xué)可以自己去看看。關(guān)于RELOCATE_TO的關(guān)鍵定義: Inthisexam

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論