I'm contributing to a project that was developed in Coocox CoIDE 2.0.6 for STM32F103RB (128Kb flash). I have to write a custom boot loader using CoIDE that can upgrade the application to the flash via serial. I started writing the boot loader in .c, at the moment it creates some console messages then tries to jump to the application immediately. I'm using this example: https://embetronicx.com/tutorials/microcontrollers/stm32/stm32f1-bootloader/stm32f1-firmware-update-using-custom-bootloader/ As you might found out already, I'm having trouble jumping to the "main" application - it just hangs. I 'm obviously not an expert on the matter.
I created a custom .ld file to the main app:
{
FLASH (rx) : ORIGIN = 0x08004400, LENGTH = 111K
RAM (rwx) : ORIGIN = 0x200000EC, LENGTH = 20K - 0xEC
}
Also I added this to the main app code:
#define VECT_TAB_OFFSET 0x00004400U
I uploaded the bootloader to 0x08000000 and the main app to 0x08004400 via STLink.
If I look to the .bin file, I see at BASEADDRESS + 4U an address that seems correct: 0x08004ab5. If I'm right, the boot loader should read this entry point address from 0x08004404 and then jump to it. However, I can see in the console "Go to app^@^@" then nothing happens. I also have little clue how to effectively debug an STM32, I've been working with Arduinos before. Could you please guide me by reviewing the code? Thank you much!
main.c
#include "main.h"
#include <stdbool.h>
#include <stdio.h>
#define ETX_APP_START_ADDRESS 0x08004400
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_USART2_UART_Init(void);
static void goto_application( void );
int main(void){
HAL_Init();
SystemClock_Config();
MX_USART2_UART_Init();
printf("Flasher\r\n");
printf("Go to app\r\n");
goto_application();
while (1){
}
}
void SystemClock_Config(void){
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_USART2_UART_Init(void){
// USART2 init
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK){
Error_Handler();
}
}
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
static void goto_application( void ){
typedef void (*jump_app)(void) __attribute__((noreturn));
uint32_t *_vectable = (__IO uint32_t*)ETX_APP_START_ADDRESS; // point _vectable to the start of the application at 0x08004400
HAL_DeInit();
jump_app app_jump = (jump_app) *(_vectable + 1); // get the address of the application's reset handler (4th byte in the table)
SCB->VTOR = _vectable;
__set_MSP(*_vectable);
app_jump();
}
void Error_Handler(void){
__disable_irq();
while (1)
{
}
}
main.h
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f1xx_hal.h"
void Error_Handler(void);
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
FYI I don't own the main app, I'm using a simple Blink example for that.
Is there any way to do debug using these pins?
Yes, that's a SWD debug interface and it is supported by the ST-LINK probe (among many others). \$\endgroup\$