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.

TMS320F28379D: ITRAP when using F021 API

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Hello,

I could use some hints, ideas, suggestions. I'm writing a bootloader, that resides in the first flash sector and should accept a firmware over CAN and store it in the remaining sectors. The bootloader erases the flash sectors that are reserved for the firmware and then flashed the firmware with data coming from the CAN bus. This works quite well!

I build the software, using make (CMake) and load the resulting bootloader.out file with CSS and a XDS200 into the TMS320F28379Ds first CPU (all other CPUs are idle). I start the software and everything works fine.

When I now power down the hardware and power it up again, the software crashed with an illegal operation. So far, it seems that the crash steams from the returning of the function that contains calls to the F021 API (which resides in RAM). If I comment out the calls to the F021 API functions, the bootloader does not crash. When I single step through the code, the API calls are not crashing, but the returning from the RAM resided calling function back to the function in flash seems to be the problem. (Function is busy waiting for Fapi_checkFsmForReady() to return Fapi_Status_FsmReady).

To me it looks like, the loading of the bootloader.out file does have some required side effects that does not take place, when power reseting the software. I've tried to set a Range Avoidance Settings: 0x00-0x80000, 0x82000-0xffffffff to prevent the debug probe (XDS200) from writing to anything else beside the flash sector of the bootloader. But this doesn't changed anything.

Is there something, I could use to see the memory range the debug probe is writing to?

best regards,

