I have a project with a FreeRTOS application running on custom hardware (STM32G483VETS). The project generates two versions of the binary. App1 loads at 0x08000000,App2 (future enhancements and bug fixes) at 0x08040000.
At power on, the MCU boots into App1 running in flash. When instructed over the CAN bus, it disables all interrupts, de-initialises all peripherals, sets up the new stack pointer and jumps to App2 with a call such as:
jump_to_app(EXTENDED_START); // EXTENDED_START is 0x08040000
Code for jump_to_app:
typedef struct {
uint32_t stack_address; // Stack Pointer
application_t *function_ptr; // Program Counter
} jump_structure_t;
void jumpToApp(const uint32_t address)
{
const jump_structure_t *jump_vector_p = (jump_structure_t*) address;
DeInit_all_modules();
/* Jump, uses assembler to avoid stack optimisation */
asm("msr msp, %0; bx %1;" : : "r"(jump_vector_p->stack_address), "r"(jump_vector_p->function_ptr));
}
Code for disabling interrupts and de-initialising modules:
void DeInitAllModules()
{
/* Disable all interrupts */
__disable_irq();
/* De-initialise all modules in the opposite order they were
* initialised in main.c
*/
// MX_OPAMP3_Init();
HAL_OPAMP_DeInit(&hopamp3);
// MX_OPAMP1_Init();
HAL_OPAMP_DeInit(&hopamp1);
// MX_TIM16_Init();
HAL_TIM_PWM_DeInit(&htim16);
// MX_SPI4_Init();
HAL_SPI_DeInit(&hspi4);
// MX_SPI3_Init();
HAL_SPI_DeInit(&hspi3);
// MX_SPI2_Init();
HAL_SPI_DeInit(&hspi2);
// MX_SPI1_Init();
HAL_SPI_DeInit(&hspi1);
//MX_DMA_Init();
HAL_NVIC_DisableIRQ(DMA1_Channel5_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel4_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel3_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn);
// MX_DAC3_Init();
HAL_DAC_DeInit(&hdac3);
// MX_COMP2_Init();
HAL_COMP_DeInit(&hcomp2);
// MX_ADC5_Init();
HAL_ADC_DeInit(&hadc5);
// MX_TIM8_Init();
HAL_TIM_PWM_DeInit(&htim8);
// MX_TIM3_Init();
HAL_TIM_Base_DeInit(&htim3);
// MX_TIM1_Init();
HAL_TIM_Base_DeInit(&htim1);
// MX_RTC_Init();
HAL_RTC_DeInit(&hrtc);
// MX_ADC1_Init();
HAL_ADC_DeInit(&hadc1);
// MX_FDCAN1_Init();
HAL_FDCAN_DeInit(&hfdcan1);
// MX_GPIO_Init();
HAL_GPIO_DeInit(USR_LED_GPIO_Port, USR_LED_Pin);
HAL_GPIO_DeInit(ERR_LED_GPIO_Port, ERR_LED_Pin);
__HAL_RCC_GPIOG_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
}
Up until the point where the jump happens, the IDE is using the ELF to display the C code, variables etc. but App2 has a separate ELF.
How do I keep debugging after the jump? Can I 'combine' the ELF files?
I am developing in STM32CubeIDE v1.9.0 and debugging using a J-Link Ultra+.
Thanks