痞子衡嵌入式:超級下載算法(RT-UFL)開發筆記番外(1) - JLinkScript妙用



  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是超級下載算法開發筆記番外篇之JLinkScript妙用

  JLinkScript 文件是配套 J-Link 調試器使用的腳本,這個腳本適用於需要定制 J-Link 執行操作的場景,它可以幫助用戶完成 J-Link 標准工具做不到的一些事情(比如 J-Link 連接順序或者執行復位的方式,或者一些定制的硬件板需要一些特殊處理),關於 JLinkScript 文件詳細解釋參見痞子衡舊文 《JLink Script文件基礎》

  痞子衡在開發 《RT-UFL - 一個適用全平台i.MXRT的超級下載算法設計》 項目時,遇到幾個難點問題,幸好有 JLinkScript 文件幫忙才得以輕松解決,今天痞子衡就跟大家分享一下解決問題過程:

一、解決默認RAM空間分配不適的問題

  超級下載算法工程是 MIMXRT_FLEXSPI_UV5.uvprojx,基於 Keil MDK uVision5,在工程選項設置里,IROM空間是 0x1000 地址開始的 60KB(0x0 - 0xFFF空間留有它用)、IRAM 空間是 0x20000000 開始的 64KB,總空間大小是 124KB。

  在整個 i.MXRT 系列里,i.MXRT1011的內部 RAM 空間最小,但也有 128KB,大小符合超級下載算法需求。但是其默認 RAM 分配是 32KB ITCM(0x0 - 0x7FFF), 32KB DTCM(0x20000000 - 0x20007FFF), 64KB OCRAM(0x20200000 - 0x2020FFFF),這就不符合超級下載算法需求了。PS: 除了i.MXRT1011之外,其他 i.MXRT 型號默認 RAM 空間都符合算法要求。

  如何解決這個默認 RAM 空間分配不適的問題?當然是調整 FlexRAM 配置了,在《百變星君FlexRAM》 一文里,我們知道 i.MXRT1011 里有兩種調整 FlexRAM 分配的方式,一種是燒寫 eFuse(靜態方式,一次性地,冷啟動系統自動完成),另一種是改寫 IOMUXC_GPR 寄存器(動態方式,可多次,軟復位仍然保持有效),所以很自然地我們想到了通過 JLinkScript 文件來改寫 IOMUXC_GPR 寄存器方式來達成目的,這樣對芯片后續運行沒有根本性影響。文件路徑在 JLinkDevices.xml 里指定:

  iMXRT1011_CortexM7.JLinkScript 內容就比較簡單了,按要求改寫 IOMUXC_GPR16/17 即可:

void ReconfigFlexRAM()
{
    unsigned int base;
    unsigned int value;

    base = 0x400AC000;

    value = 0xFA;
    MEM_WriteU32(base + 0x44, value);
    value = MEM_ReadU32(base + 0x44);
    JLINK_SYS_Report1("GPR17:", value);

    value = MEM_ReadU32(base + 0x40);
    value |= 0x4;
    MEM_WriteU32(base + 0x40, value);
    value = MEM_ReadU32(base + 0x40);
    JLINK_SYS_Report1("GPR16:", value);

    JLINK_SYS_Report("J-Link script: FlexRAM has been reconfigured to 64KB ITCM, 64KB DTCM");
}

void SetupTarget(void) {
  ReconfigFlexRAM();
}

void AfterResetTarget(void) {
  ReconfigFlexRAM();
}
  • Note:這種方法也可以用來解決客戶應用程序存在動態調整 FlexRAM 的代碼導致軟復位后 IDE 無法再次下載的問題,因為下載算法需要的 RAM 空間被重新分配掉了,我們需要在 JLinkScript 再將其改回來。

