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.
现在开发的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)相关库文件的加载功能?
如果不行,有没有好的建议能帮忙解决上述的需求呢?
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 // RAMGS2 : origin = 0x0000E000, length = 0x00001000 // RAMGS3 : origin = 0x0000F000, length = 0x00000FF8 // // RAMGS3_RSVD : origin = 0x0000FFF8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ RAML_Data : origin = 0x00008000, length = 0x00002000 RAML_Prog : origin = 0x0000A000, length = 0x00002000 RAMG_All : origin = 0x0000C000, length = 0x00003FF8 BOOTROM : origin = 0x003F8000, length = 0x00007FC0 SECURE_ROM : origin = 0x003F2000, length = 0x00006000 RESET : origin = 0x003FFFC0, length = 0x00000002 /* Flash sectors */ /* BANK 0 */ BEGIN_BOOT : origin = 0x088000, length = 0x000008 ,fill = 0xFFFF/* codestart */ BOOT_STARTFLAG : origin = 0x088008, length = 0x000010 ,fill = 0xFFFF/* bootloader flag */ BOOT_VERSION : origin = 0x088018, length = 0x000008 ,fill = 0xFFFF/* bootloader version*/ BOOT_FLASH : origin = 0x088020, length = 0x001FD0 ,fill = 0xFFFF/* bootloader code */ BOOT_DATETIME : origin = 0x089FF0, length = 0x000008 ,fill = 0xFFFF/* bootloader compile datetime */ BOOT_FINISHFLAG : origin = 0x089FF8, length = 0x000008 ,fill = 0xFFFF/* bootloader finish flag */ APP1_BEGIN : origin = 0x08A000, length = 0x000008 //,fill = 0xFFFF/* codestart */ APP1_STARTFLAG : origin = 0x08A008, length = 0x000010 //,fill = 0xFFFF/* app1 flag */ APP1_VERSION : origin = 0x08A018, length = 0x000008 //,fill = 0xFFFF/* app1 version*/ APP1_FLASH : origin = 0x08A020, length = 0x005FD0 //,fill = 0xFFFF/* app1 code */ APP1_DATETIME : origin = 0x08FFF0, length = 0x000008 //,fill = 0xFFFF/* app1 compile datetime */ APP1_FINISHFLAG : origin = 0x08FFF8, length = 0x000008 //,fill = 0xFFFF/* app1 finish flag */ /* BANK 1 */ APP_ALGORITHM : origin = 0x090000, length = 0x002000 //,fill = 0xFFFF/* share algorithm code */ APP2_BEGIN : origin = 0x092000, length = 0x000008 //,fill = 0xFFFF/* codestart */ APP2_STARTFLAG : origin = 0x092008, length = 0x000010 //,fill = 0xFFFF/* app2 flag */ APP2_VERSION : origin = 0x092018, length = 0x000008 //,fill = 0xFFFF/* app2 version*/ APP2_FLASH : origin = 0x092020, length = 0x005FD0 //,fill = 0xFFFF/* app2 code */ APP2_DATETIME : origin = 0x097FF0, length = 0x000008 //,fill = 0xFFFF/* app2 compile datetime */ APP2_FINISHFLAG : origin = 0x097FF8, length = 0x000008 //,fill = 0xFFFF/* app2 finish flag */ // FLASH_BANK0_SEC15_RSVD : origin = 0x0AFFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ } SECTIONS { codestart : > BEGIN_BOOT, ALIGN(8) .text : > BOOT_FLASH, ALIGN(8) .cinit : > BOOT_FLASH, ALIGN(8) .switch : > BOOT_FLASH, ALIGN(8) .reset : > RESET, TYPE = DSECT /* not used, */ .stack : > RAMM0 | RAMM1 .init_array : > BOOT_FLASH, ALIGN(8) .bss : > RAMG_All .bss:output : > RAMG_All .bss:cio : > RAMG_All .data : > RAMG_All .sysmem : > RAMG_All .const : > BOOT_FLASH, ALIGN(8) // /* Allocate IQ math areas: */ // IQmath : > FLASH_BANK0_SEC1, ALIGN(8) // IQmathTables : > FLASH_BANK0_SEC2, ALIGN(8) // flashApi :{ -l FAPI_F28003x.lib } > APP_ALGORITHM GROUP { .TI.ramfunc { // -l sfra_f64_tmu_eabi.lib } ramfuncs isrcodefuncs dclfuncs } LOAD = BOOT_FLASH, RUN = RAML_Prog, LOAD_START(RamfuncsLoadStart), LOAD_SIZE(RamfuncsLoadSize), LOAD_END(RamfuncsLoadEnd), RUN_START(RamfuncsRunStart), RUN_SIZE(RamfuncsRunSize), RUN_END(RamfuncsRunEnd), ALIGN(8) GROUP { algorithmfuncs { // -l sfra_f64_tmu_eabi.lib -l FAPI_F28003x_EABI_v1.58.10.lib // -l rts2800_fpu32_eabi.lib } } LOAD = APP_ALGORITHM, RUN = RAML_Prog, LOAD_START(LibfuncsLoadStart), LOAD_SIZE(LibfuncsLoadSize), LOAD_END(LibfuncsLoadEnd), RUN_START(LibfuncsRunStart), RUN_SIZE(LibfuncsRunSize), RUN_END(LibfuncsRunEnd), ALIGN(8) // SFRA_F32_Data : > RAMG_All, ALIGN = 64 // SFRA_Data : > RAMG_All, ALIGN = 64 // FPUmathTables : > APP1_FLASH boot_startflag : > BOOT_STARTFLAG, ALIGN(8) boot_version : > BOOT_VERSION, ALIGN(8) boot_datetime : > BOOT_DATETIME, ALIGN(8) boot_finishflag : > BOOT_FINISHFLAG, ALIGN(8) app1_startflag : > APP1_STARTFLAG, ALIGN(8) app1_version : > APP1_VERSION, ALIGN(8) app1_datetime : > APP1_DATETIME, ALIGN(8) app1_finishflag : > APP1_FINISHFLAG, ALIGN(8) app2_startflag : > APP2_STARTFLAG, ALIGN(8) app2_version : > APP2_VERSION, ALIGN(8) app2_datetime : > APP2_DATETIME, ALIGN(8) app2_finishflag : > APP2_FINISHFLAG, ALIGN(8) } /* //=========================================================================== // End of file. //=========================================================================== */
当前Boot程序项目利用上面的CMD文件,可以将FAPI_F28003x_EABI_v1.58.10.lib放在指定位置,内存分配如下图所示:
现在有2个问题:
第一、如果尝试将rts2800_fpu32_eabi.lib也放入APP_ALGORITHM区域,编译不通过,有如下错误及警告:
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>
第二、Boot项目已经将FAPI_F28003x_EABI_v1.58.10.lib放在指定扇区,App项目中如何调用此扇区中的函数呢?似乎需要另外的包含函数地址的lib文件才可以。但是如何生成这个symbols_lib文件呢?
好的。
之前用28002x的时候,因为Flash API已经嵌入在Boot ROM中,所以大大节省了代码占用Flash空间。
但是现在28003x,只提供软件Flash API,所以不得不考虑压缩代码尺寸了。
当前的情况:
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)
<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>
利用Strawberry和cgxml工具生成的F28002x_Project1_out_test_tmp.asm文件内容如下:
asm文件仅定义了函数名及其位置
; 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
F28002x_Project2项目调用test函数,可以正常运行。
尝试将test函数copy到RAM运行一直不成功。
以下是一种尝试:
CMD文件:
.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)
main.c文件
#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; MemCopy(&ApifuncsLoadStart, &ApifuncsLoadEnd, &ApifuncsRunStart); R_Test1 = 123; R_Test2 = 456; for(;;) { R_Test3 = test(R_Test1,R_Test2); } } void MemCopy(uint16_t *SourceAddr, uint16_t* SourceEndAddr, uint16_t* DestAddr) { while(SourceAddr < SourceEndAddr) { *DestAddr++ = *SourceAddr++; } return; }
Debug的时候,MemCopy的参数都指向RAM区
调用test函数时,PC仍位于Flash中:
请问怎样配置CMD文件才能将test函数拷贝到RAM运行?
根据这篇帖子的说法,不能将ROM中的Flash API代码拷贝到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进行读数/取指操作,就不会有问题。只要满足这个条件,即便在擦除/编程的过程中,遇到中断也没关系。
具体可参考
刚刚查看了BoootRom中SCI_Boot代码
// // 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)) { // // If OTP is programmed, then call OTP patch function // ((void (*)(void))entryAddress)(); } // // Check if SCI is enabled on device or not // if(SysCtl_isPeripheralPresent(SYSCTL_PERIPH_PRESENT_SCIA) == false) { return(FLASH_ENTRY_POINT); } // // Assign GetWordData to the SCI-A version of the // function. GetWordData is a pointer to a function. // GetWordData = SCIA_GetWordData; // // Initialize the SCI-A port for communications // with the host. // // // Enable the SCI-A clocks // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA); SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4); EALLOW; HWREGH(SCIA_BASE + SCI_O_FFTX) = SCI_FFTX_SCIRST; // // 1 stop bit, No parity, 8-bit character // No loopback // HWREGH(SCIA_BASE + SCI_O_CCR) = (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE); SCI_setParityMode(SCIA_BASE,SCI_CONFIG_PAR_NONE); // // Enable TX, RX, Use internal SCICLK // HWREGH(SCIA_BASE + SCI_O_CTL1) = (SCI_CTL1_TXENA | SCI_CTL1_RXENA); // // Disable RxErr, Sleep, TX Wake, // Disable Rx Interrupt, Tx Interrupt // HWREGB(SCIA_BASE + SCI_O_CTL2) = 0x0U; // // Relinquish SCI-A from reset and enable TX/RX // SCI_enableModule(SCIA_BASE); EDIS; // // GPIO INIT // SCIBOOT_configure_gpio(bootMode); // // CPU1 Patch/Escape Point 13 // entryAddress = CPU1BROM_TI_OTP_ESCAPE_POINT_13; if((entryAddress != 0xFFFFFFFFUL) && (entryAddress != 0x00000000UL)) { // // If OTP is programmed, then call OTP patch function // ((void (*)(void))entryAddress)(); } // // Perform autobaud lock with the host. // Note that if autobaud never occurs // the program will hang in this routine as there // is no timeout mechanism included. // SCI_lockAutobaud(SCIA_BASE); // // Read data // byteData = SCI_readCharBlockingNonFIFO(SCIA_BASE); // // Configure TX pin after autobaud lock // (Performed here to allow SCI to double as wait boot) // GPIO_setPadConfig(SCI_gpioTx,GPIO_PIN_TYPE_PULLUP); GPIO_setPinConfig(SCI_gpioTxPinConfig); // // Write data to request key // SCI_writeCharNonBlocking(SCIA_BASE,byteData); // // If the KeyValue was invalid, abort the load // and return the flash entry point. // if(SCIA_GetWordData() != BROM_EIGHT_BIT_HEADER) { return FLASH_ENTRY_POINT; } ReadReservedFn(); entryAddress = GetLongData(); CopyData(); return entryAddress; }
CopyData函数代码
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; uint16_t wordData; uint16_t i; // // Get the size in words of the first block // BlockHeader.BlockSize = (*GetWordData)(); // // While the block size is > 0 copy the data // to the DestAddr. There is no error checking // as it is assumed the DestAddr is a valid // memory location // while(BlockHeader.BlockSize != (uint16_t)0x0000U) { BlockHeader.DestAddr = GetLongData(); for(i = 1; i <= BlockHeader.BlockSize; i++) { wordData = (*GetWordData)(); *(uint16_t *)BlockHeader.DestAddr = wordData; BlockHeader.DestAddr+=1U; } // // Get the size of the next block // BlockHeader.BlockSize = (*GetWordData)(); } return; }
可以看到,CopyData中并没有调用FLASH API,而是直接往指针处地址写值:
*(uint16_t *)BlockHeader.DestAddr = wordData;
也没有看到任何地方擦除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中运行
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 { codestart : > BEGIN, ALIGN(8) .text : > FLASH_BANK0_SEC13, ALIGN(8) .cinit : > FLASH_BANK0_SEC13, ALIGN(8) .switch : > FLASH_BANK0_SEC13, ALIGN(8) .reset : > RESET, TYPE = DSECT /* not used, */ .stack : > RAMM1 .init_array : > FLASH_BANK0_SEC13, ALIGN(8) .bss : > RAMLS7 .bss:output : > RAMLS7 .bss:cio : > RAMLS7 .const : > FLASH_BANK0_SEC13, ALIGN(8) .data : > RAMLS7 .sysmem : > RAMLS7 Project1_Function { -l test.obj(.text) } load = FLASH_BANK0_SEC1415, run = RAMGS0, table(BINIT), ALIGN(8) .binit : > FLASH_BANK0_SEC1415 }
其中table(BINIT)可以省去在main中调用memcpy的代码。
Project1的linkinfo.xml中,test的地址(load和run)以及尺寸如下
<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>
生成仅包含函数名和地址的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的地址和范围,将
#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; MemCopy(ApifuncsLoadStart, ApifuncsLoadEnd, ApifuncsRunStart); R_Test1 = 123; R_Test2 = 456; for(;;) { R_Test3 = test(R_Test1,R_Test2); } } void MemCopy(uint16_t *SourceAddr, uint16_t* SourceEndAddr, uint16_t* DestAddr) { while(SourceAddr < SourceEndAddr) { *DestAddr++ = *SourceAddr++; } return; }
以上可以实现Project2项目在RAM中运行Project1项目共享的函数test。
但是这个过程过于繁琐,期望能有更好的实现方案