痞子衡嵌入式:大話雙核i.MXRT1170之單獨線上調試從核工程的方法(IAR篇)

来源:https://www.cnblogs.com/henjay724/archive/2022/04/07/16114916.html
-Advertisement-
Play Games

大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是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() 函數。

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);
    }
}
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元起步)再發。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 假期結束了,準備好開始學習了嗎?今天給大家帶來一道列表的題目,快來看看你會不會解。前幾天有小伙伴問了一個Python列表的問題,這裡拿出來給大家分享下,一起學習下。 題目如下: Python學習交流Q群:903971231### SUMMER OF '69: Return the sum of th ...
  • 作者:小李子說程式 來源:https://www.toutiao.com/i6878184496945070604 前言 軟體開發springboot項目過程中,不可避免的需要處理各種異常,spring mvc 架構中各層會出現大量的try {...} catch {...} finally {.. ...
  • 前言 在日常生活中,我們的工作有時候需要對數據進行可視化,讓它一圖標之類的呈現出來。圖給人的感覺是最直觀的,並且能夠一眼就看到數據。 今天我們一起瞭解瀑布圖的重要性,以及如何使用不同的繪圖庫(如 Matplotlib、Plotly)繪製瀑布圖。瀑布圖是一種二維圖表,專門用於瞭解隨著時間或多個步驟或變 ...
  • 一、序言 Java多線程編程線程池被廣泛使用,甚至成為了標配。 線程池本質是池化技術的應用,和連接池類似,創建連接與關閉連接屬於耗時操作,創建線程與銷毀線程也屬於重操作,為了提高效率,先提前創建好一批線程,當有需要使用線程時從線程池取出,用完後放回線程池,這樣避免了頻繁創建與銷毀線程。 // 任務 ...
  • 介紹如何通過使用基於Roslyn的編譯時AOP框架來解決.NET項目的代碼復用問題。 可以在項目編譯時自動插入指定代碼,從而避免在運行時帶來的性能消耗。 ...
  • 2022年第一場Blazor中文社區的開發者分享活動,我們的團隊也全程參與其中,在議程中,也分享了我們團隊的Blazor 管理後臺模板,針對於Blazor,先科普一波,避免有些朋友不瞭解,Blazor是微軟推出的基於.NET的前端技術。利用現有的.NET生態,受於.NET的性能,可靠性和安全性,不僅 ...
  • 通常,PDF格式的文檔能支持的編輯功能不如office文檔多,針對PDF文檔裡面有表格數據的,如果想要編輯表格裡面的數據,可以將該PDF文檔轉為Excel格式,然後編輯。本文,將以C#代碼為例,介紹如何實現由PDF格式到Excel文檔格式的轉換。下麵是具體步驟。 【dll引用方法】 方法1 在程式中 ...
  • 一、原子操作 先看一段問題代碼 /// <summary> /// 獲取自增 /// </summary> public static void GetIncrement() { long result = 0; Console.WriteLine("開始計算"); //10個併發執行 Parall ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...