This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3220S:自定义引导

Guru**** 2525750 points
Other Parts Discussed in Thread: CC3220S, UNIFLASH, ENERGIA, CC3200

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1189520/cc3220s-custom-boot

器件型号:CC3220S
主题中讨论的其他器件: UNIFLASHENERGIACC3200

在具有 CC3220S 的定制板中、我需要能够启动2个不同的应用

在闪存中、这2个应用程序的可执行文件必须被分开(App1.bin 和 App2.bin)

为此、我开发了一个定制的二级引导加载程序、在确定必须执行哪些应用程序后、将其加载到 RAM 中并 运行

  • 我的 Booloader 占用地址0x20004000-0x2001285F
  • 应用程序从地址0x20014000开始驻留(因此与我的引导不存在重叠)
  • .resetVecs 元素放置在0x20014000中(链接器 cmd 文件中强制的值)
  • resetISR 位于0x200302d5 (从映射文件读取的值)中

我的启动成功启动、并从0x20014000开始将 App1从闪存复制到 RAM

要运行应用、我使用以下汇编器行、强制寄存器 R0 = 0x20014000 (=应用程序.resetVecs 的地址)

  1. ldr sp、[r0]->将堆栈指针重置为初始值
  2. 添加 r0、r0、#4 ->将 R0增加4 (R0 = 0x20014004)
  3. LDR R1、[r0]->在0x20014004中、有应用程序的复位 ISR 的地址、该地址在 R1中复制
  4. BX R1 -->跳转至包含在 R1中的地址(然后应用程序的 resetISR 的地址存储在程序计数器中)

使用 Code Composer Studio 12中的内置调试器时、一切看起来都正常、但应用程序无法运行...

我使用 UniFlash 8将所有内容集成到闪存中

  • 我的引导加载程序是 MCU 映像
  • 该应用程序作为用户文件插入到/sys/app1.bin 中(mu boot 用于加载该应用程序的相同路径)

编程并重新启动后:

  • 启动开始
  • 应用程序加载到 RAM 中(通过 CRC32控制来确保正确加载)
  • 先前的汇编器行已 成功执行

(笑声) 但应用程序无法启动。

对于应用、我尝试将调试版本和 MCU+Image 版本保存在闪存中、但没有任何变化

我出了什么问题?

