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 v 2.01 with the TMS570LS1224, CCS 6.1 and Halcogen 4.4.
I can successfully erase and write using the flash api with no optimization. However, it seems that with full optimization (I haven't tried other levels yet) that the call to erase flash (Fapi_issueAsyncCommandWithAddress) erases the flash, but then causes an undef entry before returning.
Are there any known issues with using optimization and the flash api?
Thanks,
David
Hi David,
Is this the same issue as you were having a while back? https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/409892/1472077#1472077
I think the next step is still the same - to determine what is causing the UNDEF. It's just going to be something like either executing an FPU instruction with the FPU turned off,
or executing from a data area...
Hi Anthony,
I think the abort is a prefetch abort, not a data abort. I can set a breakpoint on the prefect about entry in the interrupt vectors and it gets hit.
The function that contains the flash api call that is causing the abort is run out of RAM, so I don't think it is an issue with trying to execute from flash when it isn't allowed. This was initially an issue for me, but after running the entire function out of RAM (not just the flash API functions) it seemed to be OK.
I have put the function to erase flash below.
Thanks,
David
#pragma CODE_SECTION(handleFlashPrepare, "flashAPI") 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) { eraseIndex = startSector; remaining = length; 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)); } } } } //We are required to flush the pipeline before anything else accesses flash Fapi_flushPipeline(); TI_Fee_Init(); pRsp->status = flashEraseCheck((uint32_t)eraseStartAddrCheck, length); }
Hi Dan,
I'm staring at the ARM TRM right now and the vector at 0x0000 0010 says Data Abort.
When you set the breakpoint as described: "I think the abort is a prefetch abort, not a data abort. I can set a breakpoint on the prefect about entry in the interrupt vectors and it gets hit."
Which address is the breakpoint set at? Prefetch would be 0x0000 000C.
Also, what information are you getting out of the LR and CP15 when this happens? I think this is the thread we need to pull on.
Do you have any other boards like a 3137 that you can reproduce the problem on ? The 3137 has an ETM port so we could use it to get a 'trace' of what is happening if you can reproduce the problem on it.
EDIT: I think the optimizer is interesting - but it changes so many things it's not a 'great' thread to pull on. The exception could be a 2nd or 3rd order removed from what's changed by turning on the optimizer. Why I'm focused on the LR / CP15 is that if we know who offended - it'll be a lot easier to explain the link to the optimizer and actually figure out how to fix the issue. Its more of a guessing game to think from the optimizer change toward the problem's root cause.
The LR register shows 0x0000_0010, but the breakpoint that is hit is at 0x0000_000C
I exported the contents of CP15, they are in the attached .txt file.
I have a bootloader that is almost identical on the 0332 and we haven't seen an issue with it. Then again, we hadn't seen an issue with previous versions of the bootloader on the 1224.
Hi David:
I got the same problem when I start with TMP570LS1227, HAL 4.4.0, Hercules F021 API020101(F021_API_CortexR4_BE_NDS.lib) and KEIL 5.12, It looks like when execute the command Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, eraseStartAddr); it will generate a _prefetch error .
In Disassembly mode, see below.
after the Fapi_issueAsyncCommandWithAddress enterace address: 0x4858, when execute to 0x4870, the error occured ,or some times jumped to another undef loacation. I still don't know how to do with it.
best regards.
JinYu
Hi JinYu,
The disassembly you are showing looks corrupted to me.
I extracted the Async.WithAddress.obj from F021_API_CortexR4_BE_NDS.lib and disassembled it:
000000: Fapi_issueAsyncCommandWithAddress: 000000: .thumb 000000: .text:Fapi_issueAsyncCommandWithAddress: 000000: B538 PUSH {R3, R4, R5, LR} ; This is missing in your disassembly 000002: 4605 MOV R5, R0 000004: 460C MOV R4, R1 000006: 2D06 CMP R5, #6 000008: D005 BEQ 0x00000016 00000a: 2D08 CMP R5, #8 00000c: D003 BEQ 0x00000016 00000e: 2D0E CMP R5, #14 000010: BF18 IT NE 000012: 2005 MOVNE R0, #5 000014: D108 BNE 0x00000028 000016: $C$L1: 000016: 2010 MOVS R0, #16 ; this is where your PC is at in the screenshot 000018: F7FFFFFE BL _Fapi_issueFsmCommand [0x18] ; This branch was disassembled incorrectly by IAR 00001c: 4803 LDR R0, $C$CON1 [0x2c] 00001e: 6004 STR R4, [R0] 000020: 4628 MOV R0, R5 000022: F7FFFFFE BL _Fapi_issueFsmCommand [0x22] ; This branch was disassembled incorrectly by IAR 000026: 2000 MOVS R0, #0 000028: $C$L2: 000028: BD38 POP {R3, R4, R5, PC} 00002a: 46C0 MOV R8, R8 ; This is a NOP to force alignment of the following data word 00002c: $d: 00002c: $C$CON1: 00002c: FFF8 .half 0xFFF8 00002e: 7110 .half 0x7110
Please note the comments I embedded above.
Summary:
So there clearly went something wrong with our library and the way the IAR tool chain interprets it. For me it looks like IAR tried to inline this function and messed up something. So please disable auto inlining in IAR and see and tell us what happens.
Best Regards,
Christian
I don't believe we have the MPU enabled...how would I check?
So I may be mis-reading it, or maybe it is an artifact of setting a breakpoint with optimization on. But I set a breakpoint in the wrapper function that calls the flash API command. The wrapper function *should* be run out of RAM. When I turn optimization off, it looks like it is, but with optimization set to level 3 it looks like it is being run out of flash. Am I not properly telling it to put the function in RAM?
Function call:
#pragma CODE_SECTION(handleFlashPrepare, "flashAPI") static void handleFlashPrepare(CmdFmt_Obj *pCmd, RspFmt_Obj *pRsp)
Linker file:
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 }
Function to copy flashAPI section to RAM:
.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
optimization off:
optimization lvl 3:
It seems that having the functions declared static is causing the issue. After removing the static keyword I don't see the error anymore.
Hi David,
I think that static functions are more likely to be inlined, could it be that the function is inlined when using static and not after you removed the keyword?
You can force the compiler to selectively not inline a function with the following two methods:
From you last two screenshots it looks like the compiler performed heavy optimizations (-o3 on), which back up my inline assumption.
One more tip, you could use copy tables instead of: LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)
8.8 Linker-Generated Copy Tables
The linker supports extensions to the link command file syntax that enable the following:
• Make it easier for you to copy objects from load-space to run-space at boot time
• Make it easier for you to manage memory overlays at run time
• Allow you to split GROUPs and output sections that have separate load and run addresses
But this is up to you, it just that I prefer the copy tables as I think that they are easier to handle.
Best Regards,
Christian