Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE, CCSTUDIO
Hello, I am a working student who received the task to write a bootloader for this microcontroller without any prior knowledge about this kind of stuff. My C knowledge is also rather shaky.
I have read/skimmed several manuals, e.g. the FLASH API manual, the 6k pages general manual of the controller and others. When reading these manuals I obviously approached them with the wrong mindset, I expected them to be like the documentation I am familiar with: A list of functions with their parameters and what they do. So I went searching for e.g. a 'reboot' function among others, but didn't find anything like that.
I have also looked into the examples in the C2000Ware directory and tried to understand them. I learned about the existence of .cmd files and what they do, but I still don't understand them fully.
My Goals are:
1. Read an update file from an SD card and overwrite the flash memory with the contents of that update file if present.
2. If the file isn't present or after the update is performed, jump to the main program.
My Problems:
1. I do not know how to jump to the address of the main program. I expected some already existing function to do that for me and to just hand it over one of the addresses in my .cmd file, but I couldn't find anything like that. I do have the main program and my bootloader as separate projects in CCStudio and fiddled with the 2838x_FLASH_Ink_ecat_cpu1.cmd files of both projects. I moved the beginning of the main program to FLASH4 and want to reserve FLASH0-FLASH3 for the bootloader.
cmd for main program:
MEMORY
{
/* BEGIN is used for the "boot to Flash" bootloader mode */
BEGIN : origin = 0x088000, length = 0x000002
BOOT_RSVD : origin = 0x000002, length = 0x0001AF /* Part of M0, BOOT rom will use this for stack */
RAMM0 : origin = 0x0001B1, length = 0x00024F
RAMM1 : origin = 0x000400, length = 0x0003F8 /* on-chip RAM block M1 */
// RAMM1_RSVD : origin = 0x0007F8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RAMD0 : origin = 0x00C000, length = 0x000800
RAMD1 : origin = 0x00C800, length = 0x000800
RAMLS0 : origin = 0x008000, length = 0x000800
RAMLS1 : origin = 0x008800, length = 0x000800
RAMLS2 : origin = 0x009000, length = 0x000800
RAMLS3 : origin = 0x009800, length = 0x000800
RAMLS4 : origin = 0x00A000, length = 0x000800
RAMLS5 : origin = 0x00A800, length = 0x000800
RAMLS6 : origin = 0x00B000, length = 0x000800
RAMLS7 : origin = 0x00B800, length = 0x000800
RAMGS0 : origin = 0x00D000, length = 0x001000
RAMGS1 : origin = 0x00E000, length = 0x001000
RAMGS2 : origin = 0x00F000, length = 0x001000
RAMGS3_to_10 : origin = 0x010000, length = 0x008000
/*
RAMGS3 : origin = 0x010000, length = 0x001000
RAMGS4 : origin = 0x011000, length = 0x001000
RAMGS5 : origin = 0x012000, length = 0x001000
RAMGS6 : origin = 0x013000, length = 0x001000
RAMGS7 : origin = 0x014000, length = 0x001000
RAMGS8 : origin = 0x015000, length = 0x001000
RAMGS9 : origin = 0x016000, length = 0x001000
RAMGS10 : origin = 0x017000, length = 0x001000*/
RAMGS11 : origin = 0x018000, length = 0x001000
RAMGS12 : origin = 0x019000, length = 0x001000
RAMGS13 : origin = 0x01A000, length = 0x001000
RAMGS14 : origin = 0x01B000, length = 0x001000
RAMGS15 : origin = 0x01C000, length = 0x000FF8
// RAMGS15_RSVD : origin = 0x01CFF8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
/* Flash sectors */
// FLASH0 : origin = 0x080002, length = 0x001FFE /* on-chip Flash */
// FLASH1 : origin = 0x082000, length = 0x002000 /* on-chip Flash */
// FLASH2 : origin = 0x084000, length = 0x002000 /* on-chip Flash */
// FLASH3 : origin = 0x086000, length = 0x002000 /* on-chip Flash */
FLASH4 : origin = 0x088002, length = 0x007FFE /* on-chip Flash */
FLASH5 : origin = 0x090000, length = 0x008000 /* on-chip Flash */
FLASH6 : origin = 0x098000, length = 0x008000 /* on-chip Flash */
FLASH7 : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */
FLASH8 : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */
FLASH9 : origin = 0x0B0000, length = 0x008000 /* on-chip Flash */
FLASH10 : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */
FLASH11 : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */
FLASH12 : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */
FLASH13 : origin = 0x0BE000, length = 0x001FF0 /* on-chip Flash */
// FLASH13_RSVD : origin = 0x0BFFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
CPU1TOCPU2RAM : origin = 0x03A000, length = 0x000800
CPU2TOCPU1RAM : origin = 0x03B000, length = 0x000800
CPUTOCMRAM : origin = 0x039000, length = 0x000800
CMTOCPURAM : origin = 0x038000, length = 0x000800
CANA_MSG_RAM : origin = 0x049000, length = 0x000800
CANB_MSG_RAM : origin = 0x04B000, length = 0x000800
RESET : origin = 0x3FFFC0, length = 0x000002
}
SECTIONS
{
codestart : > BEGIN, ALIGN(8)
.text : >> FLASH5 | FLASH6 | FLASH7 | FLASH8, ALIGN(8)
.cinit : > FLASH8 | FLASH9 | FLASH10, ALIGN(8)
.switch : > FLASH5, ALIGN(8)
.reset : > RESET, TYPE = DSECT /* not used, */
.stack : > RAMM1
#if defined(__TI_EABI__)
.init_array : > FLASH5, ALIGN(8)
.bss : >> RAMLS4 | RAMLS5 | RAMLS6 | RAMLS7 | RAMGS2
.bss:output : > RAMLS3
.bss:cio : > RAMLS5
.data : > RAMLS5
.sysmem : > RAMLS5
/* Initalized sections go in Flash */
.const : > FLASH10, ALIGN(8)
#else
.pinit : > FLASH5, ALIGN(8)
.ebss : > RAMLS5
.esysmem : > RAMLS5
.cio : > RAMLS5
/* Initalized sections go in Flash */
.econst : >> FLASH8 | FLASH9, ALIGN(8)
#endif
ramgs0 : > RAMGS0, type=NOINIT
ramgs1 : > RAMGS1, type=NOINIT
PIXDATA_RAM > RAMGS3_to_10, type=NOINIT
MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT
MSGRAM_CPU_TO_CM : > CPUTOCMRAM, type=NOINIT
MSGRAM_CM_TO_CPU : > CMTOCPURAM, type=NOINIT
/* The following section definition are for SDFM examples */
/* Filter_RegsFile : > RAMGS0
Filter1_RegsFile : > RAMGS1, fill=0x1111
Filter2_RegsFile : > RAMGS2, fill=0x2222
Filter3_RegsFile : > RAMGS3, fill=0x3333
Filter4_RegsFile : > RAMGS4, fill=0x4444
Difference_RegsFile : >RAMGS5, fill=0x3333 */
#if defined(__TI_EABI__)
.TI.ramfunc : {} LOAD = FLASH7,
RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
LOAD_START(RamfuncsLoadStart),
LOAD_SIZE(RamfuncsLoadSize),
LOAD_END(RamfuncsLoadEnd),
RUN_START(RamfuncsRunStart),
RUN_SIZE(RamfuncsRunSize),
RUN_END(RamfuncsRunEnd),
ALIGN(8)
#else
.TI.ramfunc : {} LOAD = FLASH7,
RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
ALIGN(8)
#endif
}
/*
//===========================================================================
// End of file.
//===========================================================================
*/
cmd for bootloader (currently erroneous)
MEMORY
{
/* BEGIN is used for the "boot to Flash" bootloader mode */
BEGIN : origin = 0x080000, length = 0x000002
BOOT_RSVD : origin = 0x000002, length = 0x0001AF /* Part of M0, BOOT rom will use this for stack */
RAMM0 : origin = 0x0001B1, length = 0x00024F
RAMM1 : origin = 0x000400, length = 0x0003F8 /* on-chip RAM block M1 */
// RAMM1_RSVD : origin = 0x0007F8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RAMD0 : origin = 0x00C000, length = 0x000800
RAMD1 : origin = 0x00C800, length = 0x000800
RAMLS0 : origin = 0x008000, length = 0x000800
RAMLS1 : origin = 0x008800, length = 0x000800
RAMLS2 : origin = 0x009000, length = 0x000800
RAMLS3 : origin = 0x009800, length = 0x000800
RAMLS4 : origin = 0x00A000, length = 0x000800
RAMLS5 : origin = 0x00A800, length = 0x000800
RAMLS6 : origin = 0x00B000, length = 0x000800
RAMLS7 : origin = 0x00B800, length = 0x000800
RAMGS0 : origin = 0x00D000, length = 0x001000
RAMGS1 : origin = 0x00E000, length = 0x001000
RAMGS2 : origin = 0x00F000, length = 0x001000
RAMGS3_to_10 : origin = 0x010000, length = 0x008000
/*
RAMGS3 : origin = 0x010000, length = 0x001000
RAMGS4 : origin = 0x011000, length = 0x001000
RAMGS5 : origin = 0x012000, length = 0x001000
RAMGS6 : origin = 0x013000, length = 0x001000
RAMGS7 : origin = 0x014000, length = 0x001000
RAMGS8 : origin = 0x015000, length = 0x001000
RAMGS9 : origin = 0x016000, length = 0x001000
RAMGS10 : origin = 0x017000, length = 0x001000*/
RAMGS11 : origin = 0x018000, length = 0x001000
RAMGS12 : origin = 0x019000, length = 0x001000
RAMGS13 : origin = 0x01A000, length = 0x001000
RAMGS14 : origin = 0x01B000, length = 0x001000
RAMGS15 : origin = 0x01C000, length = 0x000FF8
// RAMGS15_RSVD : origin = 0x01CFF8, length = 0x000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
/* Flash sectors */
FLASH0 : origin = 0x080002, length = 0x001FFE /* on-chip Flash */
FLASH1 : origin = 0x082000, length = 0x002000 /* on-chip Flash */
FLASH2 : origin = 0x084000, length = 0x002000 /* on-chip Flash */
FLASH3 : origin = 0x086000, length = 0x002000 /* on-chip Flash */
// FLASH4 : origin = 0x088000, length = 0x008000 /* on-chip Flash */
// FLASH5 : origin = 0x090000, length = 0x008000 /* on-chip Flash */
// FLASH6 : origin = 0x098000, length = 0x008000 /* on-chip Flash */
// FLASH7 : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */
// FLASH8 : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */
// FLASH9 : origin = 0x0B0000, length = 0x008000 /* on-chip Flash */
// FLASH10 : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */
// FLASH11 : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */
// FLASH12 : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */
// FLASH13 : origin = 0x0BE000, length = 0x001FF0 /* on-chip Flash */
// FLASH13_RSVD : origin = 0x0BFFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
CPU1TOCPU2RAM : origin = 0x03A000, length = 0x000800
CPU2TOCPU1RAM : origin = 0x03B000, length = 0x000800
CPUTOCMRAM : origin = 0x039000, length = 0x000800
CMTOCPURAM : origin = 0x038000, length = 0x000800
CANA_MSG_RAM : origin = 0x049000, length = 0x000800
CANB_MSG_RAM : origin = 0x04B000, length = 0x000800
RESET : origin = 0x3FFFC0, length = 0x000002
}
SECTIONS
{
codestart : > BEGIN, ALIGN(8)
.text : >> FLASH1 | FLASH2 | FLASH3, ALIGN(8)
.cinit : > FLASH2 | FLASH3, ALIGN(8)
.switch : > FLASH1, ALIGN(8)
.reset : > RESET, TYPE = DSECT /* not used, */
.stack : > RAMM1
#if defined(__TI_EABI__)
.init_array : > FLASH1, ALIGN(8)
.bss : >> RAMLS4 | RAMLS5 | RAMLS6 | RAMLS7 | RAMGS2
.bss:output : > RAMLS3
.bss:cio : > RAMLS5
.data : > RAMLS5
.sysmem : > RAMLS5
/* Initalized sections go in Flash */
.const : > FLASH3, ALIGN(8)
#else
.pinit : > FLASH1, ALIGN(8)
.ebss : > RAMLS5
.esysmem : > RAMLS5
.cio : > RAMLS5
/* Initalized sections go in Flash */
.econst : >> FLASH2 | FLASH3, ALIGN(8)
#endif
ramgs0 : > RAMGS0, type=NOINIT
ramgs1 : > RAMGS1, type=NOINIT
PIXDATA_RAM > RAMGS3_to_10, type=NOINIT
MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT
MSGRAM_CPU_TO_CM : > CPUTOCMRAM, type=NOINIT
MSGRAM_CM_TO_CPU : > CMTOCPURAM, type=NOINIT
/* The following section definition are for SDFM examples */
/* Filter_RegsFile : > RAMGS0
Filter1_RegsFile : > RAMGS1, fill=0x1111
Filter2_RegsFile : > RAMGS2, fill=0x2222
Filter3_RegsFile : > RAMGS3, fill=0x3333
Filter4_RegsFile : > RAMGS4, fill=0x4444
Difference_RegsFile : >RAMGS5, fill=0x3333 */
#if defined(__TI_EABI__)
.TI.ramfunc : {} LOAD = FLASH3,
RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
LOAD_START(RamfuncsLoadStart),
LOAD_SIZE(RamfuncsLoadSize),
LOAD_END(RamfuncsLoadEnd),
RUN_START(RamfuncsRunStart),
RUN_SIZE(RamfuncsRunSize),
RUN_END(RamfuncsRunEnd),
ALIGN(8)
#else
.TI.ramfunc : {} LOAD = FLASH3,
RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
ALIGN(8)
#endif
}
/*
//===========================================================================
// End of file.
//===========================================================================
*/
you probably get what I was trying to do. but assuming the addresses where correct and the approach is correct, how do I jump to the starting address of the main program from the bootloader?
From the documentation, it seemed to me that something like this should be enough, but I never got it to work: int jump_to_main_program() { return 0x088002; }
2. I do not know how to access/read from the SD card. I have some mmc_F2828x.c file in my project that gives me access to the drive and a ff.h file that deals with files/FRESULTs. I tried opening a file that just contains the string 'hello' with this snippet:
FRESULT fresult = f_open(&update_file, "/hello", FA_READ);
but it doesn't work (sorry for unformatted code snippets, but this website doesn't let me use C code snippets.) Must be that I also need to use disk_read() somehow. I am quite confident that I figure out the SD card stuff on my own in the end, but I have no confidence in my ability to figure out how to jump to a specific address and how to overwrite specific parts of the flash and how to order bootloader and main program. I feel very lost with this task.
I would already greatly appreciate if someone could just point me in the direction of where to learn how this stuff works. I also checked out the C2000 Academy, but it didn't help me at all. I feel like I am just brute forcing things and have no idea what I am doing, contrary to my usual development tasks with python or rust.