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.

TMS320F280033: 对于具备二次Bootloader的项目,如何将库文件分配到指定扇区

Part Number: TMS320F280033
Other Parts Discussed in Thread: SFRA

现在开发的280033项目Flash分配如下图:

Bank0

Sector 15

App1

24K * 16 bit

48KBytes

Bank1

Sector 7

App2

24K * 16 bit

48KBytes

Sector 14

Sector 6

Sector 13

Sector 5

Sector 12

Sector 4

Sector 11

Sector 3

Sector 10

Sector 2

Sector 9

Boot,16KBytes

Sector 1

Algorithm Library

算法库

Sector 8

Sector 0

程序上电时从Boot区运行,若App2区域内存在有效代码,则擦除App1区域并将App2区域代码复制到App1区域,然后擦除App2区域,跳转到App1运行。

程序(boot或App1)运行时,若遇到升级Boot程序命令则直接升级Boot区,若遇到升级App程序命令则,将收到的程序代码写入App2区域后重启。

现在有如下需求:

将App用到的Ti提供的一些库文件(包括但不限于FlashAPI,SFRA、DCL)固定存放到算法库区域(Bank1:Sector0~Bank1~Sector2),

一方面boot和app共用的FlashAPI代码只需要在FLASH中存储一份,可缩减代码空间

另一方面,可以节省App1和App2的占用空间,尽量为app逻辑代码提供空间

现在包括2个程序:Boot程序,App程序,

请问,对于上表提到的算法库,是否可以新建一个CCS工程,仅提供算法区(Bank1:Sector0~Bank1~Sector2)相关库文件的加载功能?

