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.

DCSM advice in linker command file for TMS320F285x

Other Parts Discussed in Thread: CONTROLSUITE, MOTORWARE

The linker command file for the F28052f

C:\ti\controlSUITE\device_support\f2805x\v104\F2805x_common\cmd\F28052f.cmd

gives the advice to write all zeroes to the Zone Select Blocks 1-30 (Memory range Z1_DCSM_RSVD)

Since this is in OTP memory, this does not seem like a good idea to me. It seems to defeat the purpose of the Zx_LINKPOINTER.

Should I write zeroes to this memory, or are the comments in this linker command file incorrect?

Best regards,

Rob Jacobs

  • Hi Rob,

    Sorry for delayed response. We are looking at why this comment was added in the linker cmd file. Till we confirm, please do not write zeros to other Zone Select Blocks.

    Regards,
    Vivek Singh
  • Hello Vivek,
    Thanks for looking into this, I will hold off on writing zeroes. In the mean time, is there example code available for using the DCSM?
    Best regards,
    Rob Jacobs
  • Hi Rob, we have example code for F2837xD using DCSM. It is an LED blinky example. It uses 2 assembly files which hold the contents of DCSM OTP locations, and a DCSM linker command file to map them to the correct location.

    You should be able to port these files to meet the F2805x device you are using. The linker command file mapping will most definitely need to be modified.

    sal
  • Please refer to the example C:\ti\controlSUITE\device_support\f2805x\v104\F2805x_examples_ccsv5\flash_f28055, it includes the needed DCSM files (F2805x_DCSM_Z1_ZoneSelectBlock.asm etc).

    Your project should include the same files and the sections linked appropriately as shown in the example. 

    Hope this helps.

    Best Regards

    Santosh Athuru

  • Hello Santosh,

    The flash_f28055 example has indeed helped, thank you very much.

    I have noticed an inconsistency in the linker command files for the F28052F, for both controlSuite and MotorWare
    DCSM_OTP_Z2_P0 : origin = 0x3D7800, length = 0x000004 /* Part of Z1 OTP. LinkPointer/JTAG lock/ Boot Mode */
    DCSM_OTP_Z1_P0 : origin = 0x3D7A00, length = 0x000006 /* Part of Z2 OTP. LinkPointer/JTAG lock */

    - Comments are swapped around
    - Length of DCSM_OTP_Z2_P0 should be 6 as well, since this Z2 includes a BOOTMODE register as well.

    The 2805x Technical Reference Manual (SPRUHE5C) describes the Z2-BOOTMODE usage on page 219.

    Best regards,

    Rob Jacobs
  • Hi Rob,

    Thank you for the feedback. We'll make the appropriate correction in next release.

    Also on below -

    Should I write zeroes to this memory, or are the comments in this linker command file incorrect?

    You do not need to write zeros to zone select block locations. We'll correct this as well in next release.

    Regards,

    Vivek Singh

  • Thank you Vivek,

    I will leave the unused OTP Zone Select Blocks as they are.

    I have been reading a lot of documentation, as well as writing some unit tests to confirm I correctly understand how the DCSM works.

    At the moment I am trying to correctly run our code from EXEONLY Flash and RAM. This now works for the most part, but when I tried to move the initialized static/globals section .cinit to protected Flash, this introduced problems to the program.
    It seems the assembly function processing the CINIT intialization table, located in boot28.inc, is attempting to copy the initialized data from (Secure, but non-EXEONLY) Flash memory to (Secure, but non-EXEONLY) RAM, while the security zone containing these sections is secured. Since the Flash memory is secure, the CINIT reads zeroes instead, and tries to write these to secure RAM, which fails without reporting any errors or changing the secure RAM, as it should.

    What is the recommended way of dealing with this situation?
    - Is there a linker command file option to tell the boot process that the CINIT must be performed from within the same security zone?
    - Should I explicitly initialize all variables from code instead of CINIT? (No preferred, since this is rather error-prone)
    - Should I duplicate the CINIT function (an assembly function, which we mostly avoid messing with) to secure Flash, and run it from there, from the _system_post_cinit() hook? Is there a C implementation of this function available?

    Best regards,

    Rob Jacobs
  • Hi Rob,

    You are right. If the cinit section is placed in protected flash then it'll not work unless _c_int00 (which does the initialization) is also placed into same secure memory.

    Please refer following link to see how to place the same at required location -

    Also refer this wiki page -

    Regards,

    Vivek Singh

  • Nice, with _c_int00 in secured Flash, the variables are initialized correctly.

    The next problem I need to tackle is loading the ramfuncs from EXEONLY Flash to EXEONLY RAM.

    SPRUHE5C page 254 explains how this is done using the SafeCopycodeZ2 function in secure ROM.

    I got this to work after some struggles, and pasted my solution in below.

    My question; is there an easier or cleaner way to get this done? The F2807x has a library which defines the ROM symbols for a similar SafeCopy function, is there such a library for the F2805x?
    \controlSUITE\libs\utilities\boot_rom\F2807x\rev0\rom_symbol_libs\c1_Safe_Zone_Code\c1rom_SafeZoneCodeSymbols.lib

    Best regards,

    Rob Jacobs

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


    The linker command file has the usual ramfuncs definition, with LOAD_SIZE(_RamfuncsLoadSize) added if it is missing.

    in main.c:
    // Declare the linker command file symbols as extern. The symbols are declared to be located at the address/value you need.
    extern uint16_t RamfuncsLoadStart, RamfuncsRunStart, RamfuncsLoadSize;

    // Declare a function type for the Safe Copy Code functions
    typedef uint16_t tFnSafeCopyCodeZx(uint32_t size, uint16_t *dst, uint16_t *src);

    // Declare an instance of these functions at the correct locations
    tFnSafeCopyCodeZx* SafeCopyCodeZ1 = (tFnSafeCopyCodeZx*) 0x3F8000;
    tFnSafeCopyCodeZx* SafeCopyCodeZ2 = (tFnSafeCopyCodeZx*) 0x3F8400;

    in main():

    // Take the address of RamfuncsLoadSize and use it as the number of words that need to be copied
    uint32_t LoadSize = (uint32_t) (&RamfuncsLoadSize);

    // Copy the code in two chunks; Even though RAML1 and RAML2 are in consecutive memory, the function will refuse to copy
    // when crossing the boundary. (Calls need return value checks and LoadSize > 0x400 check, this is an example only)
    SafeCopyCodeZ2(0x400, (uint16_t*) &RamfuncsRunStart, (uint16_t*) &RamfuncsLoadStart); // RAML1
    SafeCopyCodeZ2(LoadSize - 0x400, (uint16_t*) (&RamfuncsRunStart + 0x400), (uint16_t*) (&RamfuncsLoadStart + 0x400)); // RAML2