谢谢、Andrea

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andrea:

    您描述的内容应该起作用。 我对CC3220SF 的引导加载程序使用类似的方法(第二级引导程序正在从 XIP 闪存执行)、这是我很久以前编写的、并且工作正常。 我个人怀疑链接器文件存在一些问题、但如果不调试真实代码、很难说... 也许在我的 bootlaoder 源代码中、您会找到一些线索。

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jan、

    非常感谢您的回复。

    我的引导加载程序源代码与您的源代码非常相似(仅在加载和执行应用程序的过程下面)

    #define SRAM_BASEADDR           0x20000000
    #define SRAM_APP_OFFSET            0x14000
    
    void RunFirmwareImage(unsigned long);
    __asm("    .sect \".text:RunFirmwareImage\"\n"
          "    .clink\n"
          "    .thumbfunc RunFirmwareImage\n"
          "    .thumb\n"
          "RunFirmwareImage:\n"
          "    ldr    sp,[r0]\n"
          "    add    r0,r0,#4\n"
          "    ldr    r1,[r0]\n"
          "    bx     r1");
    
    void LoadAndExecute(AppRec_t AppRec)
    {
    	unsigned long Token;
    	long FileHandle;
    	SlFsFileInfo_t FsFileInfo;
    
        // Get the file size using File Info structure
        if (sl_FsGetInfo(FWname[AppRec], NULL, &FsFileInfo) >= 0)
        {
            // File exist - open it
            FileHandle = sl_FsOpen(FWname[AppRec], SL_FS_READ, &Token);
            if (FileHandle > 0)
            {
                // File opened - read it into RAM
                if (sl_FsRead(FileHandle, 0, (unsigned char *)(SRAM_BASEADDR + SRAM_APP_OFFSET), FsFileInfo.Len) >= 0)
                {
                    // File copied into RAM - close it
                    if (sl_FsClose(FileHandle, 0, 0, 0) >= 0)
                    {
                        // Eval and check CRC32
                        if (CRC32check(AppRec, (unsigned char *)(SRAM_BASEADDR + SRAM_APP_OFFSET), FsFileInfo.Len) == 0)
                        {
                            // CRC32 is correct - stop the network services
                            sl_Stop(200);
                            // Execute the application
                            RunFirmwareImage(SRAM_BASEADDR + SRAM_APP_OFFSET);
                        }
                    }
                }
            }
        }
    }

    唯一的区别是 CRC32check()函数,用于验证 RAM 中加载的文件的 CRC32

    我有2个问题:

    1. 由于我的器件是 CC3220S (安全)、因此必须对应用程序(在您的示例中为 energia.bin、在我的示例中为 app1.bin)进行签名、或者我可以使用 CCS 中构建的"正常" bin 文件?
    2. 在我的应用程序中打开映射文件我注意到:
      1. 入口点符号:"resetISR" 地址:2000cc25
      2. 2000cc24  0000001a   nortos_cc32xx.a:startup_cc32xx_ccs.oem4 (.text:resetISR)

    在行(a)中、 复位 ISR 的地址 是一个奇数 、该地址加载到程序计数器中以运行应用程序;这是正确的?

    此致

    Andrea

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andrea:

    您的问题答案:

    1.应用程序在二进制代码的开头不能有带签名的标头。 只有引导加载程序才应根据证书链进行签名、因为这是由 ROM 引导程序验证的。 您应该验证您的应用程序代码是否不包含此标头。

    2.很抱歉,但我不理解你的问题。 我不会定期使用 TI 编译器中的映射文件。 但我认为类似的工作可以在 CCS 中执行"内存分配工具"。

    我可以为 CC3200器件的应用程序和引导程序提供链接器文件示例。 我在前一个项目中使用的代码。 由于 CC3220S 和 CC3200具有相同的代码执行方式(来自引导程序0x20004000的入口点、256KB RAM 以及从 RAM 执行)、因此示例也应在 CC3220S 中工作。

    引导加载程序:

    --retain=g_pfnVectors
    
    #define RAM_BASE 0x20004000
    
    MEMORY
    {
        SRAM_CODE (RWX) : origin = 0x20004000, length = 0x8000
        SRAM_DATA (RWX) : origin = 0x20000000, length = 0x4000
    }
    
    SECTIONS
    {
        .intvecs:   > RAM_BASE
        .init_array : > SRAM_CODE
        .vtable :   > SRAM_CODE
        .text   :   > SRAM_CODE
        .const  :   > SRAM_CODE
        .cinit  :   > SRAM_CODE
        .pinit  :   > SRAM_CODE
        .data   :   > SRAM_DATA
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_DATA(HIGH)
    }

    应用:

    --retain=g_pfnVectors
    
    #define RAM_BASE 0x20020000
    
    MEMORY
    {
        SRAM_DATA (RWX) : origin = 0x20000000, length = 0x20000  /* 128 KB */
        SRAM_CODE (RWX) : origin = 0x20020000, length = 0x20000  /* 128 KB */
    }
    
    SECTIONS
    {
        .intvecs:   > RAM_BASE
        .init_array : > SRAM_CODE
        .vtable :   > SRAM_CODE
        .text   :   > SRAM_CODE
        .const  :   > SRAM_CODE
        .cinit  :   > SRAM_CODE
        .pinit  :   > SRAM_CODE
        .data   :   > SRAM_DATA
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_DATA(HIGH)
    }
    

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jan、

    使用 CCS 中的"去汇编"窗口中的分步调试、我发现我的 Booloader 运行正常

    堆栈指针和程序计数器被成功设置并且内核执行"某些操作"(我只看到汇编器代码)

    但是,如果我让代码自由运行, 它会跳 转到 FreeRTOS resetISR()

    因此、我尝试了以下实验:

    • 我重建了我的 App1、以便将.resetVecst 映射到0x20004000 (入口点地址)中
    • 我被引导加载程序从闪存中移除、并使用 App1 (通过 Uniflash)对其进行了覆盖

    这样,SLB 应该直接启动 App1 -->但不能 启动 App1 (!)

    奇怪的是、如果我通过 CCS 中的调试器加载 App1、一切都正常

    但我认为这个新问题需要一个新的问题...

    此致

    Andrea