大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是i.MXRT1170下單獨線上調試從核工程的方法(基於IAR)。 兩年前痞子衡寫過一篇《雙核i.MXRT1170之Cortex-M7與Cortex-M4互相激活之道》,那篇文章從離線啟動的角度介紹了跑雙核應用的基本方法,基本上把雙核啟動 ...
大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是i.MXRT1170下單獨線上調試從核工程的方法(基於IAR)。
兩年前痞子衡寫過一篇《雙核i.MXRT1170之Cortex-M7與Cortex-M4互相激活之道》,那篇文章從離線啟動的角度介紹了跑雙核應用的基本方法,基本上把雙核啟動的細節都介紹到了。
在應用開發的階段,很多時候我們還是需要線上調試的,主核的調試沒什麼特別要註意的地方,從核的調試大家估計就有點陌生了,今天痞子衡就給大家介紹下 IAR 開發環境下調試從核工程的方法:
一、測試準備
首先需要準備好測試環境,包含必要的軟體和硬體,痞子衡的環境如下:
- 集成開發環境: IAR EW for Arm v9.10.2,[點此下載](https://www.iar.com/products/architectures/
- 軟體開發包: SDK_2.11.0_MIMXRT1170-EVK(Toolchain要包含IAR),點此下載
- 軟體驅動: J-Link driver v7.56b,點此下載
- 硬體工具: J-Link Plus調試器
- 硬體開發板: MIMXRT1170-EVK (Rev.C),含板載 DAP-Link 調試器
我們知道 i.MXRT1170 其實主從核是在 Fuse 里可配的,我們就以預設配置(Cortex-M7 為主,Cortex-M4 為從)為例來介紹,選取的測試工程是 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm4。
二、在IAR下調試
使用 IAR 打開 hello_world_demo_cm4.eww 工程,切換到 debug build (就是在 RAM 中執行)。
2.1 工程選項處理器選 Cortex-M4 核調試情況
我們先來看一下工程選項里處理器選擇 Cortex-M4,並且不使能任何額外腳本時調試情況。也就是說在明知主核 Cortex-M7 處於激活狀態而 Cortex-M4 處於未激活狀態時,IAR C-SPY 調試組件能否工作。
痞子衡分別測試了板載 DAP-Link 調試器以及外接 J-Link 調試器,測試結果均是不能直接調試,DAP-Link 下提示 "Failed to connect to CPU",J-Link 下提示 "Select core is not same as the target core"。
2.2 工程選項處理器選 NXP MIMXRT1176xxxA_M4 調試情況
再來看一下工程選項里處理器選擇 NXP MIMXRT1176xxxA_M4 時調試情況(會調用相關腳本,在 IAR/J-Link 里已經做好)。也就是雖然 Cortex-M4 處於未激活狀態,但是有配套腳本會負責激活工作。
J-Link 下是可以直接調試的,在 Debug Log 視窗,我們可以看到有 .jlinkscript 腳本執行的痕跡,腳本列印信息里顯示其識別到 Cortex-M4 未激活,並且會做激活相關工作。
- Note: 這個跟 NXP MIMXRT1176xxxA_M4 選擇相關的 .jlinkscript 腳本在 JLink 驅動安裝目錄下,由於 log 里沒有直接顯示路徑,那大概率已經被打包進 DLL 文件里了,我們看不到具體腳本代碼實現。
DAP-Link 下也是可以直接調試的,在 Debug Log 視窗,我們可以看到 iMXRT_1170.dmac 腳本被執行了,腳本列印信息里顯示其識別到 Cortex-M4 未激活,並且會做激活相關工作。
- Note: 這個跟 NXP MIMXRT1176xxxA_M4 選擇相關的 iMXRT_1170.dmac 腳本在 IAR 安裝目錄下,具體路徑已經在 log 里顯示出來了,我們可以看到其具體腳本代碼實現。
如果你細心觀察,你會發現 DAP-Link 下必須要在工程選項 Debugger / Extra Options 裡加 “--macro_param enable_core=1” 語句才能正常調試,這是因為 iMXRT_1170.dmac 腳本需要接受這個參數才能正常激活從核 Cortex-M4。
2.3 自己實現用於從核調試的腳本
現在我們知道了調試從核 Cortex-M4 工程必須要有專門腳本來負責激活從核才行,雖然 IAR/J-Link 里已經做好這個腳本,但是兩者行為是否統一我們不清楚(畢竟看不見 J-Link 下腳本源碼),而且這個腳本是隨著 IAR/J-Link 版本而變化的,具有一定的不可控性。
為了完全掌控從核調試的主動性與確定性,最好我們自己重新實現 IAR/J-Link 下的調試腳本,線上調試時直接指定使用我們自己寫的腳本,這樣即使工程選項里處理器選擇 Cortex-M4 我們也能正常調試。
對於 DAP-Link,我們新建一個 mimxrt1170_connect_cm4_user.mac 文件(具體內容見附錄一)放到工程目錄下,並且在 IAR 選項里指定使用這個 mac 文件。這個 mac 文件語法詳見 《IAR內部C-SPY調試組件配套巨集文件(.mac)用法介紹》,其中最重要的是 execUserCoreConnect() 保留巨集函數里要做激活 Cortex-M4 工作。
- Note: 如果希望調試從核 Cortex-M4 時,主核 Cortex-M7 依然在跑,可以註釋掉 mimxrt1170_connect_cm4_user.mac 文件里的 execUserSetup() 函數。
對於 J-Link,我們新建一個 mimxrt1170_connect_cm4_user.jlinkscript 文件(具體內容見附錄二)放到工程目錄下,並且在 IAR 選項里指定使用這個 jlinkscript 文件。這個 jlinkscript 文件語法詳見 《JLink Script文件基礎及其在IAR下調用方法》,其中最重要的是 InitTarget() 用戶自定義動作函數里要做激活 Cortex-M4 工作。
- Note: 如果希望調試從核 Cortex-M4 時,主核 Cortex-M7 依然在跑,可以註釋掉 mimxrt1170_connect_cm4_user.jlinkscript 文件里的 AfterResetTarget() 函數。
附錄一、IAR 腳本(用於DAP-Link)
prepare_core_spin_code(cmVersion)
{
__var start;
if (cmVersion == 7)
{
start = 0x2021FF00;
__writeMemory32(start >> 7, 0x40c0c068, "AP0_Memory");
}
if (cmVersion == 4)
{
start = 0x20200000;
__writeMemory32(start & 0xFFFF, 0x40c0c000, "AP0_Memory");
__writeMemory32(start >> 16, 0x40c0c004, "AP0_Memory");
}
__writeMemory32(start + 0x20, start, "AP0_Memory");
__writeMemory32(0x223105, start + 0x4, "AP0_Memory");
}
release_core(cmVersion)
{
if (cmVersion == 7)
{
__writeMemory32(0x2, 0x40c04000, "AP0_Memory");
}
if (cmVersion == 4)
{
__writeMemory32(0x1, 0x40c04000, "AP0_Memory");
}
}
reset_core(cmVersion)
{
__var reg;
__var ctrlAddr;
__var statAddr;
if (cmVersion == 7)
{
ctrlAddr = 0x40c042a4;
statAddr = 0x40c042b0;
}
if (cmVersion == 4)
{
ctrlAddr = 0x40c04284;
statAddr = 0x40c04290;
}
__writeMemory32(0x1, ctrlAddr, "AP0_Memory");
do
{
reg = __readMemory32(statAddr, "AP0_Memory");
__delay(10);
}while(reg & 0x1);
}
//_ExecDeviceCoreConnect()
execUserCoreConnect()
{
__probeCmd("j.i swd /force");
// dummy read
__readAPReg(2);
__delay(10);
// Disable system reset caused by sysrstreq from each core
__writeMemory32(0x3c00, 0x40C04004, "AP0_Memory");
prepare_core_spin_code(4);
release_core(4);
// switch to AP1
__writeDPReg(1<<24, 2);
}
execUserPreReset()
{
reset_core(4);
release_core(4);
__writeDPReg(1<<24, 2);
}
execUserSetup()
{
__var reg;
reg = __readMemory32(0x40c04000, "AP0_Memory");
if((reg & 0x2) == 0)
{
prepare_core_spin_code(7);
reset_core(7);
}
}
附錄二、J-Link 腳本
void prepare_core_spin_code(unsigned int cmVersion)
{
unsigned int start;
if (cmVersion == 7)
{
start = 0x2021FF00;
MEM_WriteU32(0x40c0c068, start >> 7);
}
if (cmVersion == 4)
{
start = 0x20200000;
MEM_WriteU32(0x40c0c000, start & 0xFFFF);
MEM_WriteU32(0x40C0c004, start >> 16);
}
MEM_WriteU32(start, start + 0x20);
// BootROM go_fatal_mode()
MEM_WriteU32(start + 0x4, 0x223105);
}
void release_core(unsigned int cmVersion)
{
if (cmVersion == 7)
{
MEM_WriteU32(0x40C04000, 0x2);
}
if (cmVersion == 4)
{
MEM_WriteU32(0x40C04000, 0x1);
}
}
void reset_core(unsigned int cmVersion)
{
unsigned int reg;
unsigned int ctrlAddr;
unsigned int statAddr;
if (cmVersion == 7)
{
ctrlAddr = 0x40c042a4;
statAddr = 0x40c042b0;
}
if (cmVersion == 4)
{
ctrlAddr = 0x40c04284;
statAddr = 0x40c04290;
}
MEM_WriteU32(ctrlAddr, 1);
do
{
reg = MEM_ReadU32(statAddr);
SYS_Sleep(10);
}while (reg & 0x1);
}
void InitTarget(void)
{
CPU = CORTEX_M7;
// Manually configure AP
JLINK_CORESIGHT_AddAP(0, CORESIGHT_AHB_AP);
JLINK_CORESIGHT_AddAP(1, CORESIGHT_AHB_AP);
JLINK_CORESIGHT_AddAP(2, CORESIGHT_APB_AP);
// Dummy read
JLINK_CORESIGHT_ReadAP(JLINK_CORESIGHT_AP_REG_IDR);
SYS_Sleep(10);
// Disable system reset caused by sysrstreq from each core
MEM_WriteU32(0x40C04004, 0x3c00);
prepare_core_spin_code(4);
release_core(4);
// Switch to AP1
CPU = CORTEX_M4;
CORESIGHT_IndexAHBAPToUse = 1;
}
void ResetTarget(void)
{
CORESIGHT_IndexAHBAPToUse = 0;
reset_core(4);
release_core(4);
CORESIGHT_IndexAHBAPToUse = 1;
}
void AfterResetTarget(void)
{
unsigned int reg;
reg = MEM_ReadU32(0x40c04000);
if((reg & 0x2) == 0)
{
prepare_core_spin_code(7);
reset_core(7);
}
}
至此,i.MXRT1170下單獨線上調試從核工程的方法痞子衡便介紹完畢了,掌聲在哪裡~~~
歡迎訂閱
文章會同時發佈到我的 博客園主頁、CSDN主頁、知乎主頁、微信公眾號 平臺上。
微信搜索"痞子衡嵌入式"或者掃描下麵二維碼,就可以在手機上第一時間看了哦。
最後歡迎關註痞子衡個人微信公眾號【痞子衡嵌入式】,一個專註嵌入式技術的公眾號,跟著痞子衡一起玩轉嵌入式。
衡傑(痞子衡),目前就職於恩智浦MCU系統部門,擔任嵌入式系統應用工程師。
專欄內所有文章的轉載請註明出處:http://www.cnblogs.com/henjay724/
與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]
可以關註痞子衡的Github主頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。
關於專欄文章有任何疑問請直接在博客下麵留言,痞子衡會及時回覆免費(劃重點)答疑。
痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。