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**** 2535750 points
Other Parts Discussed in Thread: CC3220S, UNIFLASH, CC3220SF, CC3200

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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1016225/cc3220s-bootloader-and-customer-application-how-to-realize

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

客户希望在 CC3220S 上实现引导加载程序和用户应用程序。 引导加载程序需要将用户应用程序加载到 RAM、然后跳转到用户应用程序。

我们的想法是通过 Uniflash 工具将第一个程序引导加载程序添加到 CC3220S。 然后使用 PC 上运行的应用通过   UART 将用户应用程序发送到引导加载程序。

以下是需要澄清的问题:

 引导加载程序应将用户应用程序置于 RAM 中的哪个位置? 地址范围是多少?

2. 如何让引导加载程序跳转到用户应用程序并开始执行用户应用程序?

3.用户应用程序是否需要更改内存位置?

4.如何管理用户应用程序的堆栈和中断向量?

   

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

    您好!

    我不确定您的客户为何要针对这些功能实施自己的引导加载程序。 ROM 引导加载程序支持完全相同的功能、您无需编写自己的引导加载程序。 此处提供了通过 ROM 引导加载程序进行编程的 UART 协议说明

    但是、如果您的客户仍想创建自己的 bootlaoder、有用的资源:

    • CC3200 SDK。 在这里、您可以找到引导加载程序示例、该示例演示了如何将代码加载到 RAM 中并从 RAM 开始执行。 此 SDK 与 CC3220S 器件不兼容、但您可以使用它们作为灵感来源。
    • 我的引导程序代码。 该代码旨在为 CC3220SF 器件加载代码、但也很有用。

    您的问题答案:

    CC3220S 器件具有256KB RAM、起始地址为0x20000000。 CC3220S 器件应用程序的入口点为地址0x20004000。 ROM 引导程序将文件/sys/mcuimg.bin 加载到地址0x20004000并开始执行。 您自己的 bootlaoder 需要链接到0x20004000的开头。

    请参阅我的引导程序代码和此代码。

    //*****************************************************************************
    // jump to code
    //*****************************************************************************
    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");
    
    
    //*****************************************************************************
    // main
    //*****************************************************************************
    void mainThread(void) {
    
      int status;
      signed long handle;
      unsigned long token;
      SlFsFileInfo_t FsFileInfo;
    
      SPI_init();
      InitTerm();
        
      // run NWP
      status = sl_Start(0,0,0);
      if (status < 0) {
        SHOW_ERROR("Unable to start NWP (code=%d)", status);
      }
    
      // get size of file energia.bin
      status = sl_FsGetInfo(APP_FILENAME, 0, &FsFileInfo);
      if (status < 0) {
        SHOW_ERROR("Unable to get size of file '%s' (code=%d)", APP_FILENAME, status);
      }
    
      // open file for read + load code into RAM
      handle = sl_FsOpen((unsigned char *)APP_FILENAME, SL_FS_READ, &token);
      if (handle < 0) {
        SHOW_ERROR("Unable to open file '%s' (code=%d)", APP_FILENAME, handle);
      }
      status = sl_FsRead(handle, 0, (unsigned char*)APP_OFFSET, FsFileInfo.Len);
      if (status < 0) {
        SHOW_ERROR("Unable to read file '%s' (code=%d)", APP_FILENAME, status);
      }
      status = sl_FsClose(handle, 0, 0, 0);
      if (status < 0) {
        SHOW_ERROR("Unable to close file '%s' (code=%d)", APP_FILENAME, status);
      }
    
      // stop NWP
      status = sl_Stop(0);
      if (status < 0) {
        SHOW_ERROR("Unable to stop NWP (code=%d)", status);
      }
    
      // jump to code
      runFirmwareImage(APP_OFFSET);
    }

    3.由您自己的引导加载程序加载的应用程序的入口点可以位于 RAM 地址空间的任意位置。 但请注意、不会与您自己的 bootlaoder 的代码发生冲突。

    向量表没有问题、因为 Cortex-M4可以将向量表重新映射到地址空间的任何位置。 针对自己的引导程序和应用程序的堆栈大小和位置取决于您的需求。 但是、启动器堆栈的最佳选择是首先使用16kB 或 RAM。

    1月

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

    您好,
    根据您为我提供的运行应用程序的方式、我尝试了两种方案、但都没有成功。
    请帮助我分析故障原因。 运行 runFirmwareImage (app_offset)后、应用程序将停止运行。
    运行时环境:
    计划1:
    APP_OFFSET:0x2001E800
    SRAM0 (rwx):origin = 0x20000000,length = 0x4000
    SRAM (rwx):origin = 0x2001E800,length = 0x00040000 - 0x1E800
    部分

       bootVecs: type = DSECT
       /*.resetVecs:加载> 0x20004000*/
       .resetVecs:载入> 0x2001E800
       vecs:load > 0x20000000、type = NoLoad

       xdc.meta:类型= COPY
       xdc.noload: type =复制

    #define SRAM_base 0x2001E800
    计划2:
    APP_OFFSET:0x2001E800
    SRAM0 (rwx):origin = 0x20000000,length = 0x4000
    SRAM (rwx):origin = 0x20004000,length = 0x00040000 - 0x4000
    部分

       bootVecs: type = DSECT
       .resetVecs:load > 0x20004000
       vecs:load > 0x20000000、type = NoLoad

       xdc.meta:类型= COPY
       xdc.noload: type =复制

    #define SRAM_base 0x20004000

    谢谢。

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

    您好!

    如果不调试真实的应用、很难说出会出现什么错误。

    第一步、您需要确保正确执行您的 Bootlaoder 代码、之后您可以 stat 构建您的应用程序代码。 如果您的应用程序入口点链接在 RAM 中间的某个位置(例如0x2001E800)、则无需创建两个存储器区域、如 SRAM0和 SRAM。 当入口点位于地址0x20004000时、此存储器分配用于能够使用前16kB 或 RAM。 这不是您的应用情况。 但是、创建两个区域是合理的、一个用于0x2001E800上的代码、另一个用于0x20000000上的数据。 这在 CC3200 SDK 中进行了演示、我在该论坛上的其他一些文章(我现在无法找到)也进行了演示。

    1月

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

    您好!

    我没有从你的答复中得到答复。

    首先、我自己的引导加载程序可以很好地运行。 默认情况下、CCS 会创建其参数。
    我使用自己的引导加载程序将我自己的引导加载程序(作为应用程序)加载到0x2001E800的 RAM 中、并执行 runFirmwareImage (0x2001E800)方法。
    在执行 runFirmwareImage (0x2001E800)方法之前、我将这些数据从 0x2001E800打印到0x2001E800 + BOOT_SIZE。 它与 bootloader.bin 相同。
    遗憾的是、程序在执行 runFirmwareImage (0x2001E800)方法后崩溃。
    我做得对吗?
    您能给我一个成功案例吗?

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

    两个区域之间的间隔 bootloader 和 app 为1K。

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

    您好!

    正如我说过的、如果不调试实数代码、很难说出您会出什么问题。 我假设您的应用程序的链接器文件有问题。 您是否能够从 CCS 中执行 JTAG 从地址0x2001E800开始链接的应用程序? 您可以尝试使用以下链接器文件...

    引导加载程序链接器文件:

    #define RAM_BASE 0x20004000
    
    /* System memory map */
    
    MEMORY
    {
        /* Application uses internal RAM for program and data */
        SRAM_CODE (RWX) : origin = 0x20004000, length = 0x8000
        SRAM_DATA (RWX) : origin = 0x20000000, length = 0x4000
    }
    
    /* Section allocation in memory */
    
    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)
    }

    应用程序链接器文件、入口点为0x20020000:

    #define RAM_BASE 0x20020000
    
    /* System memory map */
    
    MEMORY
    {
        /* Application uses internal RAM for program and data */
        SRAM_DATA (RWX) : origin = 0x20000000, length = 0x20000  /* 128 KB */
        SRAM_CODE (RWX) : origin = 0x20020000, length = 0x20000  /* 128 KB */
    }
    
    /* Section allocation in memory */
    
    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月

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

    您好!

     您的回答非常好。

    谢谢。

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

    您好!

    当我使用默认参数 SRAM_base = 0X20004000时、生成的 bin 文件大小为127K。当我使用 SRAM_base = 0X2001E800 (offset 106K)时、生成的 bin 文件为233K、生成的 bin 文件包括偏移大小。 为什么这样?在我在另一个项目中偏移 SRAM_base 后、生成的 bin 文件的大小不会改变。

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

    您好!

    我无法回答您的问题。 生成的二进制文件的大小也取决于您的链接器文件和应用程序。 如果不使用真实代码、很难说出您的案例中发生的情况。 以下 是 TI 链接器文件的说明。

    1月