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.

F28M35M52C: Flash Programming fails while CSM is active

Part Number: F28M35M52C

Tool/software:

Hello,

I have a bootloader that downloads a flash image over CAN for programming into FLASH.  The CSM is active with the following:

Z1 CSMPSWD set to password value

Z1 GRABSECT 0xFFF55555

Z1 GRABRAM 0xFFFFFFF5

All of the other security settings are unset (erased value)

The FLASH API is loaded into C0 RAM upon startup.

It appears the FLASH API is returning successful status on both sector erase and write commands but the flash is NOT being erased and not being written to.

If I erase the password (with or without the GRABSECT and GRABRAM settings), everything works normally.  Flash is erased as expected and written as expected and verified with a CRC.

I have tried with the stack in both C0 and C1 RAM, although given the GRABSECT and GRABRAM settings, everything (Flash code, Ram code, Ram, stack, etc.) are all in Z1.

Any suggestions or something I missed here?

Thanks in advance,

--Keith

  • Hi Keith, 

    Will look to get this to the correct expert.

    Thanks,

    Charles

  • Hi Keith,

    It seems everything is working as expected except for the returned status of the flash API. I would expect it to return a fail when you have CSM passwords programmed and have assigned the flash to the secure zone.

    Can you share a screenshot of the success status that gets returned? I will reassign this thread to our flash API expert who can better assist you.

    Thank you,

    Luke

  • Luke,

    I'm confused. Are you saying I have to unlock the flash in order to reprogram it? This is the reason I placed the flash API in secure RAM in the first place.

    If I have to unlock the device in order to program flash from the bootloader, this means I have to place the password in the bootloader which leaves it vulnerable, especially during programming via bootloader download.

    I will work on a meaningful screenshot or other evidence of the return code. 

    --Keith

  • Keith,

    Please note that flash api doesn't wait till flash operation is completed. It just issues the command and returns back. Hence, the user application must wait for the FMC to complete the operation before returning to any kind of Flash accesses. Refer below flash api user guide for more details

    Also can you check FMSTAT value using Fapi_getFsmStatus() function and see if their are any errors?
    Regards,
    Rajeshwary
  • Doing an erase on sectors that are in Z1

    (As mentioned above: 

    Z1 CSMPSWD set to password value

    Z1 GRABSECT 0xFFF55555

    Z1 GRABRAM 0xFFFFFFF5

    )

    Waiting for FSM to complete and then reading FMSTAT register using Fapi_getFsmStatus().

    The register value is 0x00000410.

    CSTAT = 1

    EV = 1

    Not particularly informative.  I read this as there was an error and erase did NOT verify but no indication as to why.

    Can you please clarify something Luke said in his last message...that I must UNLOCK the Flash prior to reprogramming from internal code that is in the same security zone?

    If so, this is a really big limitation and I can't find any documentation that confirms this in either the CSM or FLASH API documentation.

    --Keith

  • Luke, per subsequent posts, I found that trying to erase the flash while still password locked was unsuccessful due to FMSTAT CSTAT = 1 and EV = 1.  

    Can you please clarify your statement that I have to unlock the flash before reprogramming from an internal bootloader (that is in the same security zone)?  This seems like a big limitation as I will have to embed the password into the bootloader code and then the flash is actually not secure during the programming process.

    I could really use some assistance on this.

    Thanks,

    --Keith

  • Hi Keith,

    How are you copying the Flash API from secure Flash to secure RAM at startup?

    If the Flash API is stored in secure memory, you should be able to program the Flash. I have clarified this with Luke.

    Thanks and regards,

    Charles

  • Thank you for clarifying Charles.

    The Flash API is being copied near the beginning of execution and appears to work properly (in a non-secured environment) because I can erase and write to Flash without issue.

    In the linker file, we establish the Flash API code range...

    C03SRAM (RWX) : origin = 0x20000000, length = 0x00002000

    GROUP
    {
    ramfuncs
    {
    -l F021_API_CortexM3_LE.lib
    }
    }
    LOAD = FLASH,
    RUN = C03SRAM
    LOAD_START(RamfuncsLoadStart),
    LOAD_END(RamfuncsLoadEnd),
    LOAD_SIZE(RamfuncsLoadSize),
    RUN_START(RamfuncsRunStart),
    PAGE = 0

    Here is the mapping of the Flash API functions from the map file:

    20000e81 Fapi_BlockErase
    2000112d Fapi_BlockProgram
    20000e70 Fapi_GlobalInit
    20000c5f Fapi_calculateEcc
    20000bb5 Fapi_calculateFletcherChecksum
    20000de9 Fapi_checkFsmForReady
    200001b5 Fapi_connectFlashPumpToCpu
    200002e7 Fapi_disableBanksForOtpWrite
    200002a7 Fapi_enableBanksForOtpWrite
    200001ad Fapi_getFsmStatus
    20000cd1 Fapi_initializeAPI
    20000d71 Fapi_isAddressEcc
    20000e55 Fapi_issueAsyncCommand
    20000e0d Fapi_issueAsyncCommandWithAddress
    20000221 Fapi_issueFsmSuspendCommand
    20000811 Fapi_issueProgrammingCommand
    20000b0b Fapi_issueProgrammingCommandForEccAddresses
    20000da1 Fapi_remapEccAddress
    200014a5 Fapi_serviceWatchdogTimer
    200007a5 Fapi_setActiveFlashBank
    20001405 Fapi_setupBankSectorEnable
    200012d1 Fapi_setupEepromSectorEnable
    20000c97 Fapi_waitDelay
    20000261 Fapi_writeEwaitValue

    In main(),

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

    When I secure the part, I set the Z1_GRABRAM register to 0xFFFFFFF5 which should make both C0 and C1 RAM secure and in the same zone (Z1) as the Flash sectors I am erasing.

    Z1_GRABSECT =  0xFFF55555

    Waiting for FSM to complete and then reading FMSTAT register using Fapi_getFsmStatus().

    The register value is 0x00000410.

    CSTAT = 1

    EV = 1

    Which only tells me that the erase failed to verify but not why.

    --Keith

  • Does the outcome result in the same if memcpy function is not stored in secure memory?

    Thanks,

    Charles

  • Hello Charles,

    memcpy is in secure FLASH.  If it isn't, then it would fail copying to RAM, right?  It must be working because I can see the output of the Flash API status on my console.  I'm not sure what you are trying to achieve with this question.  Can you clarify?

    I also tried resetting the GRABRAM register so that the Flash API is now in unsecure RAM and I get exactly the same failure.

    --Keith

  • Hi Keith,

    Can you give me the linker cmd file or whole project for evaluation?

    Thanks and regards,

    Charles

  • Hi Charles,

    It will take quite a bit of effort to sanitize and test the project before I can send it.  Let me include the linker command file here to see if you can detect any issues first.

    Thanks,

    --Keith

    --------------------------------------------------------------------------

    --retain=g_pfnVectors

    --retain=dcsm_z1_secvalues.obj(.z1secvalues,.z1_csm_rsvd)
    --retain=dcsm_z2_secvalues.obj(.z2secvalues,.z2_csm_rsvd)

    MEMORY
    {
    BOOTROM (RX) : origin = 0x00000000, length = 0x00010000

    /* Flash Block 0, Sector 0 Z1 CSM */
    CSM_ECSL_Z1 : origin = 0x00200000, length = 0x00000024 // Reserved to avoid permanent board lock
    CSM_RSVD_Z1 : origin = 0x00200024, length = 0x0000000C // Reserved to avoid permanent board lock

    /*To load the memory address after reset*/
    FLASH_BOOT (RWX) : origin = 0x00200030, length = 0x00000004
    /* To store the .exe file, global variables, initialized data */
    FLASH (RWX) : origin = 0x00200034, length = 0x0000FF00 // Reserved for bootloader (part of sector N and sector M, L)

    //Flash_Api data Write and Read purpose used
    FLASH_C (RWX) : origin = 0x00274000, length = 0x4000 /*16k*/
    FLASH_B (RWX) : origin = 0x00278000, length = 0x4000 /*16k*/
    FLASH_A (RWX) : origin = 0x0027C000, length = 0x3fd0 /*~16k*/ // == 0x0027FFD0

    CSM_RSVD_Z2 : origin = 0x0027FFD0, length = 0x0000000C // Reserved to avoid permanent board lock
    CSM_ECSL_Z2 : origin = 0x0027FFDC, length = 0x00000024 // Reserved to avoid permanent board lock

    C03SRAM (RWX) : origin = 0x20000000, length = 0x00002000 // Used RAM C0 sector only
    S01SHRAM (RWX) : origin = 0x20008000, length = 0x00004000 // Used SRAM S0 and S1 sector
    //S23SHRAM (RWX) : origin = 0x2000c000, length = 0x4000

    MAC_OTP (R) : origin = 0x680810, length = 0x8
    }

    SECTIONS
    {
    /* Allocate program areas: */
    .text : > FLASH
    .binit : > FLASH
    .cinit : > FLASH
    .pinit : > FLASH

    /* Initialized sections go in Flash */
    .const : > FLASH

    /* Allocate uninitalized data sections: */
    .vtable : > C03SRAM //| S03SHRAM
    .data : > /*> C03SRAM |*/ S01SHRAM // Either one RAM
    .bss : > /*C03SRAM |*/ S01SHRAM
    .dma : > /*C03SRAM |*/ S01SHRAM // Either one RAM
    .sysmem : > /*C03SRAM |*/ S01SHRAM
    .stack : > C03SRAM | S01SHRAM
    .cio : > /*C03SRAM |*/ S01SHRAM
    .neardata : > /*C03SRAM |*/ S01SHRAM
    .rodata : > /*C03SRAM |*/ S01SHRAM
    .args : > /*C03SRAM |*/ S01SHRAM

    .z1secvalues : > CSM_ECSL_Z1
    .z1_csm_rsvd : > CSM_RSVD_Z1
    .z2secvalues : > CSM_ECSL_Z2
    .z2_csm_rsvd : > CSM_RSVD_Z2

    // ramfuncs : LOAD = FLASH, /* Load section to Flash */
    // RUN = C03SRAM, /* Run section from RAM */
    // LOAD_START(RamfuncsLoadStart),
    // LOAD_SIZE(RamfuncsLoadSize),
    // LOAD_END(RamfuncsLoadEnd),
    // RUN_START(RamfuncsRunStart),
    // PAGE = 0

    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    GROUP
    {
    ramfuncs
    {
    -l F021_API_CortexM3_LE.lib
    }
    }
    LOAD = FLASH,
    RUN = C03SRAM,//S47SHRAM,
    LOAD_START(RamfuncsLoadStart),
    LOAD_END(RamfuncsLoadEnd),
    LOAD_SIZE(RamfuncsLoadSize),
    RUN_START(RamfuncsRunStart),
    PAGE = 0//,ALIGN(4)
    #else
    GROUP
    {
    ramfuncs
    {
    -l F021_API_CortexM3_LE.lib
    }
    }
    LOAD = FLASH,
    RUN = C03SRAM, //S47SHRAM,
    LOAD_START(RamfuncsLoadStart),
    LOAD_END(RamfuncsLoadEnd),
    LOAD_SIZE(RamfuncsLoadSize),
    RUN_START(RamfuncsRunStart),
    PAGE = 0//,ALIGN(4)
    #endif
    #endif


    .MACOTP : > MAC_OTP
    }

    __STACK_TOP = __stack + 256;

  • Hi Keith,

    It seems like you've allocated some resources to S0 and S1 SHRAM, which are non secure memories. Could you try allocating everything to the securable RAMs (C0 and C1)?

    Thank you,

    Luke

  • Hello,

    I moved stuff around.  I couldn't fit the .vtable section within the secure RAM (C0/C1 sectors).  Other than that, everything is in the secure RAM.  As soon as I set a password and change the GRABRAM and GRABSECT registers, I can't erase or write the FLASH.

    MEMORY CONFIGURATION

    name origin length used unused attr fill
    ---------------------- -------- --------- -------- -------- ---- --------
    BOOTROM 00000000 00010000 00000000 00010000 R X
    CSM_ECSL_Z1 00200000 00000024 00000000 00000024 RWIX
    CSM_RSVD_Z1 00200024 0000000c 00000000 0000000c RWIX
    FLASH_BOOT 00200030 00000004 00000004 00000000 RW X
    FLASH 00200034 0000ff00 0000dc70 00002290 RW X
    FLASH_C 00274000 00004000 00000000 00004000 RW X
    FLASH_B 00278000 00004000 00000000 00004000 RW X
    FLASH_A 0027c000 00003fd0 00000000 00003fd0 RW X
    CSM_RSVD_Z2 0027ffd0 0000000c 00000000 0000000c RWIX
    CSM_ECSL_Z2 0027ffdc 00000024 00000000 00000024 RWIX
    MAC_OTP 00680810 00000008 00000000 00000008 R
    C03SRAM 20000000 00004000 00003e3a 000001c6 RW X
    S01SHRAM 20008000 00004000 000001b0 00003e50 RW X


    SEGMENT ALLOCATION MAP

    run origin load origin length init length attrs members
    ---------- ----------- ---------- ----------- ----- -------
    00200030 00200030 0000a480 0000a480 r-x
    00200030 00200030 00000004 00000004 r-x .ti_catalog_arm_cortexm3_concertoInit_begin
    00200034 00200034 000001ac 000001ac r-- .resetVecs
    002001e0 002001e0 0000a2d0 0000a2d0 r-x .text
    0020b7d0 0020b7d0 00002288 00002288 r--
    0020b7d0 0020b7d0 00002288 00002288 r-- .const
    0020da98 0020da98 00000210 00000210 r--
    0020da98 0020da98 00000200 00000200 r-- .cinit
    0020dc98 0020dc98 00000010 00000010 r-- .binit
    20000000 20000000 000020f8 00000000 rw-
    20000000 20000000 000001ac 00000000 rw- .vecs
    200001b0 200001b0 00001f48 00000000 rw- .bss
    200020f8 0020a4b0 00001320 00001320 rwx
    200020f8 0020a4b0 00001320 00001320 rwx ramfuncs
    20003418 20003418 000009ec 00000000 rw-
    20003418 20003418 000005ea 00000000 rw- .data
    20003a04 20003a04 00000400 00000000 rw- .stack
    20003e04 0020da58 0000003c 0000003c r-x
    20003e04 0020da58 0000003c 0000003c r-x .flashfuncs
    20008000 20008000 000001b0 00000000 rw-
    20008000 20008000 000001b0 00000000 rw- .vtable

    --Keith

  • After yet one more read through the CSM and registers, I tried changing the SECZONEREQUEST SEM bits to restrict access to the flash wrapper registers to only Zone 1.  The tech ref manual seems to imply that a 00 value should allow any access without restriction (non-secure, zone 1 or 2) but this is apparently not the case.

    Anyway, this resolved my immediate issue.