I am developing a bootloader and have some trouble jumping from the bootloader to the application. As far as I can see the problem is because I am doing certain initializations in the bootloader which are then also performed in the application. I posted a question about this on the TI forums (https://e2e.ti.com/support/microcontrollers/other/f/908/p/894608/3308592#3308592) but I am not getting any responses so I am looking for another way to fix it.
My idea now is to start the bootloader, download the application image, save it to flash memory and then instead of jumping to the application I want to restart the device and jump to the application before any sort of initialization has been done. I am not sure if this will work but I have been stuck on the jump from bootloader to application for a while now and finally want to make some progress.
For this to work the bootloader will have to somehow know it should jump to the application before any initialization. As far as I know it is not possible to simply write to a single byte somewhere in flash memory because it will require erasing a whole block and the block size on the device I am using is 8KB large. It seems like a waste to reserve 8KB on a device, just so I can save a simple value to pass on between system resets.
Does anyone have any tips on how I could accomplish this?
I am developing for the CC2652R1F using Code Composer Studio along with the TI v18.12.5.LTS compiler.
EDIT:
I tried using kkrambo's situation but it seems not to be working correctly.
I edited my linker command file to include a .boot_cfg section in RAM with a size of four. I put the new linker command file further below.
I then created a global variable uint32_t config
in my file along with #pragma DATA_SECTION(config, ".boot_cfg");
to link it to that section, but I am not sure if I did that correctly. After that I tried reading the value, then changing and then resetting the system to see if it worked.
This is the code I used:
if (config == 0) {
GPIO_write(CONFIG_GPIO_LED_RED, CONFIG_GPIO_LED_ON);
sleep(2);
config = 2;
SysCtrlSystemReset();
} else {
GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_GPIO_LED_ON);
while(1) {}
}
When I just flash the bootloader so I would not have to reset the device using the debugger because I think it might reset the power I see the red light turn on, then the value should change and the system should reset and then hopefully I would see the green light go on, but neither lights turned on. So I think the SysCtrlSystemReset()
function might not be working probably.
So I tried going through the bootloader step by step, then after the config = 2;
statement I used the CPU reset button in the IDE to go back to the beginning, but then when I come back to the if statement the value is still 0.
Linker Command File:
--stack_size=1024 /* C stack is also used for ISR stack */
--heap_size=256
/* Retain interrupt vector table variable */
--retain=g_pfnVectors
/* Override default entry point. */
--entry_point ResetISR
/* Allow main() to take args */
--args 0x8
/* Suppress warnings and errors: */
/* - 10063: Warning about entry point not being _c_int00 */
/* - 16011, 16012: 8-byte alignment errors. Observed when linking in object */
/* files compiled using Keil (ARM compiler) */
--diag_suppress=10063,16011,16012
#define FLASH_BASE 0x0
#define FLASH_SIZE 0x58000
#define RAM_BASE 0x20000000
#define RAM_CFG_BASE 0x20013FFC
#define RAM_CFG_SIZE 0x4 // reserve 4 bytes of ram for bootloader config
#define RAM_SIZE 0x14000 - RAM_CFG_SIZE
#define GPRAM_BASE 0x11000000
#define GPRAM_SIZE 0x2000
#define FLASH_START FLASH_BASE
#define PAGE_SIZE 0x2000
#define BOOT_BASE 0x50000
#define BOOT_END FLASH_CCFG_START - 1
#define BOOT_SIZE ((BOOT_END) - (BOOT_BASE) + 1)
#define APP_BASE 0x0
#define APP_END BOOT_BASE
#define APP_SIZE BOOT_BASE
#define FLASH_CCFG_START 0x00057FA8
#define FLASH_CCFG_END (FLASH_START + FLASH_SIZE - 1)
#define FLASH_CCFG_SIZE ((FLASH_CCFG_END) - (FLASH_CCFG_START) + 1)
/* System memory map */
MEMORY
{
BOOT (RWX) : origin = BOOT_BASE, length = BOOT_SIZE
APP (RWX) : origin = APP_BASE, length = APP_SIZE
FLASH_CCFG (RX) : origin = FLASH_CCFG_START, length = FLASH_CCFG_SIZE
/* Application uses internal RAM for data */
SRAM (RWX) : origin = RAM_BASE, length = RAM_SIZE
RAM_CFG (RWX) : origin = RAM_CFG_BASE, length = RAM_CFG_SIZE
/* Application can use GPRAM region as RAM if cache is disabled in the CCFG
(DEFAULT_CCFG_SIZE_AND_DIS_FLAGS.SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM = 0) */
GPRAM (RWX): origin = GPRAM_BASE, length = GPRAM_SIZE
}
/* Create global constant that points to top of stack */
/* CCS: Change stack size under Project Properties */
__STACK_TOP = __stack + __STACK_SIZE;
/* Section allocation in memory */
SECTIONS
{
.intvecs : > BOOT_BASE
.text : > BOOT
.TI.ramfunc : {} load=BOOT, run=SRAM, table(BINIT)
.const : > BOOT
.constdata : > BOOT
.rodata : > BOOT
.binit : > BOOT
.cinit : > BOOT
.pinit : > BOOT
.init_array : > BOOT
.emb_text : > BOOT
.ccfg : > FLASH_CCFG (HIGH)
.boot_cfg : > RAM_CFG
.vtable : > SRAM
.vtable_ram : > SRAM
vtable_ram : > SRAM
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM (HIGH)
.nonretenvar : > SRAM
.gpram : > GPRAM
}
Board_init()
before doing anything else? If it's doing something you don't want, then you need to modify it. \$\endgroup\$ – Dave Tweed Apr 7 '20 at 16:32