Torsten

  • Torsten,

    There should not be any read or fetch access from the Flash bank/OTP when an erase or program operation is in progress. Therefore, the Flash API functions, the user application functions that call the Flash API functions, and any ISRs (Interrupt service routines,) must be executed from RAM. For example, the entire code snippet shown below should be executed from RAM and not just the Flash API functions. The reason for this is because the Fapi_issueAsyncCommandWithAddress() function issues the erase command to the FSM, but it does not wait until the erase operation is over. As long as the FSM is busy with the current operation, there should not be a Flash access.

    //

    // Erase a Sector

    //

    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32*)0x0080000);

    //

    // Wait until the erase operation is over

    //

    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}

     

    Thanks and regards,
    Vamsi

  • Vamsi Gudivada said:

    There should not be any read or fetch access from the Flash bank/OTP when an erase or program operation is in progress. Therefore, the Flash API functions, the user application functions that call the Flash API functions, and any ISRs (Interrupt service routines,) must be executed from RAM.

    Yes, that is the case. I think otherwise, the code wouldn't even execute correctly, if execute after loaded via CCS. Second error source that comes to mind, would be a missing copying of the F021 library code and the code that calls this code from flash to RAM. But I think, if that copying was missing, the code would already crash when I try to call one of the F021 library functions.

    That's my code:

    #pragma FUNCTION_OPTIONS ( flash_memory_words, "--opt_level=0" );
    RAMFUNC bool flash_memory_words(uint16_t* buffer, uint16_t size, uint32_t addr)
    {
        EALLOW;
    
        bool result = true;
    
        for ( ; size != 0 && result; )
        {
            // Flashing 0xffffs to the flash memory sets also the ECC portion of the flash,
            // which then can not be altered
            if ( !empty_portion(buffer, FLASH_PORTION) )
            {
                result = Fapi_issueProgrammingCommand(
                            (uint32 *)addr,
                            (uint16*)buffer,
                            FLASH_PORTION, 0, 0,
                            Fapi_AutoEccGeneration) == Fapi_Status_Success;
    
                while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
                    ;
    
                result = result && Fapi_getFsmStatus() == 0;
            }
    
            addr   += FLASH_PORTION;
            buffer += FLASH_PORTION;
            size   -= FLASH_PORTION;
        }
    
        EDIS;
    
        return result;
    }
    

    The crash occurs after the return. Interesting enough, I'm not able to set a break point in that function, but I have to set it before and then step through that function. But maybe this is just a CCS debugger issue. I once observed that the flash memory content of the addresses behind the call to this function where all zero:

    08088e:   56BF02C1    MOVB         *+XAR1[0], #0x02, UNC
    267         return flash_memory_words(block_buffer, MAX_DATA_BLOCK_WORD_SIZE, block_address - block_address % MAX_DATA_BLOCK_SIZE);
    080890:   060A        MOVL         ACC, @0xa
    080891:   8F00C200    MOVL         XAR4, #0x00c200
    080893:   D580        MOVB         XAR5, #0x80
    080894:   18A9FF00    AND          @AL, #0xff00
    080896:   76408729    LCR          flash_memory_words
    268     }
            C$L11:
    080898:   0000        ITRAP0       
    080899:   0000        ITRAP0       
    08089a:   0000        ITRAP0       
    339     {
            Device_configureTMXAnalogTrim():

    Which would make perfectly sense, that this would cause a ITRAP. But was never able to observe this a second time, so I would think that this was a debugger issue too. Interesting enough, erasing the flash memory, where the firmware is supposed to be flashed to, works.

    The .TI.ramfunc contains all Fapi_xxx functions according to the map file and also all functions that do call that API functions and also all relevant ISRs:

    .TI.ramfunc 
    *          0    00081528    000009dd     RUN ADDR = 00008000
                      00081528    00000259     F021_API_F2837xD_FPU32.lib : FlashStateMachine.obj (.text:__Fapi_setupFlashStateMachine)
                      00081781    0000019d                                : Program.obj (.text:_Fapi_issueProgrammingCommand)
                      0008191e    00000088                                : Read.obj (.text:__Fapi_loopRegionForValue)
                      000819a6    00000042                                : BlankCheck.obj (.text:_Fapi_doBlankCheck)
                      000819e8    00000034                                : Init.obj (.text:_Fapi_initializeAPI)
                      00081a1c    0000002e                                : Utilities.obj (.text:_Fapi_calculateFletcherChecksum)
                      00081a4a    0000002d                                : FlashStateMachine.obj (.text:__Fapi_issueFsmCommand)
                      00081a77    0000002c                                : Utilities.obj (.text:__Fapi_divideUnsignedLong)
                      00081aa3    00000025                                : FlashStateMachine.obj (.text:_Fapi_setActiveFlashBank)
                      00081ac8    00000022                                : FlashStateMachine.obj (.text:_Fapi_isAddressEcc)
                      00081aea    00000022                                : FlashStateMachine.obj (.text:__Fapi_setupSectorsForWrite)
                      00081b0c    00000020                                : Async.obj (.text:_Fapi_issueAsyncCommandWithAddress)
                      00081b2c    0000001a                                : Utilities.obj (.text:_Fapi_waitDelay)
                      00081b46    00000016                                : Read.obj (.text:_Fapi_flushPipeline)
                      00081b5c    0000000d                                : Utilities.obj (.text:__Fapi_scaleCycleValues)
                      00081b69    00000001     --HOLE-- [fill = 0]
                      00081b6a    0000000c                                : Init.obj (.ebss) [fill = 0]
                      00081b76    0000000b                                : Utilities.obj (.text:__Fapi_calculateOtpChecksum)
                      00081b81    0000000a                                : FlashStateMachine.obj (.text:_Fapi_checkFsmForReady)
                      00081b8b    00000006                                : FlashStateMachine.obj (.text:_Fapi_getFsmStatus)
                      00081b91    00000077     Fapi_UserDefinedFunctions.c.obj (.TI.ramfunc:_Fapi_setupEepromSectorEnable)
                      00081c08    00000076     can_adapter.c.obj (.TI.ramfunc:_can_interrupt)
                      00081c7e    00000064     main.c.obj (.TI.ramfunc:_bootloader_timer_isr)
                      00081ce2    0000005c     flash_driver.c.obj (.TI.ramfunc:_flash_memory_words)
                      00081d3e    0000004b     flash_driver.c.obj (.TI.ramfunc:_flash_write_and_check_meta_data)
                      00081d89    00000043     libc2000ware.a : flash.c.obj (.TI.ramfunc:_Flash_initModule)
                      00081dcc    0000002f     Fapi_UserDefinedFunctions.c.obj (.TI.ramfunc:_Fapi_setupBankSectorEnable)
                      00081dfb    0000002d     libc2000ware.a : flash.c.obj (.TI.ramfunc:_Flash_setBankPowerMode)
                      00081e28    00000026                    : flash.c.obj (.TI.ramfunc:_Flash_setWaitstates)
                      00081e4e    0000001e                    : flash.c.obj (.TI.ramfunc:_Flash_setPumpPowerMode)
                      00081e6c    0000001a                    : flash.c.obj (.TI.ramfunc:_Flash_disableCache)
                      00081e86    0000001a                    : flash.c.obj (.TI.ramfunc:_Flash_disablePrefetch)
                      00081ea0    00000019                    : flash.c.obj (.TI.ramfunc:_Flash_enableCache)
                      00081eb9    00000019                    : flash.c.obj (.TI.ramfunc:_Flash_enablePrefetch)
                      00081ed2    00000017                    : flash.c.obj (.TI.ramfunc:_Flash_enableECC)
                      00081ee9    00000016     flash_driver.c.obj (.TI.ramfunc:_erase_sector)
                      00081eff    00000004     libc2000ware.a : sysctl.c.obj (.TI.ramfunc)
                      00081f03    00000002     Fapi_UserDefinedFunctions.c.obj (.TI.ramfunc:_Fapi_serviceWatchdogTimer)
    

    The code to copy that segment from the load address to the run address looks like this:

        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    

    The corresponding sniped of the linker script looks like this:

        GROUP
        {
            .TI.ramfunc
            /* All functions from the F021 API are running from RAM */
    
    #       ifdef TARGET_MC_FAMILY_F2837xD
                { -l F021_API_F2837xD_FPU32.lib}
    #       elif defined TARGET_MC_FAMILY_F2837xS
            { -l F021_API_F2837xS_FPU32.lib}
    #       else
    #           error "Unsupported Device!"
    #       endif
    
        } LOAD = FLASH,
          RUN  = RAMLS0_1,
          LOAD_START(_RamfuncsLoadStart),
          LOAD_SIZE(_RamfuncsLoadSize),
          LOAD_END(_RamfuncsLoadEnd),
          RUN_START(_RamfuncsRunStart),
          RUN_SIZE(_RamfuncsRunSize),
          RUN_END(_RamfuncsRunEnd),
          PAGE = 0, ALIGN(8)
    

    But I think is that mapping or copying is correct, as otherwise the application should not run after loaded from the debugger. I think there might be something, that the debugger is initializing the the normal boot procedure is not doing. Copying the code to RAM is done, as the timer ISR is correctly executed after POR as I see a LED blinking.

    Any idea?

    Kind regards,

    Torsten

  • Torsten,

    1. Are you erasing the flash to where the RAM function would return after completing the execution of this function?

    2. When the application returns back to flash, do you see valid code in that flash location?  

    3. What are the load and run addresses of flash_memory_words() as per the map file?

    4. Is watchdog disabled in your application Or do you service it regularly in your application? In debugger case, gel file disables it.

    5. When the application lands in illegal ISR, did you notice any flash ECC error as well?   

    6. In the snap that you shared, address 0x80898 shows up as all 0s.  Is that expected?  

    Thanks and regards,
    Vamsi

  • 1) No. I debugged the situation multiple times now. Wenn debugging on source level, I receive the ITRAP when returning from the function above. If I try to return from that function on assembler code level, I do not experience an ITRAP. Either it's a Heisenbug or it's related to timings. I tried to debug through the assembler code quite fast, but I'm not able to cause the ITRAP, when debugging in assembler (Assembler Step Into).

    2) Yes.

    3) 0x00081ce2 and 0x000087ba

    4) Watchdog is disabled.

    5) I don't think so. Please find attached a screenshot of the FLASH_ECC_REGS Registers

    6) I observed that only once. And I've never observed it again. From the intended program flow, it would not be expected. But if I would observe that reproducible, it would probably be the culprit I'm looking for. I guess it was a glitch in CCS.

    I made an other observation: The flashing fails due to the flash not being erased. The bootloader should have erased the flash. It does so, by calling the following function for all sectors of the firmware flash range:

    RAMFUNC bool erase_sector(uint32_t start_address)
    {
        bool result = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32*)start_address) == Fapi_Status_Success;
    
        while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
            ;
    
        Fapi_FlashStatusType status = Fapi_getFsmStatus();
        result = result && status == 0;
    
        return result;
    }
    

    The function is called and does _not_ report an error (Fapi_getFsmStatus() returns 0). But it does _not_ erase the given sector! And _again_ this only happens, when the bootloader runs from POR. If the bootloader runs after loading the bootloader.out file into the target, everything went fine.

    Is there a chance that I could get the source code of the F021 library?

    Is there something else to initialize the F021 library beside calls to Fapi_initializeAPI() and Fapi_setActiveFlashBank()?

    Any other idea in what direction, I could investigate?

    best regards,

    Torsten

  • Further investigating into the failing flash erase in the bootloader POW case:

    When I run the bootloader in CCS after loading the bootloader.out into the target. Fapi_getFsmStatus() after the Fapi_issueAsyncCommandWithAddress() returns 0, no matter if the flash area of the bootloader was already erased or not.

    When I power reset the target and then connect to the target with the debugger, I can observe that Fapi_getFsmStatus() returns 0xC10 when the flash area is not empty and 0x810 when the flash is empty. Both error codes have bit 11 being set, which is RESERVED according to Table 3-327 in SPRUHM8I Revised September 2019.

     

  • Torsten,

    Thank you for the update that erase is failing.

    1. In the Flash API usage wiki at https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/951668?-FAQ-FAQ-on-Flash-API-usage-for-C2000-devices, please search for below questions and let me know if it helps to fix the erase issue. Especially check whether EALLOW is called before erase or not.
      • What are the common debug tips that we can consider when Flash API fails to erase or program?
      • Does Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, xx) function call return after completing the sector erase operation?
      • If the Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, xx) does not wait for the erase operation completion, how do we know whether the erase operation succeeded or not?
    2. Are you facing this issue on CPU1 or CPU2?
    3. Are you able to successfully execute the flash API example from C2000ware? Example is at: C2000Ware_3_03_00_00\device_support\f2837xd\examples\dual\flash_programming

    Regarding the Flash API source code: Please see https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/780927?-FAQ-F05-Flash-Does-TI-distribute-the-API-source-code-

    Regarding the FMSTAT reserved bit:  That tells me that the erase did not succeed.  Please try above FAQ suggestions and then we can analyze this further based on your reply.

    Thanks and regards,
    Vamsi

  • Hi Vamsi,

    looks like I was missing an EALLOW in front of Fapi_initializeAPI() and Fapi_setActiveFlashBank(). Does this makes sense to you? I mean it worked when being executed after loaded from CCS but not after POR.

    Anyhow: thanks a lot and have a nice weekend,

    Torsten

  • Torsten,

    Glad it helped to fix. Yes, that makes sense. 

    After loading the code to flash in CCS, if you do a reset/restart in debugger (helps to bring the device to reset state after code is loaded via flash plugin) and then execute your application, you will notice the same with debugger as well.

    Have a nice weekend.  I will close this post.

    Thanks and regards,
    Vamsi