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.
您好!
我目前正在尝试将 C2000器件中闪存存储体的一个未使用扇区用于 EEPROM 仿真。 在研究这一点时、我收到了一个文档(SPRAB69A)、其中概述了对较旧的第2代器件的类似实现。
我打算使用最新的闪存 API 来修改该框架。 但是、在应用程序中运行此代码时遇到了持久的问题。 我一直收到错误消息"无法在此地址找到源文件。"
此外、当我尝试在代码中包含"Fapi_setActiveFlashBank"函数时、我遇到另一个错误:"#10099-D 程序将无法装入可用内存中、或者该段包含一个需要 trampoline 但无法为此段生成的调用站点。 对"Group_1"大小为0x933的段0进行对齐/分块运行放置失败。 可用内存范围:"
我附上了我的代码供您参考。
感谢您的帮助。
链接器代码:
MEMORY { PAGE 0 : RAMM0 : origin = 0x0000F5, length = 0x00030B RAMLS0 : origin = 0x008000, length = 0x000800 RAMLS1 : origin = 0x008800, length = 0x000800 RAMLS2 : origin = 0x009000, length = 0x000800 RAMLS3 : origin = 0x009800, length = 0x000800 RAMLS4 : origin = 0x00A000, length = 0x000800 RESET : origin = 0x3FFFC0, length = 0x000002 #ifdef __TI_COMPILER_VERSION__ #if __TI_COMPILER_VERSION__ >= 20012000 GROUP { /* GROUP memory ranges for crc/checksum of entire flash */ #endif #endif /* BEGIN is used for the "boot to Flash" bootloader mode */ BEGIN : origin = 0x080000, length = 0x000002 /* Flash sectors */ /* BANK 0 */ FLASH_BANK0_SEC0 : origin = 0x080002, length = 0x000FFE /* on-chip Flash */ FLASH_BANK0_SEC1 : origin = 0x081000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC3 : origin = 0x083000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC4 : origin = 0x084000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC5 : origin = 0x085000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC7 : origin = 0x087000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC8 : origin = 0x088000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC9 : origin = 0x089000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000 /* on-chip Flash */ FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000 /* on-chip Flash */ /* BANK 1 */ FLASH_BANK1_SEC0 : origin = 0x090000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC1 : origin = 0x091000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC2 : origin = 0x092000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC3 : origin = 0x093000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC4 : origin = 0x094000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC5 : origin = 0x095000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC6 : origin = 0x096000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC7 : origin = 0x097000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC8 : origin = 0x098000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC9 : origin = 0x099000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC10 : origin = 0x09A000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC11 : origin = 0x09B000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC12 : origin = 0x09C000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC13 : origin = 0x09D000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC14 : origin = 0x09E000, length = 0x001000 /* on-chip Flash */ FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x000FF0 /* on-chip Flash */ FLASH_BANK1_SEC15_DO_NOT_USE : origin = 0x09FFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ #ifdef __TI_COMPILER_VERSION__ #if __TI_COMPILER_VERSION__ >= 20012000 } crc(_ccs_flash_checksum, algorithm=C28_CHECKSUM_16) #endif #endif PAGE 1 : BOOT_RSVD : origin = 0x000002, length = 0x0000F3 /* Part of M0, BOOT rom will use this for stack */ RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */ RAMLS5 : origin = 0x00A800, length = 0x000800 RAMLS6 : origin = 0x00B000, length = 0x000800 RAMLS7 : origin = 0x00B800, length = 0x000800 RAMGS0 : origin = 0x00C000, length = 0x002000 RAMGS1 : origin = 0x00E000, length = 0x002000 RAMGS2 : origin = 0x010000, length = 0x002000 RAMGS3 : origin = 0x012000, length = 0x002000 } SECTIONS { codestart : > BEGIN, PAGE = 0, ALIGN(4) .text : >>FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3, PAGE = 0, ALIGN(4) .cinit : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4) .pinit : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4) .switch : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4) .reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */ .stack : > RAMM1, PAGE = 1 .ebss : > RAMLS5, PAGE = 1 .esysmem : > RAMLS5, PAGE = 1 .econst : > FLASH_BANK0_SEC4, PAGE = 0, ALIGN(4) ramgs0 : > RAMGS0, PAGE = 1 ramgs1 : > RAMGS1, PAGE = 1 GROUP { .TI.ramfunc { -l F021_API_F28004x_FPU32.lib} } LOAD = FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC13, RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3, LOAD_START(_RamfuncsLoadStart), LOAD_SIZE(_RamfuncsLoadSize), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), RUN_SIZE(_RamfuncsRunSize), RUN_END(_RamfuncsRunEnd), PAGE = 0, ALIGN(4) /* crc/checksum section configured as COPY section to avoid including in executable */ .TI.memcrc : type = COPY } /* //=========================================================================== // End of file. //=========================================================================== */
头文件:
//############################################################################ // // FILE: F280xx_EEPROM.h // // TITLE: Function Prototypes, Global Variables, Pointer Initialization // and, Bank/Page Status Definitions // //############################################################################ // Authors: Tim Love / Pradeep Shinde // Release Date: Sep 2009 //############################################################################ #include <F021_F28004x_C28x.h> // Project specific defines //#define SINGLE_BYTE 1 #define MULTI_BYTE 1 //Just for flash #define FLASH_SECTOR 0x090000 #define RESET_BANK_POINTER Bank_Pointer = (uint16 *)FLASH_SECTOR // Sector H #define RESET_PAGE_POINTER Page_Pointer = (uint16 *)(FLASH_SECTOR+1) #define END_OF_SECTOR 0x8FFFF; //Only for ECC #define ECC_BANK_BUFFER (uint16*)0x0 #define ECC_PAGE_BUFFER (uint16*)0x0 //#endif // Bank/Page Status Definitions #define EMPTY_BANK 0xFFFF #define CURRENT_BANK 0xA00A #define USED_BANK 0x0000 #define BLANK_PAGE 0xFFFF #define CURRENT_PAGE 0x00FF #define USED_PAGE 0x0000 // Function Prototypes extern void EEPROM_GetValidBank(); extern void EEPROM_Erase(); extern void EEPROM_Read(); extern void EEPROM_Write(); extern void EEPROM_UpdateBankStatus(); extern void EEPROM_UpdatePageStatus(); extern void EEPROM_GetSinglePointer(uint16 First_Call); extern void EEPROM_ProgramSingleByte(uint16 data); // Global Variables extern uint16 *Bank_Pointer; extern uint16 *Page_Pointer; extern uint16 *Sector_End; extern uint16 Read_Buffer[64]; extern uint16 Write_Buffer[64];
源文件:
//############################################################################ // // FILE: F280xx_EEPROM.c // // TITLE: EEPROM Read, Write, and Erase Functions // //############################################################################ // Authors: Tim Love / Pradeep Shinde // Release Date: Sep 2009 //############################################################################ #include "F280xx_EEPROM.h" // EEPROM Include File // Global Variables uint16 Read_Buffer[64]; uint16 Write_Buffer[64]; uint16 Bank_Counter = 0; uint16 Page_Counter = 0; uint16 Bank_Status[1] = {0}; uint16 Page_Status[1] = {0}; uint16 *Bank_Pointer; uint16 *Page_Pointer; uint16 *Sector_End; //Fapi_FlashStatusType FlashStatus; Fapi_FlashStatusType ProgStatus; // All Flash API functions need to be ran from internal RAM. Place all functions // that contain Flash API calls in .TI.ramfunc to allow copy from Flash to RAM. #pragma CODE_SECTION(EEPROM_Erase,".TI.ramfunc"); #pragma CODE_SECTION(EEPROM_Write,".TI.ramfunc"); #pragma CODE_SECTION(EEPROM_UpdateBankStatus,".TI.ramfunc"); #pragma CODE_SECTION(EEPROM_UpdatePageStatus,".TI.ramfunc"); #pragma CODE_SECTION(EEPROM_ProgramSingleByte,".TI.ramfunc"); //######################### EEPROM_GET_VALID_BANK ############################ void EEPROM_GetValidBank() { //Each page holds 64 data words //Page size = Page_status word + 64W = 65W //Bank Size = Bank_status word + 8 * Page size = 1 + 8*65 = 521W uint16 i; RESET_BANK_POINTER; // Reset Bank Pointer to enable search for current Bank RESET_PAGE_POINTER; // Reset Page Pointer to enable search for current Page // Find Current Bank for(i=0;i<8;i++) { Bank_Status[0] = *(Bank_Pointer); // Read contents of Bank Pointer if(Bank_Status[0] == EMPTY_BANK) // Check for Unused Bank { Bank_Counter = i; // Set Bank Counter to number of current page return; // If Bank is Unused, return as EEPROM is empty } if(Bank_Status[0] == CURRENT_BANK) // Check for In Use Bank { Bank_Counter = i; // Set Bank Counter to number of current bank Page_Pointer = Bank_Pointer + 1; // Set Page Pointer to first page in current bank break; // Break from loop as current bank has been found } if(Bank_Status[0] == USED_BANK) // Check for Used Bank Bank_Pointer += 521; // If Bank has been used, set pointer to next bank } // Find Current Page for(i=0;i<8;i++) { Page_Status[0] = *(Page_Pointer); // Read contents of Page Pointer // Check for Blank Page or Current Page if(Page_Status[0] == BLANK_PAGE || Page_Status[0] == CURRENT_PAGE) { Page_Counter = i; // Set Page Counter to number of current page break; // Break from loop as current page has been found } if(Page_Status[0] == USED_PAGE) // Check for Used Page Page_Pointer += 65; // If page has been used, set pointer to next page } if (Bank_Counter==7 && Page_Counter==7) // Check for full EEPROM { EEPROM_Erase(); // Erase flash sector being used as EEPROM RESET_BANK_POINTER; // Reset Bank Pointer as EEPROM is empty RESET_PAGE_POINTER; // Reset Pank Pointer as EEPROM is empty asm(" ESTOP0"); } } //######################### EEPROM_GET_VALID_BANK ############################ //############################# EEPROM_ERASE ################################# void EEPROM_Erase() { Fapi_StatusType Status; Status = Fapi_issueAsyncCommandWithAddress((Fapi_EraseSector),(uint32 *)FLASH_SECTOR); while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){} if(Status != Fapi_Status_Success) // If Erase fails halt program or handle error { asm(" ESTOP0"); } } //############################# EEPROM_ERASE ################################# //############################# EEPROM_READ ################################## void EEPROM_Read() { uint16 i; EEPROM_GetValidBank(); // Find In Use Bank and Current Page // Transfer contents of Current Page to Read Buffer for(i=0;i<64;i++) Read_Buffer[i] = *(++Page_Pointer); } //############################# EEPROM_READ ################################## //############################ EEPROM_WRITE ################################## void EEPROM_Write() { // Variables need for Flash API Functions Fapi_StatusType Status; uint32 Length; // Fapi_FlashStatusType ProgStatus; //Fapi_setActiveFlashBank(Fapi_FlashBank0); EEPROM_GetValidBank(); // Find In Use Bank and Current Page EEPROM_UpdatePageStatus(); // Update Page Status of previous page EEPROM_UpdateBankStatus(); // Updage Bank Status of current and previous bank // Program data located in Write_Buffer to current page Length = 64; // Set Length for programming Status = Fapi_issueProgrammingCommand((uint32 *)(Page_Pointer+1),Write_Buffer,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly); // Modify Page Status from Blank Page to Current Page if flash programming was successful if (Status == Fapi_Status_Success) { Page_Status[0] = CURRENT_PAGE; // Set Page Status to Current Page Length = 1; // Set Length for programming status Status = Fapi_issueProgrammingCommand((uint32 *)Page_Pointer,Page_Status,Length,ECC_PAGE_BUFFER,Length, Fapi_DataOnly); } } //############################ EEPROM_WRITE ################################## //###################### EEPROM_UPDATE_BANK_STATUS ########################### void EEPROM_UpdateBankStatus() { // Variables needed for Flash API Functions uint32 Length; Length = 1; // Set Length for programming Bank_Status[0] = *(Bank_Pointer); // Read Bank Status from Bank Pointer Page_Status[0] = *(Page_Pointer); // Read Page Status from Page Pointer // Program Bank Status for Empty EEPROM if (Bank_Status[0] == EMPTY_BANK) { Bank_Status[0] = CURRENT_BANK; // Set Bank Status to In Use Bank // Program Bank Status to current bank Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer,Bank_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly); Page_Counter =0; Page_Pointer = Bank_Pointer + 1; // Set Page Pointer to first page of current bank } // Program Bank Status of full bank and following bank if (Bank_Status[0] == CURRENT_BANK && Page_Counter == 7) { Bank_Status[0] = USED_BANK; // Set Bank Status to Used Bank // Program Bank Status to full bank Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer,Bank_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly); Bank_Pointer +=521; // Increment Bank Pointer to next bank Bank_Status[0] = CURRENT_BANK; // Set Bank Status to In Use Bank // Program Bank Status to current bank Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer,Bank_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly); Page_Counter = 0; Page_Pointer = Bank_Pointer +1; // Set Page Pointer to first page of current bank } } //###################### EEPROM_UPDATE_BANK_STATUS ########################### //###################### EEPROM_UPDATE_PAGE_STATUS ########################### void EEPROM_UpdatePageStatus() { // Variables needed for Flash API Functions uint16 Length; Bank_Status[0] = *(Bank_Pointer); // Read Bank Status from Bank Pointer Page_Status[0] = *(Page_Pointer); // Read Page Status from Page Pointer // Check if Page Status is blank. If so return to EEPROM_WRITE. if(Page_Status[0] == BLANK_PAGE) return; // Program previous page's status to Used Page else { Page_Status[0] = USED_PAGE; // Set Page Status to Used Page Length = 1; // Set Length for programming Fapi_issueProgrammingCommand((uint32 *)Page_Pointer,Page_Status,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly); Page_Pointer +=65; // Increment Page Pointer to next page } } //###################### EEPROM_UPDATE_PAGE_STATUS ########################### //###################### EEPROM_GET_SINGLE_POINTER ########################### void EEPROM_GetSinglePointer(uint16 First_Call) { uint16 *End_Address; End_Address = (uint16 *)END_OF_SECTOR; // Set End_Address for sector if(First_Call == 1) // If this is first call to function, find valid pointer { RESET_BANK_POINTER; // Reset Bank Pointer to beginning of sector while(*(Bank_Pointer) != 0xFFFF) // Test each location for data Bank_Pointer++; // Increment to next location } if(Bank_Pointer >= End_Address) // Test if sector is full { EEPROM_Erase(); // Erase flash sector being used as EEPROM RESET_BANK_POINTER; // Reset Bank Pointer as EEPROM is empty asm(" ESTOP0"); } } //###################### EEPROM_GET_SINGLE_POINTER ########################### //##################### EEPROM_PROGRAM_SINGLE_BYTE ########################### void EEPROM_ProgramSingleByte(uint16 data) { // Variables needed for Flash API Functions uint32 Length; Write_Buffer[0] = data; // Prepare data to be programmed Length = 1; // Set Length for programming Fapi_issueProgrammingCommand((uint32 *)Bank_Pointer++,Write_Buffer,Length,ECC_BANK_BUFFER,Length, Fapi_DataOnly); EEPROM_GetSinglePointer(0); // Test for full sector } //##################### EEPROM_PROGRAM_SINGLE_BYTE ###########################
您好!
每当您进入闪存 API 库函数时、CCS 都会向您显示 "无法在此地址找到源文件"。 消息、因为闪存 API 源不可供其显示-这不是问题。 您可以忽略此警告。
关于链接器错误: 只是说、为该输出段分配的存储器是不够的。 尝试合并几个存储器范围(以便适合该段)并将该段映射到新的大存储器范围。
另请注意、我们计划在即将发布的 C2000Ware 版本中发布 EEPROM 示例(针对 F28P65x 器件-但您应该能够针对 F28004x 轻松对其进行编辑)。
谢谢。此致、
瓦姆西
尊敬的 Vamsi:
以下是我立即尝试运行代码时收到的提示消息:C:/Users\...\Debug\project.out:{3}0x3fbd92{4}中没有"_system_post_cinit ()"的源可用
0x3fbd92{4}地址恰好位于引导 ROM 中。
此外、该代码会在没有 "Fapi_setActiveFlashBank"函数的情况下构建、但在图片中、它将生成所描述的错误消息。
谢谢。此致、
阿洛巴。
您好!
有关引导 ROM 中登录执行错误的说明:如 TRM 的表 4-15所示。 等待点地址、地址0x3fbd92属于 ITRAP ISR。
这意味着 CPU 执行了一个非法指令。 在调用映射到.TI.ramfunc 段的任何函数之前、请检查是否执行了 memcpy ()。
对于链接器错误、请遵循我之前提供的建议。
谢谢。此致、
瓦姆西
尊敬的 Vamsi:
感谢您的答复。 我已经尝试实施您的建议来解决链接器错误、但遗憾的是、仍然存在。
关于`memcpy ()`函数,它不会在我的代码中的任何点执行,因为我不确定源或目的。
请看一下我共享的命令文件吗? 您的建议将会非常有帮助。
谢谢、此致、
阿洛巴
Atoba,
请查看此常见问题解答一次:
如何将应用程序从 RAM 配置修改为闪存配置?: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/878674
此外、您可以看看任何 C2000Ware 示例-它们应该具有闪存构建配置(如上面的常见问题解答中所述)。 您可以单步执行并了解常见问题解答中介绍的过程。
谢谢。此致、
瓦姆西
至于链接器命令文件:您能展示您在链接器命令文件中所做的操作(您说的此操作无助于消除错误)吗?
谢谢。此致、
瓦姆西
尊敬的 Vamsi:
以下是我对链接器命令文件所做的修改:
从这里:
GROUP { .TI.ramfunc { -l F021_API_F28004x_FPU32.lib} } LOAD = FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC13, RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
为此、请执行以下操作:
GROUP { .TI.ramfunc { -l F021_API_F28004x_FPU32.lib} } LOAD = FLASH_BANK0_SEC7 | FLASH_BANK0_SEC8 | FLASH_BANK0_SEC9 | FLASH_BANK0_SEC10 | FLASH_BANK0_SEC13, RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
谢谢。
阿洛巴。
您好!
您可以将几个存储器合并到一个存储器范围中并尝试、而不是使用存储器?
示例:
从这里:
FLASH_A:origin = 0x90000、length = 0x1000
FLASH_B:origin = 0xA0000、length = 0x1000
为此、请执行以下操作:
FLASH_AB:origin = 0x90000、length = 0x2000
并使用合并的存储器范围。
请告诉我们这是否有帮助。
谢谢。此致、
瓦姆西
您好!
由于我没有收到您的回复、因此我将关闭此帖子、前提是我的最后一次回复帮助您解决了此问题。
如果您仍有其他问题、可以根据需要打开新帖子。
谢谢。此致、
瓦姆西