二、解決ROM空間不重疊帶來的型號識別問題

  在 《 識別當前i.MXRT型號》 一文中,痞子衡詳細描述了超級下載算法設計里是如何識別具體 i.MXRT 型號的,簡單概括就是因為芯片本身沒有固定地址寄存器來標明型號,因此我們用比對 ROM 空間里指定地址內容的方式來替代(每個 i.MXRT 型號 ROM 內容都不一樣,且同內核型號 ROM 起始地址是一致的),文中僅用 RT600 和 RT1060 兩個型號來做了示例,但在增加 i.MXRT1010 和 i.MXRT1170 兩款型號支持時,我們發現這兩款 ROM 可讀空間竟然沒有重疊。

  i.MXRT1011 的 ROM 空間是 0x200000 - 0x20FFFF(64KB),i.MXRT117x 的 ROM 空間是 0x200000 - 0x23FFFF(256KB),乍一看,這不是有重疊的嘛。但是很可惜的是,i.MXRT117x 前 64KB ROM 空間被刻意保護起來了,代碼無法訪問,因此比對 ROM 空間內容的方法對 i.MXRT1170 來說就失效了,必須新找其他方法來做型號識別。

  痞子衡有考慮過用讀芯片外設寄存器的方式來區分 i.MXRT 型號(找有差異的那個即可),但是在 Memory Map 里找了一圈也沒找到合適寄存器,因為 i.MXRT10xx 與 i.MXRT11xx 在外設寄存器地址分配上差異很大,也是幾乎沒有地址重疊的外設。

  無奈之下,痞子衡又想到了通過 JLinkScript 文件來在固定 RAM 地址處寫標識的方式來達成目的,痞子衡選擇了 0xFFFC - 0xFFFF 地址空間里的四個字節來存放標識,因此我們在超級下載算法工程選項設置里將這個地址先留出來:

  然后對超級下載算法源代碼里 ufl_get_imxrt_chip_id() 函數做一點小改動,這里我們用了 0x5AA60FF0 來標識 I.MXRT1170,實測是可行的,當然如果覺得不放心,可以將標識空間再拓大一些,標識符也相應長一些。

#define FP_FLAG_ADDR     (0x0000FFFCu)
#define FP_FLAG_RT117X   (0x5AA60FF0u)

rt_chip_id_t ufl_get_imxrt_chip_id(void)
{
    rt_chip_id_t chipId = kChipId_Invalid;
    core_type_t coreType;

    coreType = ufl_get_core_type();
    if (kCoreType_CM7 == coreType)
    {
        uint32_t rt117xFlag = *(uint32_t *)FP_FLAG_ADDR;
        if (rt117xFlag == FP_FLAG_RT117X)
        {
            return kChipId_RT117x;
        }
        else 
        {
            // 代碼省略...
        }
    }
    else if (kCoreType_CM33 == coreType)
    {}

    // 代碼省略...

  與第一小節一樣,在 JLinkDevices.xml 里指定好 JLinkScript 文件路徑,然后 iMXRT117x_CortexM7.JLinkScript 內容也比較簡單,按要求將標識符寫進 RAM 里即可:

void SetFlagInITCM()
{
    MEM_WriteU32(0xFFFC, 0x5AA60FF0);

    JLINK_SYS_Report("J-Link script: 0x5AA60FF0 has been written to address 0xFFFC");
}

void SetupTarget(void) {
  SetFlagInITCM();
}

void AfterResetTarget(void) {
  SetFlagInITCM();
}
  • Note:標識符似乎不能放在 0x0 - 0xFFF 空間里,這個空間在當前超級下載算法設計里被 JLink 占用了,痞子衡測試了 0x0 - 0x3 和 0xFFC - 0xFFF 兩處空間地址,均失敗了。

  至此,超級下載算法開發筆記番外篇之JLinkScript妙用痞子衡便介紹完畢了,掌聲在哪里~~~

歡迎訂閱

文章會同時發布到我的 博客園主頁CSDN主頁知乎主頁微信公眾號 平台上。

微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM