Tool/software:
Hello,
I am using the TMS320F28377D micro and attempting to use the Fapi library to write some data to flash. The objective is to write some tunable software values to flash when the user commands a commit via CAN. I wrote a function to accomplish this and it works the first time the function is called, but on the second time the function is called, the CPU gets suspended and is possibly at ITRAP0. I have tried to follow the flash examples and Fapi guide the best that I could.
Below is the function for writing parameters which is called from within a timer interrupt and the current linker that I am using. StartOfParameters is defined as 0xB8000. Any suggestions are greatly appreciated.
__attribute__((ramfunc))
boolean writeParameters(struct parameters_t *parameters_p, uint32_t size)
{
#if defined(_2837xD)
Fapi_StatusType returnCheck;
Fapi_FlashStatusWordType oFlashStatusWord;
boolean success = 0;
uint16_t flashWriteIndex;
Flash_claimPumpSemaphore(FLASHPUMPSEMAPHORE_BASE, FLASH_CPU1_WRAPPER); //includes EALLOW and EDIS
EALLOW;
//initialize the flash API
returnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 200);
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
//checks if the initialization was successful
if (returnCheck == Fapi_Status_Success)
{
//set the active flash bank
returnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
//checks if the flash bank setting was successful
if (returnCheck == Fapi_Status_Success)
{
//erases the sector containing the parameters struct
returnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32_t*)startOfParameters);
//waits for the erase to finish
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
//checks if the erase was successful
if (returnCheck == Fapi_Status_Success)
{
//verify erase operation
returnCheck = Fapi_doBlankCheck((uint32_t *)startOfParameters, 0x1000, &oFlashStatusWord);
//waits for the blank check to complete
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
//checks if the blank check was successful
if (returnCheck == Fapi_Status_Success)
{
for (flashWriteIndex = 0; flashWriteIndex < (size/2); flashWriteIndex++)
{
//writes a chunk of data to flash
returnCheck = Fapi_issueProgrammingCommand((uint32_t *)startOfParameters + (flashWriteIndex * 4), (uint16 *)parameters_p + (flashWriteIndex * 8), 8, 0, 0, Fapi_AutoEccGeneration);
//waits for the program operation to complete
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
success = 1;
if (returnCheck != Fapi_Status_Success)
{
success = 0;
break;
}
}
} //blank check success
} //erase success
} //set active flash bank success
} //initialization success
Flash_releasePumpSemaphore(FLASHPUMPSEMAPHORE_BASE); //includes EALLOW and EDIS
return success;
#elif defined(_2838xD)
#endif
}
if ((cpu1Data.writeFlash == 1) && (cpu2Data.state != 1))
{
DINT;
writeParameters(¶meters, 20);
cpu1Data.writeFlash = 0;
EINT;
}
#ifdef CLA_C
// Define a size for the CLA scratchpad area that will be used
// by the CLA compiler for local symbols and temps
// Also force references to the special symbols that mark the
// scratchpad are.
CLA_SCRATCHPAD_SIZE = 0x100;
--undef_sym=__cla_scratchpad_end
--undef_sym=__cla_scratchpad_start
#endif //CLA_C
MEMORY
{
PAGE 0 : /* Program Memory */
/* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
/* BEGIN is used for the "boot to Flash" bootloader mode */
BEGIN : origin = 0x086000, length = 0x000002
APPHDR : origin = 0x086002, length = 0x00000C
RAMM0 : origin = 0x000123, length = 0x0002DD
RAMD0 : origin = 0x00B000, length = 0x000800
RAMLS0 : origin = 0x008000, length = 0x000800
RAMLS1 : origin = 0x008800, length = 0x000800
//RAMLS4 : origin = 0x00A000, length = 0x000800
//RAMLS5 : origin = 0x00A800, length = 0x000800
RAMLS4_5 : origin = 0x00A000, length = 0x001000
RAMGS14 : origin = 0x01A000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
RAMGS15 : origin = 0x01B000, length = 0x000FF8 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
// RAMGS15_RSVD : origin = 0x01BFF8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash sectors */
//FLASHA_ : origin = 0x080002, length = 0x001FFE /* on-chip Flash */
//FLASHB_ : origin = 0x082000, length = 0x002000 /* on-chip Flash */
//FLASHC_ : origin = 0x084000, length = 0x002000 /* on-chip Flash */
FLASH : origin = 0x08600E, length = 0x029FF1 /* on-chip Flash */
//FLASHD_ : origin = 0x086000, length = 0x002000 /* on-chip Flash */
//FLASHE_ : origin = 0x088000, length = 0x008000 /* on-chip Flash */
//FLASHF_ : origin = 0x090000, length = 0x008000 /* on-chip Flash */
//FLASHG_ : origin = 0x098000, length = 0x008000 /* on-chip Flash */
//FLASHH_ : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */
//FLASHI_ : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */
FLASHL : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */
FLASHM : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */
FLASHN : origin = 0x0BE000, length = 0x001FF0 /* on-chip Flash */
// FLASHN_RSVD : origin = 0x0BFFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
PAGE 1 : /* Data Memory */
/* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */
BOOT_RSVD : origin = 0x000002, length = 0x000121 /* Part of M0, BOOT rom will use this for stack */
RAMM1 : origin = 0x000400, length = 0x0003F8 /* on-chip RAM block M1 */
// RAMM1_RSVD : origin = 0x0007F8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RAMD1 : origin = 0x00B800, length = 0x000800
RAMLS2 : origin = 0x009000, length = 0x000800
RAMLS3 : origin = 0x009800, length = 0x000800
FLASHJ : origin = 0x0B0000, length = 0x008000 //tables
FLASHK : origin = 0x0B8000, length = 0x002000 //parameters
RAMGS0 : origin = 0x00C000, length = 0x001000 //parameters
RAMGS1 : origin = 0x00D000, length = 0x001000 //cpu1 shared data
RAMGS2 : origin = 0x00E000, length = 0x001000 //cpu2 shared data
RAMGS3 : origin = 0x00F000, length = 0x001000 //scope buffers
RAMGS4 : origin = 0x010000, length = 0x001000
RAMGS5 : origin = 0x011000, length = 0x001000
RAMGS6 : origin = 0x012000, length = 0x001000
RAMGS7 : origin = 0x013000, length = 0x001000
RAMGS8 : origin = 0x014000, length = 0x001000
RAMGS9 : origin = 0x015000, length = 0x001000
RAMGS10 : origin = 0x016000, length = 0x001000
// RAMGS11 : origin = 0x017000, length = 0x000FF8 /* Uncomment for F28374D, F28376D devices */
// RAMGS11_RSVD : origin = 0x017FF8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RAMGS11 : origin = 0x017000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
RAMGS12 : origin = 0x018000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
RAMGS13 : origin = 0x019000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400
CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400
CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080
CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080
}
SECTIONS
{
/* Allocate program areas: */
.cinit : > FLASH PAGE = 0, ALIGN(8)
.text : > FLASH PAGE = 0, ALIGN(8)
codestart : > BEGIN PAGE = 0, ALIGN(8)
appheader : > APPHDR PAGE = 0
//these are for the xcp basic driver
CAL_PARAMS : > FLASH PAGE = 0
FPUmathTables : > FLASH PAGE = 0
//
parameters : > FLASHK PAGE = 1, ALIGN(8)
tables : > FLASHJ PAGE = 1, ALIGN(8)
/* Allocate uninitalized data sections: */
.stack : > RAMM1 PAGE = 1
.switch : > FLASH PAGE = 0, ALIGN(8)
.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
#if defined(__TI_EABI__)
.init_array : > FLASH, PAGE = 0, ALIGN(8)
.bss : > RAMLS2, PAGE = 1
.bss:output : > RAMLS2, PAGE = 1
.bss:cio : > RAMLS2, PAGE = 1
.data : > RAMLS2, PAGE = 1
.sysmem : > RAMLS2, PAGE = 1
/* Initalized sections go in Flash */
.const : > FLASH, PAGE = 0, ALIGN(8)
#else
.pinit : > FLASH, PAGE = 0, ALIGN(8)
.ebss : > RAMLS2, PAGE = 1
.esysmem : > RAMLS2, PAGE = 1
.cio : > RAMLS2, PAGE = 1
/* Initalized sections go in Flash */
.econst : >> FLASH PAGE = 0, ALIGN(8)
#endif
Filter_RegsFile : > RAMGS0, PAGE = 1
SHARERAMGS0 : > RAMGS0, PAGE = 1
SHARERAMGS1 : > RAMGS1, PAGE = 1
SHARERAMGS2 : > RAMGS2, PAGE = 1
SHARERAMGS3 : > RAMGS3, PAGE = 1
SHARERAMGS4 : > RAMGS4, PAGE = 1
ramgs0 : > RAMGS0, PAGE = 1
ramgs1 : > RAMGS1, PAGE = 1
CLADataLS0 : > RAMLS0, PAGE=0
CLADataLS1 : > RAMLS1, PAGE=0
Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1
CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1
/* CLA specific sections */
#if defined(__TI_EABI__)
Cla1Prog : LOAD = FLASH,
RUN = RAMLS4_5,
LOAD_START(Cla1funcsLoadStart),
LOAD_END(Cla1funcsLoadEnd),
RUN_START(Cla1funcsRunStart),
LOAD_SIZE(Cla1funcsLoadSize),
PAGE = 0, ALIGN(8)
#else
Cla1Prog : LOAD = FLASH,
RUN = RAMLS4_5,
LOAD_START(_Cla1funcsLoadStart),
LOAD_END(_Cla1funcsLoadEnd),
RUN_START(_Cla1funcsRunStart),
LOAD_SIZE(_Cla1funcsLoadSize),
PAGE = 0, ALIGN(8)
#endif
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
#if defined(__TI_EABI__)
.TI.ramfunc : {} LOAD = FLASH,
RUN = RAMGS14,
LOAD_START(RamfuncsLoadStart),
LOAD_SIZE(RamfuncsLoadSize),
LOAD_END(RamfuncsLoadEnd),
RUN_START(RamfuncsRunStart),
RUN_SIZE(RamfuncsRunSize),
RUN_END(RamfuncsRunEnd),
PAGE = 0, ALIGN(8)
#else
.TI.ramfunc : {} LOAD = FLASH,
RUN = RAMD0,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
PAGE = 0, ALIGN(8)
#endif
#else
ramfuncs : LOAD = FLASH,
RUN = RAMD0,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
PAGE = 0, ALIGN(8)
#endif
#endif
/* The following section definitions are required when using the IPC API Drivers */
GROUP : > CPU1TOCPU2RAM, PAGE = 1
{
PUTBUFFER
PUTWRITEIDX
GETREADIDX
}
GROUP : > CPU2TOCPU1RAM, PAGE = 1
{
GETBUFFER : TYPE = DSECT
GETWRITEIDX : TYPE = DSECT
PUTREADIDX : TYPE = DSECT
}
/* The following section definition are for SDFM examples */
//Filter1_RegsFile : > RAMGS1, PAGE = 1, fill=0x1111
//Filter2_RegsFile : > RAMGS2, PAGE = 1, fill=0x2222
//Filter3_RegsFile : > RAMGS3, PAGE = 1, fill=0x3333
//Filter4_RegsFile : > RAMGS4, PAGE = 1, fill=0x4444
//Difference_RegsFile : >RAMGS5, PAGE = 1, fill=0x3333
#ifdef CLA_C
/* CLA C compiler sections */
//
// Must be allocated to memory the CLA has write access to
//
CLAscratch :
{ *.obj(CLAscratch)
. += CLA_SCRATCHPAD_SIZE;
*.obj(CLAscratch_end) } > RAMLS1, PAGE = 0
.scratchpad : > RAMLS1, PAGE = 0
.bss_cla : > RAMLS1, PAGE = 0
.const_cla : LOAD = FLASH,
RUN = RAMLS1,
RUN_START(_Cla1ConstRunStart),
LOAD_START(_Cla1ConstLoadStart),
LOAD_SIZE(_Cla1ConstLoadSize),
PAGE = 0
#endif //CLA_C
}