痞子衡
认证:普通会员
作者动态
400行Python代码实现文语处理助手(1) - 环境搭建
14小时前
超级好用的可视化PyQt GUI构建工具(Qt Designer)
18小时前
浅析Cortex-M系统堆栈机制
2天前
极易上手的可视化wxPython GUI构建工具(wxFormBuilder)
4天前
第一本Git命令教程(1) - 准备
6天前

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妙用痞子衡便介绍完毕了,掌声在哪里~~~

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 1
收藏 2
关注 29
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