如果不行,有没有好的建议能帮忙解决上述的需求呢?

  • Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    MEMORY
    {
    BEGIN : origin = 0x00080000, length = 0x00000002
    BOOT_RSVD : origin = 0x00000002, length = 0x00000126
    RAMM0 : origin = 0x00000128, length = 0x000002D8
    RAMM1 : origin = 0x00000400, length = 0x000003F8
    // RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    // RAMLS0 : origin = 0x00008000, length = 0x00000800
    // RAMLS1 : origin = 0x00008800, length = 0x00000800
    // RAMLS2 : origin = 0x00009000, length = 0x00000800
    // RAMLS3 : origin = 0x00009800, length = 0x00000800
    // RAMLS4 : origin = 0x0000A000, length = 0x00000800
    // RAMLS5 : origin = 0x0000A800, length = 0x00000800
    // RAMLS6 : origin = 0x0000B000, length = 0x00000800
    // RAMLS7 : origin = 0x0000B800, length = 0x00000800
    // RAMGS0 : origin = 0x0000C000, length = 0x00001000
    // RAMGS1 : origin = 0x0000D000, length = 0x00001000
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    当前Boot程序项目利用上面的CMD文件,可以将FAPI_F28003x_EABI_v1.58.10.lib放在指定位置,内存分配如下图所示:

    现在有2个问题:

    第一、如果尝试将rts2800_fpu32_eabi.lib也放入APP_ALGORITHM区域,编译不通过,有如下错误及警告:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    warning #10278-D: LOAD placement specified for section ".text:decompress:none:rts2800_fpu32_eabi.lib<copy_decompress_none.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    warning #10278-D: LOAD placement specified for section ".text:rts2800_fpu32_eabi.lib<memcpy.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    warning #10278-D: LOAD placement specified for section "__TI___TI_zero_init_specialization:rts2800_fpu32_eabi.lib<copy_zero_init.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    warning #10278-D: LOAD placement specified for section ".text:decompress:ZI:__TI_zero_init_nomemset:rts2800_fpu32_eabi.lib<copy_zero_init.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    warning #10278-D: LOAD placement specified for section ".text:decompress:ZI:rts2800_fpu32_eabi.lib<copy_zero_init.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    warning #10278-D: LOAD placement specified for section ".text:rts2800_fpu32_eabi.lib<memset.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    warning #10278-D: LOAD placement specified for section ".text:decompress:lzss:rts2800_fpu32_eabi.lib<copy_decompress_lzss.c.obj>". This section contains decompression routines required for linker generated copy tables and C/C++ auto-initialization. Must ensure that this section is copied to run address before the C/C++ boot code is executed or is placed with single allocation specifier (ex. "> MEMORY").
    undefined first referenced
    symbol in file
    --------- ----------------
    __TI_SYSMEM_SIZE C:/ti/ccs1110/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/lib/rts2800_fpu32_eabi.lib<memory.c.obj>
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    请问如何处理?

    第二、Boot项目已经将FAPI_F28003x_EABI_v1.58.10.lib放在指定扇区,App项目中如何调用此扇区中的函数呢?似乎需要另外的包含函数地址的lib文件才可以。但是如何生成这个symbols_lib文件呢?

  • 我咨询相关工程师后回复你

  • 好的。

    之前用28002x的时候,因为Flash API已经嵌入在Boot ROM中,所以大大节省了代码占用Flash空间。

    但是现在28003x,只提供软件Flash API,所以不得不考虑压缩代码尺寸了。

  • 阅读文档 ZHCABQ0后受到启发,待我这边测试后有结果了再来更新。

  • 当前的情况:

    1.可以将Boot项目已经将FAPI_F28003x_EABI_v1.58.10.lib放在指定扇区

    2.根据文档 ZHCABQ0 和  ZHCABP6,可以生成SymbolLibrary.lib(仅包含函数名及其地址)

    3.可以在App项目中引用SymbolLibrary.lib,并调用调用函数

    现在的问题是,不能将lib中的函数Copy到RAM运行

    在App项目中使用CODE_SECTION指定Flash_API位置,在CMD中指定对应Section,在main中memcpy拷贝代码,结果发现调用的函数仍然运行于Flash中。

    以下示例完全参考ZHCABP6 文档,基于F28002x:

    其中F28002x_Project1定义函数test,存放位置如下(位于文件CPU1_RAM\F28002x_Project1_linkInfo.xml)

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <logical_group id="lg-10" display="no" color="cyan">
    <name>Project1_Function</name>
    <load_address>0x8e0f8</load_address>
    <run_address>0x8e0f8</run_address>
    <size>0x8</size>
    <contents>
    <object_component_ref idref="oc-d8"/>
    </contents>
    </logical_group>
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    利用Strawberry和cgxml工具生成的F28002x_Project1_out_test_tmp.asm文件内容如下:

    asm文件仅定义了函数名及其位置

    Fullscreen
    1
    2
    3
    4
    5
    ; This file is *auto-generated*. Do not edit. Mods risk being overwritten
    ; Assembly file : F28002x_Project1_out_test_tmp.asm
    .global test
    test .set 0x8e0f8
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    F28002x_Project2项目调用test函数,可以正常运行。

    尝试将test函数copy到RAM运行一直不成功。

    以下是一种尝试:

    CMD文件:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .TI.apifunc : LOAD = FLASH_BANK0_SEC1415,
    RUN = RAMLS7,
    LOAD_START(ApifuncsLoadStart),
    LOAD_SIZE(ApifuncsLoadSize),
    LOAD_END(ApifuncsLoadEnd),
    RUN_START(ApifuncsRunStart),
    RUN_SIZE(ApifuncsRunSize),
    RUN_END(ApifuncsRunEnd),
    ALIGN(8)
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    main.c文件

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "driverlib.h"
    #include "device.h"
    #include "test.h"
    extern uint16_t ApifuncsLoadStart;
    extern uint16_t ApifuncsLoadEnd;
    extern uint16_t ApifuncsRunStart;
    void MemCopy(uint16_t *SourceAddr, uint16_t* SourceEndAddr, uint16_t* DestAddr);
    #pragma CODE_SECTION(test, ".TI.apifunc");
    int R_Test1,R_Test2,R_Test3;
    void main(void)
    {
    // ApifuncsLoadStart = (uint16_t*)0x0008E002;
    // ApifuncsLoadEnd = (uint16_t*)0x0008E100;
    // ApifuncsRunStart = (uint16_t*)0x0000B800;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Debug的时候,MemCopy的参数都指向RAM区

    调用test函数时,PC仍位于Flash中:

    请问怎样配置CMD文件才能将test函数拷贝到RAM运行?

  • 好的感谢分享!我也和相关的工程师跟进一下

  • 根据这篇帖子的说法,不能将ROM中的Flash API代码拷贝到RAM运行

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/402181/copy-flash-api-from-rom-to-ram

    但是这很令人费解

    BOOT ROM中的SCI Boot等代码也会擦写FLASH,请问ROM中的这些代码擦写FLASH的时候也会将FLASH API拷贝到RAM中运行吗?

    再者,我之前F280025项目的bootloader项目中使用F28002xCPU1_BootROM_Symbols.lib库来调用ROM中的Flash API,也能对Flash进行擦写编程,只是在线debug的时候会出现异常。

    这里重新读了FLASH_API使用手册:

    里边提到,只要在执行FLASH擦除/编程的过程中只要不对这块(Bank)正在擦除/编程的FALSH进行读数/取指操作,就不会有问题。只要满足这个条件,即便在擦除/编程的过程中,遇到中断也没关系。

    具体可参考

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1206817/tms320f280049-flash-api-user-application-from-ram

  • 刚刚查看了BoootRom中SCI_Boot代码

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //
    // SCI_Boot - This module is the main SCI boot routine.
    // It will load code via the SCI-A port.
    //
    // It will return a entry point address back
    // to the system initialization routine which in turn calls
    // the ExitBoot routine.
    //
    uint32_t SCI_Boot(uint32_t bootMode)
    {
    uint32_t entryAddress;
    uint16_t byteData;
    //
    // CPU1 Patch/Escape Point 13
    //
    entryAddress = CPU1BROM_TI_OTP_ESCAPE_POINT_13;
    if((entryAddress != 0xFFFFFFFFUL) &&
    (entryAddress != 0x00000000UL))
    {
    //
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    CopyData函数代码

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    uint16fptr GetWordData; // GetWordData is a pointer to the function that
    // interfaces to the peripheral. Each loader assigns
    // this pointer to it's particular GetWordData function.
    //
    // CopyData - This routine copies multiple blocks of data from the host
    // to the specified RAM locations. There is no error
    // checking on any of the destination addresses.
    // That is because it is assumed all addresses and block size
    // values are correct.
    //
    // Multiple blocks of data are copied until a block
    // size of 00 00 is encountered.
    //
    void CopyData(void)
    {
    struct HEADER {
    uint32_t DestAddr;
    uint16_t BlockSize;
    } BlockHeader;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    可以看到,CopyData中并没有调用FLASH API,而是直接往指针处地址写值:

    Fullscreen
    1
    *(uint16_t *)BlockHeader.DestAddr = wordData;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    也没有看到任何地方擦除Flash的代码

    CopyData函数顶端的注释说,此函数将接收的数据块拷贝到RAM中,而实际上通过SCI_Boot下载程序时,上位机发送下来的地址都是位于FLASH空间,而不是RAM空间。

    bootrom中可以直接这样写FLASH吗?

  • bootrom版的FLASH API是直接操作FLASH的,无需搬运到RAM中。

    对于有bootrom FLASH API的器件,bootrom FLASH API 与 在代码中调用、执行时搬运到RAM的RAM版FLASH API lib之间是有取舍的,

    bootrom版:不占用代码空间,但是运行速度慢;

    RAM版:占用代码空间,但是搬运到RAM中执行速度快;并且只能搬运到RAM中运行;代码在执行时,不能对同一bank的其它sector进行操作。

  • 非常感谢。

    关于在Project2中调用Project1中放置于指定位置的函数,不能运行于RAM的问题

    目前临时的解决办法如下:

    以Project1和Project2为例

    在Project1中,将test放置在指定FLASH位置,并装载到指定RAM中运行

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    MEMORY
    {
    BEGIN : origin = 0x08D000, length = 0x000002
    BOOT_RSVD : origin = 0x00000002, length = 0x00000126
    RAMM0 : origin = 0x00000128, length = 0x000002D8
    RAMM1 : origin = 0x00000400, length = 0x000003F8 /* on-chip RAM block M1 */
    RAMLS7 : origin = 0x0000B800, length = 0x00000800
    RAMGS0 : origin = 0x0000C000, length = 0x000007F8
    BOOTROM : origin = 0x003F0000, length = 0x00008000
    BOOTROM_EXT : origin = 0x003F8000, length = 0x00007FC0
    RESET : origin = 0x003FFFC0, length = 0x00000002
    FLASH_BANK0_SEC13 : origin = 0x08D002, length = 0x000FFE /* on-chip Flash */
    FLASH_BANK0_SEC1415 : origin = 0x08E000, length = 0x002000 /* on-chip Flash */
    }
    SECTIONS
    {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    其中table(BINIT)可以省去在main中调用memcpy的代码。

    Project1的linkinfo.xml中,test的地址(load和run)以及尺寸如下

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    <object_component id="oc-d9">
    <name>.text:test</name>
    <load_address>0x8e000</load_address>
    <run_address>0xc000</run_address>
    <size>0x8</size>
    <input_file_ref idref="fl-6"/>
    </object_component>
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    生成仅包含函数名和地址的F28002x_FlashAPI_SymbolLibrary.lib,该lib文件中仅包含1个test.obj

    其中 F28002x_Project1_out_test_tmp.asm 文件内容如下:

    从上图可知,F28002x_FlashAPI_SymbolLibrary.lib文件中将test函数定位到0xc000,即RAMGS0所在的RAM区域

    F28002x_FlashAPI_SymbolLibrary.lib文件加入Project2中。

    在Project2中,手动指定memcpy的地址和范围,将

    0x08E000(FLASH_BANK0_SEC1415)的代码拷贝到0x0000C000(RAMGS0)的位置。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "driverlib.h"
    #include "device.h"
    #include "test.h"
    uint16_t* ApifuncsLoadStart;
    uint16_t* ApifuncsLoadEnd;
    uint16_t* ApifuncsRunStart;
    void MemCopy(uint16_t *SourceAddr, uint16_t* SourceEndAddr, uint16_t* DestAddr);
    #pragma CODE_SECTION(test, ".TI.apifunc");
    int R_Test1,R_Test2,R_Test3;
    void main(void)
    {
    ApifuncsLoadStart = (uint16_t*)0x0008E000;
    ApifuncsLoadEnd = (uint16_t*)0x0008E100;
    ApifuncsRunStart = (uint16_t*)0x0000C000;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    以上可以实现Project2项目在RAM中运行Project1项目共享的函数test。

    但是这个过程过于繁琐,期望能有更好的实现方案

  • 好的,我需要一些时间来看一下