在1.2.2章節我們安裝了SDK程序(安裝位置:G:\nxp),在1.2.3章節我們安裝了IAR開發工具,接下來我們打開IAR開發工具,如圖 1所示![]() 在本章節我們主要是講解如何通過IAR+JLINK調試i.MX6ULL的IAR工程,關于IAR工具的具體使用,大家可以網上查找相關的文檔。 然后我們點擊“file->open->workspace”,如圖 2所示: ![]() 然后會打開“Open Workspace”對話框,我們這里以sdk里面的hello_world工程為例,來學習一下通過JLINK來調試i.MX6ULL的程序。該工程的目錄在sdk安裝位置的“boards\evkmcimx6ull\demo_apps\hello_world\iar”目錄下面,因為我們的sdk安裝到了G盤的nxp文件夾下,所以hello_world工程的絕對路徑是“G:\nxp\boards\evkmcimx6ull\demo_apps\hello_world\iar”(大家可以根據自己sdk安裝的位置,選擇對應的目錄)。我們在“Open Workspace”對話框里選擇hello_world工程的目錄,最終在改目錄下選擇“hello_world.eww”(IAR工程文件的后綴名是eww),然后點擊“打開”按鈕,如圖 3所示 ![]() Hello_world工程打開后的界面如圖 4所示: ![]() 我們可以看到該工程提供了四種編譯方式,如圖 5所示: ![]() 我們這里使用默認的“ddr_debug”方式編譯該工程。 我們可以點擊工具欄上的“Make”按鈕,編譯該工程,如圖 6所示: ![]() 從上圖的編譯結果輸出信息,我們可以看到編譯成功。 然后我們連接JLNIK V9下載器到i.MX6ULL終結者開發板的JTAG接口,如圖 7所示:
由于i.MX6ULL芯片的JTAG接口和SAI(聲卡)是復用的,所以我們使用JTAG接口的時候需要修改下開發板(V1.0的底板需要去掉底上的電阻R183;V1.1的底板需要去掉聲卡芯片旁邊的跳線帽(J50))。 然后我們連接開發板的調試串口到PC電腦上,并在電腦上打開串口終端,串口終端的波特率設置成115200,8位數據位,無奇偶校驗,1位停止位,不選擇流控,如圖 8所示:
設置完成串口終端,我們打開串口終端,如圖 9所示:
然后我們給開發板上電,接著我們在IAR工程界面的菜單欄點擊“Debug without Loading”圖標,如圖 10所示:
如果JLINK和開發板的JTAG接口連接正確的話,會進入到調試界面,如圖 11所示:
從上圖我們可以看到hello_world的程序已經開始運行,程序的指針在main函數入口處停止,等待我們執行調試。
從上圖,我們可以看到一共有7個快捷圖標,他們分別是: Step Over:單步執行(沒點擊一次,程序相應的運行一行) Step Into:如果程序指針當前指向的是一個函數調用,如果點擊此圖標,則會進入到當前指向的這個函數內部 Step Out:與Step Into想對應,如果我們通過Step Into進入到某個函數內部去執行了,此時想返回到之前的函數,并繼續執行此前函數的嚇一跳命令,我們可以點擊此圖標 Next Statement:右擊某一行選“Set Next Statement”,可以不執行中間程序,執行點直接到此行,用于不執行某些代碼 Run to Cursor:程序調試的時候運行到光標處(我們可以在任意一行程序鼠標單擊一下,使光標定位到該行,然后點擊“Run to Cursor”,程序就會運行到光標所在的行,并停住) Go:執行程序,程序遇到斷點會停止,如果沒有設置斷點,程序就會一直繼續執行 Stop Debugging:結束調試模式 在調試模式下控制程序執行主要通過上面的7個快捷圖標來實現。 下面我們來看一下怎么給程序設置斷點。IAR工程里面給程序設置斷點很簡單,我們在普通編譯模式或者調試模式下,只需要鼠標點擊每行最左側的灰色空白區域,就可以為該行添加斷點,如圖 13所示:
斷點添加完成后,如圖 14所示:
從上圖我們可以看到添加斷點的行,在該行的最左側會有一個“紅色的實點”。 取消斷點的方式和添加斷點的方式一樣,我們只需要鼠標單擊斷點的“紅色實點”,就可以取消添加的斷點。 接下來我們演示下通過JLINK調試i.MX6ULL的程序,我們在編譯完成hello_world工程以后(點擊菜單欄的Make快捷圖標),然后點擊菜單欄的“Debug without Downloading”快捷圖標,進入調試模式,如圖 15所示:
然后進入調試模式,程序指針跳轉到main函數的入口處,等待調試運行,如圖 16所示:
然后我們在調用PRINTF函數的一行添加一個斷點,如圖 17所示:
然后我們點擊調試快捷圖標中的“Stop Over”開始單步執行,程序數顯會執行到“BOARD_InitPins();”一行,如圖 18所示:
然后我們繼續點擊“Step Over”快捷圖標,程序運行到“BOARD_BootClockRUN();”該行,如圖 19所示;
我們可以看到上圖中程序指針指向的該行“BOARD_BootClockRUN()”是一個函數調用,接下來我們演示一下“Step Into”快捷圖標進入到函數內部執行的功能。我們點擊調試快捷圖標中的“Step Into”快捷圖標,可以看到程序指針進入到BOARD_BootClockRUN函數內部,如圖 20所示:
然后我們把光標定位到“if (CLOCK_GetMux(kCLOCK_Pll1SwMux) == 0)”該行,然后點擊調試快捷圖標中的“Run to Cursor”,延時下該圖標的功能,點擊完改圖標,程序指針直接運行到了 “if (CLOCK_GetMux(kCLOCK_Pll1SwMux) == 0)”該行,并停在了該行,等待我們繼續點擊調試快捷圖標,如圖 21所示:
然后我們點擊調試快捷圖標中的“Step Out”快捷圖標,演示下跳出“BOARD_BootClockRUN”函數,并繼續運行該函數后面的程序,運行結果如圖 22所示:
然后我們點擊調試快捷圖標中的“Go”快捷圖標,演示下該圖標的功能。我們在“PRINTF(“hello world.\r\n”);”一行添加了一個斷點,運行結果如圖 23所示:
從上圖我們可以看到“Go”快捷圖標的功能是程序繼續運行,如果遇到斷點,就停止,否則一直往下執行。 上圖中的程序最后進入while(1)主循環,在while(1)主循環里面主要實現接收串口數據,并把接收到的串口數據通過串口再次發送出去。為了驗證“Go”快捷圖標在沒有遇到斷點的情況下會一直執行,我們繼續點擊“Go”快捷圖標,繼續運行程序,我們可以看到串口終端打印輸出了“hello world.”字符串,如圖 24所示:
然后我們在串口調試終端輸入任意的字符,可以看到串口調試中斷會打印出我們輸入的字符,運行結果如圖 25所示:
我們在調試完程序,可以通過調試快捷圖標中的“Stop Debugging”快捷圖標退出調試模式,運行結果如圖 26所示:
|