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.
Hi,
I am using flash api v2.1.1 with the TMS570ls1224. If I step through my code I can flash data OK, but if I just let it run I get a prefetch entry. Any idea what could cause this?
In my Halcogen configuration I have pipeline mode and 3 data wait states. These were the default values so I haven't changed them.
What is the difference between pipeline and normal mode? I tried to change to normal mode to see if it makes a difference, but Halcogen changes it back to pipeline.
[EDIT] This was consistently working when I stepped through, but not when I ran. Now I see the prefetch error all the time. I think I am doing all the initialization needed, and the values being passed into the functions (I've tried writing and erasing) are valid. What would cause a prefetch entry when making a call to either
Fapi_issueProgrammingCommand or Fapi_issueAsyncCommandWithAddress
Thanks,
David
static void handleFlashWrite(CmdFmt_Obj *pCmd, RspFmt_Obj *pRsp) { uint32_t startAddr; uint32_t startProgAddr; uint32_t sizeInBytes; uint32_t bytesRemain; uint8_t *pData; uint8_t *checkData; uint32_t bytes = 0; uint8_t sectorIndex = 0; uint8_t bank = 0; Fapi_StatusType fapiStatus = Fapi_Error_InvalidBank; //Init to an error // visually indicate progress for diag output diagPrintf("%s", BOOT_INDICATION_SYMBOL); // misc init startAddr = pCmd->params[0]; startProgAddr = startAddr; sizeInBytes = pCmd->params[1]; pData = (uint8_t *)&pCmd->params[2]; checkData = pData; bytesRemain = sizeInBytes; //Set the status to an error. if we get all the way through, then we will set it OK pRsp->status = ERR_BURNING_FLASH; //Check the size to be flashed if (sizeInBytes < 16) { bytes = sizeInBytes; } else { bytes = 16; } //Find the bank to flash. Note, this should always be bank 0, but was put in for portability. for (sectorIndex = 0; sectorIndex < NUMBEROFSECTORS - 1; sectorIndex++) { if (startAddr < (uint32_t)(flash_sector[sectorIndex+1].start)) { bank = flash_sector[sectorIndex].bankNumber; //We have the bank, so get out of the for loop sectorIndex = NUMBEROFSECTORS; } } //Initialize the flash banks fapiStatus = Fapi_initializeFlashBanks(HCLK_FREQ); if(fapiStatus == Fapi_Status_Success) { //Set the bank we are flashing as active fapiStatus = Fapi_setActiveFlashBank((Fapi_FlashBankType)bank); if(fapiStatus == Fapi_Status_Success) { //Enable the sectors to be flashed fapiStatus = Fapi_enableMainBankSectors(ENABLE_ALL_SECTORS); if(fapiStatus == Fapi_Status_Success) { while(FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy){}; //TODO bytes needs to be a multiple of 8 because ECC generation is done on 64 bits while((bytesRemain > 0) && (fapiStatus == Fapi_Status_Success)) { fapiStatus = Fapi_issueProgrammingCommand((uint32_t *)startProgAddr, (uint8_t *)pData, (uint8_t)bytes, 0, 0, Fapi_DataOnly); //TODO change to Fapi_AutoEccGeneration while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy ); startProgAddr += bytes; pData += bytes; bytesRemain -= bytes; if(bytesRemain < 16) { bytes = bytesRemain; } } if(fapiStatus == Fapi_Status_Success) { pRsp->status = checkFlashProgram(startAddr, (uint32_t)&checkData, sizeInBytes); } } } } }
Hi,
My bootloader resides in the first 6 sectors of flash, so I am trying to write to the first sector that would be my main app, which starts at address 0x00020000.
I also have an erase function (set up to erase sectors 7-15.) If I step through it will erase 2 sectors OK, but on the third (or if I just let it run) I get a prefetch error on the call to Fapi_issueAsyncCommandWithAddress. (function code below). I have checked the Fapi status, and all the values it increments/decrements and they look OK.
I'm wondering if there is some set up or initialization I am missing or done wrong. I have the api in my linker file (below), also, the first thing I do in my main app is copy the api to RAM. Is anything else needed?
Linker file / code to copy api to RAM
--retain="*(.intvecs)" /*----------------------------------------------------------------------------*/ /* Memory Map */ MEMORY { VECTORS (X) : origin=0x00000000 length=0x00000020 FLASH_API (RX) : origin=0x00000020 length=0x000014E0 FLASH0 (RX) : origin=0x00001500 length=0x0001EB00 STACKS (RW) : origin=0x08000000 length=0x00003500 RAM (RW) : origin=0x08003500 length=0x0002cb00 } /*----------------------------------------------------------------------------*/ /* Section Configuration */ SECTIONS { .intvecs : {} > VECTORS flashAPI : { --library= F021_API_CortexR4_BE.lib < FlashStateMachine.IssueFsmCommand.obj FlashStateMachine.SetActiveBank.obj FlashStateMachine.InitializeFlashBanks.obj FlashStateMachine.EnableMainSectors.obj FlashStateMachine.IssueFsmCommand.obj FlashStateMachine.ScaleFclk.obj Init.obj Utilities.CalculateEcc.obj Utilities.WaitDelay.obj Utilities.CalculateFletcher.obj Read.MarginByByte.obj Read.Common.obj Read.FlushPipeline.obj Read.WdService.obj Async.WithAddress.obj Program.obj > (.text) } load = FLASH_API, run = RAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size) .text : {} > FLASH0 .const : {} > FLASH0 .cinit : {} > FLASH0 .pinit : {} > FLASH0 FEE_TEXT_SECTION : {} > FLASH0 FEE_CONST_SECTION : {} > FLASH0 .bss : {} > RAM .data : {} > RAM .sysmem : {} > RAM FEE_DATA_SECTION : {} > RAM } .text .arm ;------------------------------------------------------------------------------- ; ; Copy the Flash API from flash to SRAM. ; .def _copyAPI2RAM_ .asmfunc _copyAPI2RAM_ .ref api_load flash_load .word api_load .ref api_run flash_run .word api_run .ref api_size flash_size .word api_size ldr r0, flash_load ldr r1, flash_run ldr r2, flash_size add r2, r1, r2 copy_loop1: ldr r3, [r0], #4 str r3, [r1], #4 cmp r1, r2 blt copy_loop1 bx lr .endasmfunc
Function to erase flash
static void handleFlashPrepare(CmdFmt_Obj *pCmd, RspFmt_Obj *pRsp) { uint32_t startAddress = PROGRAMFLASH_BEGIN_ADDRESS; uint32_t sectorIndex = 0; uint8_t bankIndex = 0; uint32_t eraseIndex; uint8_t startBank; uint8_t startSector; uint8_t endBank = 0; uint32_t *eraseStartAddrCheck; uint32_t *eraseStartAddr; bool endLoop = FALSE; int remaining; uint32_t endAddress; uint32_t length; Fapi_StatusType fapiStatus = Fapi_Error_InvalidBank; //Init to an error // for diag output alreadyPrintedHeader = FALSE; eraseStartAddrCheck = (uint32_t *)startAddress; eraseStartAddr = (uint32_t *)startAddress; length = ((PROGRAMFLASH_END_ADDRESS - PROGRAMFLASH_BEGIN_ADDRESS) + 1); endAddress = startAddress + length; for (sectorIndex = 0; (sectorIndex < NUMBEROFSECTORS - 1) && (endLoop == FALSE); sectorIndex++) { if (startAddress == (uint32_t)(flash_sector[sectorIndex].start)) { startBank = flash_sector[sectorIndex].bankNumber; startSector = flash_sector[sectorIndex].sectorNumber; eraseStartAddrCheck = flash_sector[sectorIndex].start; eraseStartAddr = flash_sector[sectorIndex].start; endLoop = TRUE; } } //Reset endLoop variable before the next loop endLoop = FALSE; for (sectorIndex = startSector; (sectorIndex < NUMBEROFSECTORS - sectorIndex) && (endLoop == FALSE); sectorIndex++) { if (endAddress <= ((uint32_t)(flash_sector[sectorIndex].start) + flash_sector[sectorIndex].length)) { endBank = flash_sector[sectorIndex].bankNumber; endLoop = TRUE; } } fapiStatus = Fapi_initializeFlashBanks(HCLK_FREQ); if(fapiStatus == Fapi_Status_Success) { for (bankIndex = startBank; (bankIndex < endBank + 1) && (fapiStatus == Fapi_Status_Success); bankIndex++) { fapiStatus = Fapi_setActiveFlashBank((Fapi_FlashBankType)bankIndex); if(fapiStatus == Fapi_Status_Success) { if (bankIndex == 0) { eraseIndex = startSector; remaining = length; } else { eraseIndex = 0; } fapiStatus = Fapi_enableMainBankSectors(ENABLE_ALL_SECTORS); while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy ){}; if(fapiStatus == Fapi_Status_Success) { do { fapiStatus = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, eraseStartAddr); while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy ){}; remaining -= flash_sector[eraseIndex++].length; eraseStartAddr = flash_sector[eraseIndex].start; }while((remaining > 0) && ( eraseIndex < flash_bank[bankIndex].numOfSectors) && (fapiStatus == Fapi_Status_Success)); } } } } pRsp->status = flashEraseCheck((uint32_t)eraseStartAddrCheck, length); }
Hi QJ,
ENABLE_ALL_SECTORS is set to 0xFFFF for sectors 0-15 in bank 0.
I am using flash lib 2.1.1. I can try using 2.1.0 and see if this changes the behavior.
So my new linker file should look something like:
--retain="*(.intvecs)" /*----------------------------------------------------------------------------*/ /* Memory Map */ MEMORY { VECTORS (X) : origin=0x00000000 length=0x00000020 FLASH_API (RX) : origin=0x00000020 length=0x000014E0 FLASH0 (RX) : origin=0x00001500 length=0x0001EB00 STACKS (RW) : origin=0x08000000 length=0x00003500 RAM (RW) : origin=0x08003500 length=0x0002cb00 } /*----------------------------------------------------------------------------*/ /* Section Configuration */ SECTIONS { .intvecs : {} > VECTORS flashAPI : { --library= F021_API_CortexR4_BE.lib (.text) } load = FLASH_API, run = RAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size) .text : {} > FLASH0 .const : {} > FLASH0 .cinit : {} > FLASH0 .pinit : {} > FLASH0 FEE_TEXT_SECTION : {} > FLASH0 FEE_CONST_SECTION : {} > FLASH0 .bss : {} > RAM .data : {} > RAM .sysmem : {} > RAM FEE_DATA_SECTION : {} > RAM }
Thanks,
David
Assuming I modified the linker file correctly, it didn't affect the behavior, but I do like not needing to list all of the files.
Using Flash api 2.1.0 helped in the sense that if I step through the write function, I can successfully write to flash. However, it will still only erase 2 sectors (it does it successfully, I can see it erase the data that I wrote) before I get a prefetch error. It seems like it will erase any two sectors, but only 2.
However, for both writing and erasing, if I just let the program run I get the prefetch error, I have to step over the flash api program and erase commands for them to work.
Also, it looks like the FEE code generated by Halcogen 4.3 is not compatible with flash API 2.1.0. I get an error in ti_fee_util.c when building, specifically on FAPI_SUSPEND_FSM; in TI_Fee_SuspendResumeErase(). That macro is defined in Helpers.h of the flash API. Using the Helpers.h file from flash api 2.1.1 builds without error, but then there seems to be an error with the define for FAPI_CHECK_FSM_READY_BUSY since it then gives a prefetch error, which it wasn't before.
Is there any way to get the source for the lib so I can further track down the issue?
David
Hi Joe,
Thanks for the thoughts.
1) I haven't enabled the watchdog. I'm assuming it's disabled by default, but I couldn't find anything quickly scanning the documentation, I'll double check.
2) I don't enable interrupts, but explicitly disabling them causes a prefetch abort whether I step over it or not. When I remove the call to
_disable_interrupt_() then I can step over the functions without a prefetch abort.
3) All the flash api functions are running out of ram, I can see this from the disassembly view.
Thanks,
David
David
Again these are just thoughts ;-)
"2) I don't enable interrupts, but explicitly disabling them causes a prefetch abort" may be a clue. That is a call to the halcogen's (sys_core) code and is probably residing in the bank you are operating on or in the erased section?
Also verify the run location of Callback function to service watchdog timer which is used by the Blank, Read, and Verify functions whether WD enabled or not.
And, Flush pipeline after erase/program operations using Fapi_flushPipeline().
Joe