自己用C語言寫單片機(jī)PIC18 serial bootloader
掃描二維碼
隨時(shí)隨地手機(jī)看文章
HyperBootloader_PIC18_J 和 HyperBootloader_PIC18_None_J
完成PIC16 bootloader (詳細(xì)情況請閱讀我的上一篇隨筆《自己用C語言寫單片機(jī)PIC16serial bootloader》) 后,接著就開始寫PIC18的UART bootloader。事實(shí)上我寫了HyperBootloader_PIC18_J 和 HyperBootloader_PIC18_None_J 兩種bootloader。 一種給PIC18F, 另一種給PIC18FJ。兩種bootloader除了在實(shí)現(xiàn)上有一點(diǎn)不同,大小也不同外,其他都差不多。都是模仿HI-TECH PICC bootloader實(shí)現(xiàn)的, 都是放置在程序存儲(chǔ)器的頭部,電腦端的程序都是用超級終端傳送應(yīng)用程序的Hex文件。在繼續(xù)之前,先講講PIC18F和PIC18FJ的區(qū)別。
PIC18F和PIC18FJ的區(qū)別
PIC18F和PIC18FJ一個(gè)不同點(diǎn)是CONFIG BITS的燒寫位置。對于PIC18F, CONFIG BITS被映射到程序存儲(chǔ)器300000h (虛擬地址)開始的單元中。對于PIC18FJ,CONFIG BITS被燒寫到程序存儲(chǔ)器的底部(真實(shí)地址),每次上電自動(dòng)會(huì)被映射到程序存儲(chǔ)器300000h (虛擬地址)開始的單元中,所以對于PIC18FJ, 更新了CONFIG BITS,reset后才生效。
Interrupt Vector Remap
由于bootloader 位于程序存儲(chǔ)器的頭部,需要對Interrupt Vector進(jìn)行remap. 代碼如下。
#asm PSECTintcode gotoAPP_START+0x8 PSECTintcodelo gotoAPP_START+0x18 #endasm
HyperBootloader_PIC18_None_J主要代碼段
HyperBootloader_PIC18_None_J 每接收一行的超級終端發(fā)過來的Hex數(shù)據(jù),一個(gè)一個(gè)程序字地?zé)?。具體實(shí)現(xiàn)的主要代碼段如下。
for(;;)//loopuntilendoffile{while(RCREG!=':');//waitforstartofhexfilelinewhile(!TXSTAbits.TRMT);TXREG=':';//theprompttodownloadanewprogramcksum=bcount=g2x();//getthebytecount#if_EEPROMSIZE>256EEADRH=TBLPTRH=g2x();//gettheaddress#elseTBLPTRH=g2x();#endifTBLPTRL=EEADR=g2x();DO_NOT_INCREMENT=1;rectype=g2x();//gettherecordtypeswitch(rectype){caseDATA://ldatarecord#if(PROG_START>0x200)||defined(__PIC18FX520)//toprotectbootloaderfrombeingoverwrittenif((FLASH)&&(TBLPTRU==0)&&(TBLPTRH<(unsignedchar)(PROG_START>>8)))//toprotectbootloaderfrombeingoverwrittenbreak;//ifbootloaderisthreatened,skipthis#endifclear_buffer();while(bcount--){TABLAT=EEDATA=buff[(EEADR&(_FLASH_WRITE_SIZE-1))]=g2x();//getthedataif((CONFIG)||(EEPROM)){if(CONFIG)//EEPROM/config.writebyteatatime{table_write();}//zap();}else{if((EEADR&(_FLASH_WRITE_SIZE-1))==(_FLASH_WRITE_SIZE-1))//program/IDLOCsflashbytesatatime{flash8();clear_buffer();}}EEADR++;}if(((EEADR&(_FLASH_WRITE_SIZE-1))!=0)&&(FLASH)&&(!CONFIG))flash8();checksum();break;caseEND://endofhexfilechecksum();TXSTA=0x02;//resetUSARTbeforejumptoapplicationRCSTA=0x00;(*((void(*)(void))PROG_START))();//jumptonewprogrambreak;caseEXTEND_ADDRESS://extendedaddressrecordwhile(bcount--){EEADR=g2x();//determineswhetherEE,ConfigorID}EEPGD=1;if(EEADR==0xF0)EEPGD=0;//selectforEEPROMCFGS=0;if((EEADR&0xF0)==0x30)CFGS=1;//selectforconfigwriteTBLPTRU=EEADR;checksum();break;}}
HyperBootloader_PIC18_J 主要代碼段
HyperBootloader_PIC18_J 每接收一行的超級終端發(fā)過來的Hex數(shù)據(jù),在存到block數(shù)組中,block滿了,再整個(gè)block地?zé)洝>唧w實(shí)現(xiàn)