作者按:本文CodeWarrior 10.6中的MPC5604B應用工程為例,介紹:①新建Qorivva MPC56xx MCU應用工程步驟和配置選項詳解、②新建Qorivva MPC56xx MCU應用工程文件詳解、③編譯目標FLASH和RAM的區別、④CodeWarrior 10.6 Qorivva MPC56xx系列MCU應用工程調試配置高級選項詳解、⑤debugger下載過程控制腳本文件(MCP5604B_VLE.tcl)詳解以及⑥如何修改MCP5604B_VLE.tcl實現在調試時,正常RAM調試目標復位等;
本文旨在解答大家使用CodeWarrior 10.x IDE開發和調試Qorivva MPC56xx系列汽車MCU應用工程時遇到的若干相關問題--比如編譯目標FLASH和RAM的區別、 如何在debug時對D-Flash或者外部QSPI Flash進行編程、如何在debug/下載應用程式的過程中保護指定存儲器地址空間等,希望對大家有所幫助和啟發。
內容提要
引言
1. CodeWarrior 10.6新建Qorivva MPC56xx MCU應用工程步驟和配置選項詳解
2. CodeWarrior 10.6新建Qorivva MPC56xx MCU應用工程文件詳解
3. 編譯目標FLASH和RAM的區別
4. CodeWarrior 10.6 Qorivva MPC56xx系列MCU應用工程調試配置高級選項詳解
4.1 設置高級編程選項--查看編程過程細節、指定Flash算法實現對D-Flash和外部QSPI Flash的編程以及保護Flash地址空間
4.2 設置MCU連接目標屬性
4.3 設置調試啟動後自動設置的默認程序斷點
5. debugger下載過程控制腳本文件(MCP5604B_VLE.tcl)詳解
5.1 關鍵詞set 定義全局變量
5.2 關鍵詞proc <functon_name> { parameter} { function script}定義腳本功能函數
① RAM初始化函數--proc init_ram {start range}
a. $parameter:獲取參數值;
b. expr ....:表達式計算;
c. reg ${GPR_GROUP}register = value:對CPU通用寄存器賦值;
d. mem v:[ address] = value :將數據value保存到存儲器地址address;
e. go 1 :運行CPU內核; stop:停止CPU內核
②獲取elf文件中的程序入口(復位向量)的函數--proc get_entry_point {}
③MPC560xx初始化函數--proc mpc560xx_init {mem_size}
④ 調試器工作環境設置函數--proc envsetup {}
5.3 腳本功能函數調用流程
總結
① 在debug啟動過程中調用MCP5604B_VLE.tcl
② 在調試界面中復位調試目標時調用MCP5604B_VLE.tcl
引言
很多讀者之前使用CW 2.10開發MPC56xx系列MCU的應用程式,但其調試界面不友好,調試效率較低,而且有一些較新的part number(比如MPC5642A)只能在CW10.x中支持,因而我推薦大家使用CW 10.x IDE。雖然CW 10.x使用與CW 2.10相同的編譯器、彙編器和連結器工具鏈,但其界面還是有很大的不同,尤其是調試界面。
本文旨在以CW10.6和MPC5604B為例,詳細介紹CW10.x IDE中MPC56xx系列MCU應用工程的創建、工程文件作用,不同的編譯目標配置和使用區別以及下載調試過程詳解,希望對大家使用CW10.x IDE開發和調試MPC56xx系列MCU應用程式有所幫助。
1. CodeWarrior 10.6新建Qorivva MPC56xx MCU應用工程步驟和配置選項詳解
通過CodeWarrior 10.6的新建工程嚮導,可以方便的創建Qorivva MPC56xx系列MCU的應用工程,以下以MPC5604B為例,詳細介紹各步驟中,配置選項的意義:
Step 1:菜單File-->New-->Bareboard Project打開應用工程創建嚮導:
Step 2:輸入應用工程名並選擇保存位置:
Step 3:選擇正確的part number(MPC5604B)和工程類型-Application(Application:應用工程;Library:靜態庫編譯工程)
Step 4:選擇Debug下載調試應用程式時連接的調試器(根據實際使用的調試器類型選擇,其中P&ECyclone為量產Flash離線編程器,也可以作為調試器使用, Open Source JTAG是Freescale官網demo板所使用的基於S08JM60的開源板載調試器)
Step 4:選擇程式語言(C/C++,對應不同的EWL2庫)、指令集(VLE/BookE, MPC560x系列MCU使用的是PowerPC e200z0/z0h內核,僅支持前綴「se_」開頭的16-bit/前綴「e_」開頭的32-bit的VLE指令集,不支持32-bit的BookE指令集)以及浮點數支持(None:不支持浮點數;Software:系統EWL庫整數指令實現;SPFP/SPFP_Only:硬體浮點數單元FPU實現,生成相應的浮點數指令,MPC560x系列MCU沒有硬體浮點數單元,只能選擇Software以軟體模擬方式實現浮點數計算)-->Finish,完成應用工程創建:
2. CodeWarrior 10.6新建Qorivva MPC56xx MCU應用工程文件詳解
在新建的MPC5604B應用工程中,其默認添加以下文件夾和文件:
文件夾Prefix:其中存在MPC5604B_FLASH_VLE.prefix和MPC5604B_RAM_VLE.prefix兩個前綴文件,分布應用於Flash和RAM編譯目標的編譯器全局符號和宏定義,以控制條件編譯過程:
在應用工程不同編譯目標配置:屬性(Properities)-->C/C++ Build-->Settings-->Tool Settings-->PowerPC Compiler-->Preprocessor-->Prefix File設置進行配置,默認兩個prefix文件配置如下:
Tips:用戶也可以在其中增加自己的全局條件編譯或者C語言宏定義,作用域為應用工程中的所有C源文件和頭文件。
文件夾Project_Headers:在文件夾下放置的是默認用於工程啟動(MPC5604B_HWInit.h)、中斷/異常處理代碼(Exceptions.h、IntcInterrupts.h)相關的頭文件和MCU外設寄存器定義頭文件(MPC5604B.h)以及數據類型定義文件(typedefs.h):
文件夾Project_Settings:其中包含了Debugger、Linker_Files和Startup_Code等3個子文件夾:
其中Debugger下的存在以下兩個文件:
a. MPC5604B_VLE.tcl:該文件是控制debugger下載過程的腳本文件,後文將詳細介紹:
b. MPC5604B.mem:存儲器配置文件,控制debug時,可見(range).vs保留(reserved)的存儲器地址區域及屬性(ReadWrite:可讀取;Read:只讀)以及保留區非法讀取時內容顯示字符定義(reservedchar):
Linker_Files文件夾下存放的是兩個連結文件(LCF--Linker Command File,全稱為連結器控制文件):
MPC5604B_FLASH.lcf:默認FLASH編譯目標使用的連結文件;
MPC5604B_RAM.lcf:默認RAM編譯目標使用的連結文件;
Tips:連結文件的作用是根據實際使用MCU part number的片上存儲器資源(如果支持外部存儲器(比如QSPI Flash或者SRAM等),則也會包含外部存儲器資源),定義不同存儲器地址區域(起始地址和長度大小)和用途劃分以及用戶應用工程中代碼和數據段的放置規則以及各種連結過程中連結器需要的符號(sympol)定義。
用戶也可以增加或者修改自己的連結文件,通過工程屬性(Properities)-->編譯目標(FLASH/RAM)-->C/C++ Build-->Settings-->Tool Settings-->PowerPC Linker-->Input-->Liner Command File(.lcf)設置:
關於Qorivva MPC56xx系列MCU的LCF文件使用和定義,請參考如下官方應用筆記(適用於CW10.x和CW 2.10 IDE):AN4497.CodeWarrior Linker Command File (LCF) for Qorivva_PX Application Note.pdf
第三個文件夾為Startup_Code,其中主要存放的是MCU啟動相關的代碼(__ppc_eabi_init.c: PPC架構EABI(Embedded Application Binary Interface--嵌入式應用二進位接口)初始化;MPC5604B_HWInit.c:MCU硬體初始化;MPC5604B_init_flash.c:編譯目標為FLASH時的用戶初始化定義;MPC5604B_init_ram.c:編譯目標為RAM時的用戶初始化定義;以及MPC5604B_Startup.c:啟動函數定義)
Tips:關於Qorivva MPC56xx系列MCU的啟動過程,請參本公眾號的如下文件(直接單擊跳轉即可閱讀):
Qorivva MPC56xx系列MCU啟動過程全解析(基於CW IDE應用工程--EAB I、連結文件、啟動文件和map文件)
Sources文件夾下默認添加了main.c(應用程式main()函數),和異常和INTC中斷處理初始化以及異常向量跳轉表等(Exceptions.c、 IntcInterrupts.c、ivor_branch_table.c):
3. 編譯目標FLASH和RAM的區別
CodeWarrior 10.6新建的Qorivva MPC56xx MCU應用工程自動創建了FLASH和RAM兩個編譯目標,同時也是調試目標,默認編譯目標為RAM,可以通過選中應用工程,選擇菜單編譯快捷方式(錘子圖標),選擇不同的編譯目標,並激活(active)之:
如果選擇FLASH作為編譯目標後,則會編譯並在工程目錄下自動生成一個FLASH文件夾,存放相關的編譯結果(elf文件--二進位可執行文件,包含調試信息和編程數據、map文件--連結結果的存儲器映射信息、mot文件--即32-bit MCU的S19編程文件,其取名源於摩託羅拉--Motorola的前3個字母。將其後綴直接修改為s19即可被FLASH編程器識別和使用了):
相應地,如果選擇RAM作為編譯目標後,則會編譯並在工程目錄下自動生成一個RAM文件夾,存放相關的編譯結果:
RAM和FLASH兩個默認創建的編譯目標配置和使用差別如下表:
另外,在調試配置界面中也會為不同的編譯目標創建不同的調試配置,調用不同的編譯結果elf文件:
Tips:通過選中應用工程右鍵-->Debug As-->Debug Configurations..即可打開以上調試配置界面,選擇和配置不同的調試目標:
4. CodeWarrior 10.6 Qorivva MPC56xx系列MCU應用工程調試配置高級選項詳解
通過點擊調試配置窗口中某一調試目標配置的Main-->Target settings-->Connection-->Edit..即可打開CW 10.6 Qorivva MPC56xx系列MCU應用工程調試配置目標連接屬性窗口:
在該屬性窗口中可以配置調試連結的相關設置:
Connection-->Interface:選擇不同的調試器類型
Connection-->Interface:查看調試器是否連接正常,若此處不能看見調試器USB接口,則需要檢查調試器連接和驅動安裝是否正常;
Target Communication Speed-->Debug Shift Freq:設置調試器時鐘頻率,即調試速度(JTAG接口的TCK時鐘頻率)。只有Cyclone和Multink FX可以設置不同的頻率,其餘調試器的頻率為固定值,不可設置; 有時候由於PCB上JTAG接口布局布線不好/走線過長,需要適當調低調試器頻率才可以正常工作。
4.1 設置高級編程選項--查看編程過程細節、指定Flash算法實現對D-Flash和外部QSPI Flash的編程以及保護Flash地址空間
點擊Advanced Programing Option,打開如下高級編程選項配置窗口:
① 勾選Enable Flash Programming Dialog,可以使能在debug下載程序的過程中彈出編程對話框窗口,便於查看下載過程中的FLASH編程編程腳本執行的步驟和細節,定位Flash編程相關問題。下圖為MPC5604B使能此選項後,debug時彈出的編程對話框窗口:
Tips:選擇RAM為編譯目標時,由於不會對Flash進行編程,即使勾選了此選項也不會彈出上圖的編程對話框窗口;
②勾選Use Alternative Algorithm,使能使用備用算法之後,可以通過Choose Alternative Algorithm選擇不同的FLASH算法,比如:
在CodeWarrior 10.6的安裝目錄(D:\Freescale\CW MCU v10.6.4\MCU\bin\plugins\support\EPPC\gdi\P&E)下有Qorivva MPC56xx系列MCU的各個part number的C-Flash和D-Flash算法文件(*.pcp):
以及一些外部QSPI FLASH的算法文件,比如MPC5606S和MPC5645S的QSPI外擴Spansion NOR FLASH的算法文件,燒寫外部QSPI FLASH加載使用:
Tips:默認的編程算法配置為使用創建工程時選擇的目標MCU part number的C-Flash的算法,可以將elf文件中連結到P-Flash中的數據和程序下載到C-Flash中,如果用戶在初始化了D-Flash的數據或者需要在QSPI接口外擴的Nor-Flash中存入數據,則需要選擇在此相應的算法文件;
另外,通過CodeWarrior 10.x IDE的debug,每次只能調用一個Flash算法文件,因此,如果需要燒寫多種Flash的數據,則需要調用多次debug,依次下載數據(推薦順序為外部QSPI Flash-->內部D-Flash-->內部P-Flash);量產時,可以通過P&E的量產Flash編程工具Cyclone在生成SAP編程鏡像文件時添加多個Flash算法和編程S19文件,從而實現一次編程多種Flash。
③勾選Preserve this Range( Memory Range 1/2/3),輸入合法的起始地址,即可保護程序下載過程中,對保護區域數據的擦除和重新編程;
Tips:設置此項時需要注意: 1. 默認不勾選保護Memory Range時,下載過程中會將所選擇算法對於的Flash存儲器空間全部擦除; 2. 要下載elf文件中不能包含設置保護的地址空間數據,否則會導致elf下載失敗;3.設置起始地址時,必須按照4/8位元組對齊,以保證Flash數據ECC結果的完整性(視具體part number的Flash ECC結構而定)
4.2 設置MCU連接目標屬性
在調試配置目標連接屬性窗口中,點擊Target-->Edit..,即可如下打開MCU連接目標設置窗口,進而可進行如下配置:
Target Type:選擇不同的MCU part number,默認為創建應用工程時的MCU part number,用戶也可在此修改為其他part number,從而在下載時調用其他MCU part number對應的FLASH算法文件;
Tips:Qorivva MPC56/57xx系列MCU中,同一個系列的MCU,不同part number之間具有存儲器和功能引腳封裝的兼容性,比如MPC5602B和MPC5604B,相同的LQFP-100/64封裝,其功能引腳兼容,只是Flash和SRAM的大小不同:
但Flash和SRAM的起始地址都相同,所以可以使用小容量的MPC5602B的Flash算法文件對大容量的MPC5604B進行編程,只是高地址(0x4000~0x7FFFF)的256KB C-Flash空間不會被擦除和編程,但反過來卻不行,因為MPC5604B的Flash算法要擦除MPC5602B中不存在256KB C-Flash,故而會出現擦除失敗。
Initialization-->Execute reset:勾選此選項則調試器下載程序到目標MCU之前將硬體復位目標MCU,否則不復位;
Initialization-->勾選Initialize target:指定下載過程中使用的調試控制腳本,默認為:${ProjDirPath}/Project_Settings/Debugger/MPC5604B_VLE.tcl,用戶可在此指定其他的腳本文件,以實現個性化的下載過程控制。
Memory-->勾選Memory configuration:配置存儲器映射文件(默認為${ProjDirPath}/Project_Settings/Debugger/MPC5604B.mem)
4.3 設置調試啟動後自動設置的默認程序斷點
通過選中調試目標-->Debugger-->Debug-->勾選Stop on Startup at,可以設置調試啟動後的默認程序斷點:
Program entry point:默認程序斷點為啟動函數/復位函數__startup();
User specified:用戶指定斷點地址,可以是elf程序中任意合法的函數名,比如默認的main,即為main()函數最開始。這也就是我們下載調試應用工程時默認程序指針(PC)停在main()函數最開始的原因所在。
Tips:如果遇到下載調試時程序無法運行至main()函數時,我們就可以將默認程序斷點設置為Program entry point,從啟動函數/復位函數__startup()開始跟蹤程序的運行,查找原因。
5. debugger下載過程控制腳本文件(MCP5604B_VLE.tcl)詳解
通過debugger控制腳本文件,用戶可以實現與P&E Multilink/Cyclone調試器的交互,實現對debug啟動過程的控制,比如對SRAM ECC的初始化、CPU寄存器、看門狗的初始化和配置等。下面就以MPC5604B的debugger控制腳本文件--MPC5604B_VLE.tcl為例給大家詳細介紹其功能和實現方法。
Tips:以下截圖中:
藍色高亮的為腳本文件語法系統保留關鍵詞;
「#」開始的行為注釋;
5.1 關鍵詞set 定義全局變量
如下為使用set定義的寄存器地址和SRAM ECC初始化大小:用戶也可以直接添加/修改全局變量定義, 此類全局變量定義之後可在整個腳本文件中調用;
Tips:默認應用工程添加的腳本控制文件與所選MCU part number對於,其會對所有的片內SARM進行ECC初始化; 用戶可以修改此處ram_size的大小,以實現調試SRAM個性化初始化(比如希望某段SRAM(典型如汽車儀表中的trip數據保護)---若想在非POR復位時不初始化SRAM,則除了修改start啟動函數中的初始化代碼之外,還需要修改此處的ECC初始化大小,或者直接注釋掉本腳本文件中對SRAM的ECC初始化腳本,以避免調試過程中調試器對其進行ECC初始化)。
5.2 關鍵詞proc <functon_name> { parameter} { function script}定義腳本功能函數
在腳本文件中,通過關鍵詞proc <functon_name> { parameter} { function script}將完成特定功能的腳本命令集合在一起,組成功能函數,被其他腳本命令調用。
在MPC5604B_VLE.tcl中定義了如下功能函數:
① RAM初始化函數--proc init_ram {start range}
該函數有兩個參數,start --起始地址,range--長度;通過$start獲得起始地址,通過set addr [expr $start + 0x18]計算SRAM起始地址+0x18作為SRAM初始化的首地址(addr),即0x40000018,通過語句set c [expr ($range-0x18)/128]獲得SRAM ECC初始化的長度(c),然後通過語句reg ${GPR_GROUP}GPR11 % = $addr和reg ${GPR_GROUP}GPR12 % = $c,將計算的SRAM ECC初始化首地址和長度分別賦值為CPU通用寄存器 GPR11和GPR12;緊接著通過若干mem v:[ address] = value,將SRAM ECC初始化程序的代碼指令二進位值存儲到地址0x40000000~0x40000017的地址空間,最後通過語句reg ${GPR_GROUP}PC = $start,讓CPU的PC程序指針寄存器指向這段代碼的首地址($start=0x40000000), 然後再調用語句go 1,執行完成SRAM ECC初始化;
Tips:此函數中用到的相關腳本語法有:
a. $parameter:獲取參數值;
b. expr ....:表達式計算;
c. reg ${GPR_GROUP}register = value:對CPU通用寄存器賦值;
d. mem v:[ address] = value :將數據value保存到存儲器地址address;
e. go 1 :運行CPU內核; stop:停止CPU內核
所謂對SRAM進行ECC初始化,就是向SRAM中寫入任意值。此函數中的實現方法是將32個CPU通用寄存器(GPR0~GPR31)循環寫入SRAM中,而最開始的0x18個字節中通過腳本已經寫入了SRAM初始化的代碼,故無需在寫入。而每個CPU通用寄存器是32-bit,即4位元組,所以一次循環將寫入32*4=128個字節,從而需要SRAM ECC初始化的長度為($range-0x18)/128;
②獲取elf文件中的程序入口(復位向量)的函數--proc get_entry_point {}
此函數通過搜尋C-Flash中的第一個boot sector中是否存在合法的bootID==0x5A0000, 判斷存在正確的Qorivva MCU啟動配置半字(RCHW),若為正確的RCHW,則偏移3位元組字節取得復位向量,並將其賦值給變量reset_vector_address,否則返回運行BAM(固化在晶片中的啟動代碼,地址位於0xFFFFC000,同樣將其賦值給變量reset_vector_address),最後返回人口地址reset_vector_address:
③MPC560xx初始化函數--proc mpc560xx_init {mem_size}
該函數有參數mem_size,即需要初始化的SRAM大小;
在此函數中,首先通過指令reset,向目標MCU發起復位,然後運行stop,停止CPU內核,接著讀取並判斷SSCM_STATUS寄存器(位於地址0xC3FD_8000),MCU是否為單晶片模式(single chip mode),若是,則通過指令mem address = value,關閉SWT看門狗(先向SWT_SR(位於地址0xFFF3_8010)服務寄存器中寫入SWT unlock序列0xc520和 0xd928,再向SWT_CR(位於地址0xFFF3_8000)控制寄存器中寫入關閉配置0xFF00000A),進而調用前面的介紹的功能函數進行SRAM初始化(語句init_ram 0x40000000 $mem_size)、獲取程序入口地址(語句reg ${GPR_GROUP}PC = [get_entry_point ]),最後將CPU堆棧指針賦值為非對齊地址0x3從而出發CPU執行代碼:
Tips:此函數中涉及以下知識點:
a. Qorivva MPC56xx系列MCU每次復位後都會執行其固化的BAM代碼,其工作流程圖如下:
b. 相關寄存器如下:
MPC560xB系列MCU的外設寄存器地址映射如下:
④ 調試器工作環境設置函數--proc envsetup {}
該函數配置調試器工作時,JTAG接口訪問MCU地址的數據類型,存儲器位寬,訪問長度等:
5.3 腳本功能函數調用流程
在MCP5604B_VLE.tcl的最後,調用上面介紹的envsetup 函數先配置好調試器工作環境,再調用mpc560xx_init 函數,完成SRAM 初始化並跳轉到程序入口執行:
總結
以上詳細介紹了MCP5604B_VLE.tcl,那麼它什麼時候會被調試器調用呢?有以下兩種情況:
① 在debug啟動過程中調用MCP5604B_VLE.tcl
當選擇FLASH作為編譯和調試目標時,在啟動debug的過程中,調試器的工作流程為:①調用執行MCP5604B_VLE.tcl初始化MCU,配置調試器運行環境-->②調用Flash算法文件(freescale_mpc5604b_1x32x128k_cflash.pcp,或者其他指定的Flash算法)下載elf/s19文件到Flash中-->③再次調用執行MCP5604B_VLE.tcl初始化MCU,配置調試器運行環境,並跳轉到應用程式入口執行,直至運行至默認斷點處。
Tips:若選擇RAM作為編譯和調試目標時,在啟動debug的過程中,則不會調用Flash算法文件對任何Flash進行編程,而是調用執行一次MCP5604B_VLE.tcl,初始化MCU,配置調試器運行環境,然後將elf/s19文件中的應用程式代碼和數據下載(直接存儲)到SRAM中,並跳轉到應用程式入口執行,直至運行至默認斷點處。
② 在調試界面中復位調試目標時調用MCP5604B_VLE.tcl
無論選擇RAM還是FLASH作為調試目標,在調試界面中,點擊reset快捷圖標進行復位時,都將打開Reset對話框,默認勾線了執行MCP5604B_VLE.tcl腳本對目標MCU進行初始化:
點擊Reset之後,可以在調試窗口的控制臺(Console)中,查看MCP5604B_VLE.tcl的執行過程日誌:
Tips:從MCP5604B_VLE.tcl的功能函數介紹,可知,在腳本文件中的proc mpc560xx_init {mem_size}函數中調用了「init_ram 0x40000000 $mem_size」對SRAM進行了初始化,所以,若在調試RAM目標時,復位調試目標,且使用默認的MCP5604B_VLE.tcl作為目標MCU初始化腳本時,將會把RAM調試目標下載(debug啟動過程中下載的)到SRAM中的應用程式代碼和數據破壞掉,從而出現程序跑飛的情況(因為編譯到SRAM中的應用程式代碼和數據已經不再存在)。
所以為了在調試RAM目標時,可以正常復位目標MCU重新調試,需要將MCP5604B_VLE.tcl中proc mpc560xx_init {mem_size}函數中調用了「init_ram 0x40000000 $mem_size」的腳本命令注釋掉:
以上就是今天跟大家分享的內容。希望對大家有用。
原創寫作不易, 如果大家覺得本文對你的工作和學習有幫助,也歡迎大家打賞鼓勵----我將堅持寫作,給大家帶來更多精彩的原創文章。
Tips:使用Android手機的讀者直接點擊文末的打賞連結進行打賞;使用iPhone的讀者由於蘋果公司關閉了微信打賞功能,請通過微信長按以下二維碼打賞鼓勵作者。
Thank you!
本微信公眾號已經發布的個人原創精品----嵌入式系統技術文章連結如下,歡迎大家參考學習,並轉發分享(可直接點擊下列文章題目跳轉閱讀):
如果你喜歡本公眾號的文章,請點擊文章最開始的公眾號關注或微信直接長按掃描識別下方二維碼關注,你也可以在微信添加朋友-->公眾號-->輸入"汽車電子expert成長之路"搜索-->點擊關注。若對本文觀點有任何意見和建議也歡迎留言指出。
您的關注、點讚、轉發分享是對我辛勤寫作的最大肯定!
胡恩偉
NXP汽車電子FAE
2018年2月12日於山城·重慶