前面介紹了如何利用MCC生成Bootloader和Application的過(guò)程,此種方法簡(jiǎn)單方便,如果需要更復(fù)雜的功能,可以在此框架下進(jìn)行完善。下面將介紹采用修改鏈接文件.gld實(shí)現(xiàn)基本的Bootloader和Application功能。
鏈接文件描述
MPLAB XC16目標(biāo)鏈接器可基于重定位目標(biāo)代碼和任意歸檔/庫(kù)文件生成用于dsPIC DSC和PIC24 MCU系列器件的二進(jìn)制代碼。大多數(shù)情況下都不需要直接調(diào)用鏈接器,因?yàn)榫幾g器驅(qū)動(dòng)程序xc16-gcc會(huì)自動(dòng)使用所有必須的參數(shù)執(zhí)行鏈接器。直接使用鏈接器并不簡(jiǎn)單,通常只有那些具有扎實(shí)的編譯器和鏈接知識(shí)的用戶才應(yīng)嘗試這么做(Bootloader相對(duì)不好做呀)。鏈接描述文件控制鏈接過(guò)程的各個(gè)方面,包括:
(1)分配數(shù)據(jù)存儲(chǔ)器和程序存儲(chǔ)器;
(2)將段從輸入文件映射到輸出文件;
(3)構(gòu)造特殊數(shù)據(jù)結(jié)構(gòu)(如中斷向量表);
(4)分配目標(biāo)器件的絕對(duì)SFR地址。
鏈接文件在整個(gè)編譯過(guò)程所處的位置如下:
比如對(duì)默認(rèn)鏈接文件的程序進(jìn)行編譯后觀察Program Memroy,入口地址默認(rèn)跳轉(zhuǎn)至0x200進(jìn)行程序的執(zhí)行,前面6個(gè)是不可屏蔽陷阱向量(0x000E地址保留),后面是中斷向量詳細(xì),均按照默認(rèn)地址進(jìn)行分配。
創(chuàng)建Boot項(xiàng)目
1.在MPLAB X IDE里面新建一個(gè)Boot Project(與新建普通項(xiàng)目過(guò)程一致),使能Timer1和AN0中斷;重新再編譯,觀察Program Memory,可以發(fā)現(xiàn)對(duì)應(yīng)IVT地址發(fā)生了變化。
2.修改.gld文件
鏈接描述文件在X:\Program Files\Microchip\xc16\v1.50\support\dsPIC33C\gld跟目錄下,現(xiàn)在對(duì)默認(rèn)gld的“.ivt __IVT_BASE :”部分進(jìn)行修改。0x2000是從Page5開(kāi)始,為什么每次加4?是因?yàn)槊總€(gè)GOTO語(yǔ)句占用兩條指令,前面篇章有介紹。
添加修改好的gld鏈接文件。
對(duì)項(xiàng)目進(jìn)行重新編譯,觀察Program Memory,可以看到IVT地址均發(fā)生了變化,產(chǎn)生了0x2000的偏移。
至此,Boot項(xiàng)目建立完畢。
創(chuàng)建Application項(xiàng)目
1.同樣在MPLAB X IDE新建一個(gè)App Project,使能AN0和Timer1中斷,這時(shí)需要將Bootloader的中斷關(guān)閉,如果在bootloader和application里面都有同樣的中斷,會(huì)產(chǎn)生編譯錯(cuò)誤。
2.修改gld文件IVT偏移地址,Reset地址為0x2000,IVT地址被重映射為0x2004開(kāi)始,Application入口地址為0x2400,長(zhǎng)度0x29B00.
此處Application的Flash起始地址是0x2000,如果沒(méi)有通知編譯器在該位置放置一個(gè)reset跳轉(zhuǎn)指令,而是由程序默認(rèn)把初始化代碼放在該處,這樣做會(huì)有一定風(fēng)險(xiǎn),編譯器有一定的概率將其他代碼放在了Flash起始位置,所以需要在gld文件中指定reset=0x2000,并不要屏蔽Reset Instruction.
修改Configuration Words部分。
修改默認(rèn)gld里面“.ivt __IVT_BASE :”部分如下,在修改的時(shí)候一定要對(duì)照datasheet里面的中斷IVT地址一一對(duì)應(yīng),否則會(huì)出錯(cuò)。
添加gld文件到項(xiàng)目文件。
編譯成功后觀察Program Memory,入口地址0x2000跳轉(zhuǎn)到0x2402執(zhí)行Application程序,同時(shí)T1中斷和AN0中斷也分別跳轉(zhuǎn)到不同的地址去執(zhí)行中斷函數(shù)。
Bootloader和application分別添加修改后的GLD,可以看到Timer1 IVT地址0x0016產(chǎn)生偏移地址后為0x002028,在Application執(zhí)行Timer1中斷后,發(fā)生中斷后通過(guò)GOTO指令跳轉(zhuǎn)至0x2B74地址去執(zhí)行中斷函數(shù)。
在Application項(xiàng)目中添加Boot Project。
編譯會(huì)發(fā)現(xiàn)出錯(cuò),如下:
主要是因?yàn)殒溄悠鲗閱⒂玫闹袛嗌梢粋€(gè)默認(rèn)向量,這就是為什么盡管Bootloader通過(guò)修改GLD文件設(shè)置了固定值,但仍由應(yīng)用程序設(shè)置了值的原因。 應(yīng)用程序設(shè)置了“ 002B74”,而B(niǎo)ootloader設(shè)置了“ 002028”。
同時(shí)在屬性設(shè)置里面需要將創(chuàng)建默認(rèn)中斷ISR Unlock,如下:
另外在Application GLD中需要對(duì)使能中斷名進(jìn)行重新命名,同時(shí)中斷函數(shù)也要改成一致。
重新進(jìn)行編譯,觀察Application Flash Program Memory,IVT地址被重映射,偏移地址是0x2000,Application入口地址是0x2402.
至此,通過(guò)GLD修改完成了Bootloader IVT重映射和存儲(chǔ)空間的再分配。