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.

TMS570LC4357: Query regarding usage of F021 API Fapi_doMarginReadByByte()

Part Number: TMS570LC4357

Hi,

I am facing an issue when using F021 APIs to execute the following sequence:

1. Read an address in Bank0.

2. Erase a sector with the address used in Step 1.

3. Write to the address read in Step 1 (and erased in Step 2).

4. Read the data written in Step 3.

All the above operations are performed on the same Bank0 address. In the above sequence, the F021 APIs called for the erase and write operations (Steps 2 and 3) do not return an error but the data is not erased from/written to the Flash. If I skip Step 1, the erase and write operations go through and read executed after the write (Step 4) also returns the correct data. Does reading from an address before an erase/write operation cause a problem?

I am using the Fapi_doMarginReadByByte() API (with Fapi_NormalRead margin mode) to read from the Flash Memory. Is it necessary to call the Fapi_setActiveFlashBank() and Fapi_enableMainBankSectors() APIs before invoking the read function? Also, should the FAPI_CHECK_FSM_READY_BUSY and FAPI_GET_FSM_STATUS checks be made after the Fapi_doMarginReadByByte() call?

Would appreciate your help in this regard.

Thanks and Regards,

Vimal

  • Hi Vimal,

    When you turn on the read margin mode it will affect all the flash banks. Since you are running code out of the bank0, the bank0 is also subject to margin mode while the code is being fetched. The ECC is always enabled on LC43x device, if a flash bit cell is marginal which should have been read incorrectly in margin mode will be corrected by the ECC, and if two or more bits are marginal during read-margin test then you can see uncorrectable error. Did you get ECC error in step 1? Did you run the code (flash operation related) out of SRAM?

    For read margin, you don't have to enable bank sector which is to enable the sector for program and erase.

  • Hi,

    Thanks for your response. The code is being executed from SRAM and not Bank0. Apologies for not mentioning this earlier.

    The Bank0 address used is 0x00180000U. There was no ECC error in Step 1. For the write operation, the Fapi_AutoEccGeneration argument is used.

    I have tried the same sequence for an address in Bank1 (which is unused) and the same issue occurs. The Flash APIs for erase/write don't return any errors but the flash contents remain unchanged. The problem occurs only if a read is performed on an address before an erase/write at the same address. If the read occurs after the write operation, this issue does not occur. The following are two sequences to demonstrate the issue (the "Data Passed" is indicative):

    Sequence 1:
    Erase 0x00180000U => No Error
    Write 0x00180000U => Data Passed: 0x1234, No Error
    Read 0x00180000U => No Error, Returns 0x1234

    Sequence 2:
    Read 0x00180000U => No Error, returns 0xFFFF
    Erase 0x00180000U => No Error
    Write 0x00180000U => Data Passed: 0x1234, No Error
    Read 0x00180000U => No Error, Returns 0xFFFF

    Sequence 2 fails for both Bank0 and Bank1 but works as expected on an address (0xF0201000U) in Bank 7 (FEE).

    Also, if data is written to or an erase operation is performed on another Bank0 address after Step 4, the operation is successful as seen in the below sequence:

    Sequence 3:
    Read 0x00180000U => No Error, returns 0xFFFF
    Erase 0x00180000U => No Error
    Write 0x00180000U => Data Passed: 0x1234, No Error
    Read 0x00180000U => No Error, returns 0xFFFF

    Erase 0x001BFF00U => No Error
    Write 0x001BFF00U => Data Passed: 0xABCD, No Error
    Read 0x001BFF00U => No Error, Returns 0xABCD

    The Fapi_setActiveFlashBank() and Fapi_enableMainBankSectors() calls are not invoked before the Fapi_doMarginReadByByte() execution.

    Another problem I am facing is that the Erase Bank operation on Bank0 results in an undefEntry exception in a subsequent Flash operation. The linker file with changes to execute the code from RAM is as follows:

    MEMORY
    {
    VECTORS (X) : origin=0x00000000 length=0x00000020
    FLASH0 (RX) : origin=0x00000020 length=0x001FFFE0
    FLASH1 (RX) : origin=0x00200000 length=0x00200000
    STACKS (RW) : origin=0x08000000 length=0x00001500
    RAM (RWX) : origin=0x08001500 length=0x0007EB00
    }

    SECTIONS
    {
    .intvecs : {} > VECTORS
    .TI.ramfunc align(32) : { -l F021_API_CortexR4_BE_L2FMC_V3D16.lib(.text) }
    LOAD=FLASH0, RUN=RAM,
    LOAD_START(RamfuncsLoadStart),
    LOAD_SIZE(RamfuncsLoadSize),
    LOAD_END(RamfuncsLoadEnd),
    RUN_START(RamfuncsRunStart),
    RUN_SIZE(RamfuncsRunSize),
    RUN_END(RamfuncsRunEnd)
    .text align(32) : {} > FLASH0 | FLASH1
    .const align(32) : {} > FLASH0 | FLASH1
    .cinit align(32) : {} > FLASH0 | FLASH1
    .pinit align(32) : {} > FLASH0 | FLASH1
    .bss : {} > RAM
    .data : {} > RAM
    .sysmem : {} > RAM
    }

    The functions which invoke Flash APIs have been prefixed with the following:

    #pragma CODE_SECTION(<xxx>, ".TI.ramfunc");

    The functions have been copied from Flash to Ram in the code using the following statement:

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

    Also, the MPU has been configured to define the SRAM region as type MPU_NORMAL_OIWTNOWA_NONSHARED with permission MPU_PRIV_RW_USER_NA_EXEC.

    Are there any other changes required?

    Thanks and Regards,

    Vimal

  • Hi,

    Would appreciate any inputs you may have on the issue.

    Thanks and Regards,

    Vimal

  • Hi QJ Wang,

    This is a critical issue. Would appreciate anything you can share that might help resolve it.

    Thanks and Regards,

    Vimal

  • Hi Vimal,

    All cacheable locations on Cortex-R5F Hercules MCUs are read allocate. This means that the data cache lines are allocated when a cache miss occurs, bringing 32 bytes of data from the main memory into the cache memory. As a result, subsequent access to these memory locations will result in a cache hit condition, and the data is directly read from the cache memory.

    Programming flash through F021 flash APIs doesn't write data to cache, so the cache is not updated. So your 2nd read gets the same value as the 1st read.

  • You can configure the main flash as Normal_OINC_Noshare

  • Hi QJ Wang,

    Thanks for your response. I was able to resolve the issue yesterday by disabling the cache. I will try your solution and update accordingly. Also, could you please share some sample code for moving the code from Flash to RAM. As mentioned I have had problems when erasing Bank0 and certain (but not all) Bank0 sectors.

    Thanks and Regards,

    Vimal

  • Hi Vimal,

    Please use the bootloader as an example.

    https://git.ti.com/cgit/hercules_examples/hercules_examples/tree/Bootloaders?h=master

    Linker CMD:

    SECTIONS
    {
    .intvecs : {} > VECTORS

    flashAPI:
    {
        .\source\Fapi_UserDefinedFunctions.obj (.text, .data)
        .\source\bl_flash.obj (.text, .data)
        --library= "c:\ti\Hercules\F021 Flash API\02.01.01\F021_API_CortexR4_BE.lib" (.text, .data)
    } palign=8 load = FLASH0, run = SRAM, LOAD_START(apiLoadStart), RUN_START(apiRunStart), SIZE(apiLoadSize)

    .text : {} > FLASH0 /*Initialized executable code and constants*/
    .const : {} > FLASH0

    .cinit : {} > FLASH0 /*Initialized global and static variables*/
    .pinit : {} > FLASH0
    .data : {} > SRAM
    .bss : {} > SRAM /*Uninitialized Global and static variables */
    .sysmem : {} > SRAM

    /* USER CODE BEGIN (4) */
    /* USER CODE END */
    }

    In sys_main.c

    extern unsigned int apiLoadStart;
    extern unsigned int apiLoadSize;
    extern unsigned int apiRunStart;

    main()

    {

         ....

        memcpy(&apiRunStart, &apiLoadStart, (uint32)&apiLoadSize);

          ...

    }

  • Hi QJ Wang,

    Thanks for your response. It seems I do not have access to the bootloader code. When I try to access the bl_link.cmd file, it says "You don't have permission to access this resource". Please suggest.

    Thanks and Regards,

    Vimal

  • Hi QJ Wang,

    I have made the changes suggested to my linker command file but I still get an unDefEntry exception in step 3 when I try the following:

    1. Read from Bank0, Sector0 and write data to SRAM.

    2. Erase Bank0, Sector0.

    3. Write data read in Step 1 from SRAM to Bank0, Sector0.

    My understanding is that this issue might arise when executing code that has been erased in Step 2. Please let me know if this is correct and what can be done to ensure that the above scenario succeeds.

    Please note that the function call sequence is as follows:

    main()->funcA()->funcB_xx()->Fapi_xxx()

    All funcB_xx() functions are put into a single file and configured to run from RAM (similar to bl_flash.c). The three steps above are part of funcA(). I have tried to execute funcA() from both Flash and RAM without success. I have also disabled interrupts prior to the execution of Step 1 and enabled them after Step 3. I am able to erase and program the unused sectors in Bank 0.

    Would appreciate your input in this regard.

    Thanks and Regards,

    Vimal

  • Vimal,

    If your code is located in flash sector0, and you'd like to erase sector 0, you have to copy all the code from sector0 to SRAM and execute the code out of the SRAM.

    The Exception vector table located at the beginning of sector 0 is erased, so you will get error when you have any external interrupt or any abort (data abort and pAbort). 

  • When I try to access the bl_link.cmd file, it says "You don't have permission to access this resource". Please suggest.

    That should be fixed - I reported a similar issue in HTTP 403 Forbidden error attempting to browse .cmd files under https://git.ti.com/