monjiemegoo
Newbie level 6
hellow guys
iam writing a simple bootloader on a stm32f103ve microcontroller from address 0x8008000 and a userapp code from address 0x8008000
my bootloader code include uart1 configuratin for show some massages and spi2 configuration for communication to a spiflash and my userapp code include timer6 , timer 7 configuration for two led blink with interrupt and uart1 interrupt for ymodem protocol and spi2 configuration and external interrupt for a push button.
frist iam program bootloader code with jlink to micro and second program userapp code with jlink too. in bootloader code after uart and spi2 configuration a bit in spiflash will be
checked and if the bit is equal to zero then code jump to userapp. i used below code for jumping.
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
JumpToApplication();
in userapp code for changing vector table of interrupt first i used below code
SCB->VTOR = 0x8008000 | 0x8000;
__enable_irq();
after that i configure all peripheral and interrupt i need. if by putty send a update command for my application a uart interrupt genarate and using ymodem protocol i write a bin file
to spiflash. when i push the pushbutton an external interrupt generate and in irq i set a bit in spiflash and jump to bootloader code for updating frimeware. and then with the bin file
in spi flash i update moico flash. but this application sometimes work and sometimes disent work. for example if i add a new interrupt to userapp or remove someting from it userapp may dosent work after update or timer interrupt may work but uart interrupt dosent work.
here my code befor i wanna jump between codes(i disable evrything)
NVIC->ICER[ 0 ] = 0xFFFFFFFF ;
NVIC->ICER[ 1 ] = 0xFFFFFFFF ;
NVIC->ICER[ 2 ] = 0xFFFFFFFF ;
NVIC->ICER[ 3 ] = 0xFFFFFFFF ;
NVIC->ICER[ 4 ] = 0xFFFFFFFF ;
NVIC->ICER[ 5 ] = 0xFFFFFFFF ;
NVIC->ICER[ 6 ] = 0xFFFFFFFF ;
NVIC->ICER[ 7 ] = 0xFFFFFFFF ;
TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
TIM_ClearITPendingBit(TIM7,TIM_IT_Update);
EXTI_ClearITPendingBit(EXTI_Line13);
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, DISABLE);
RCC_DeInit();
GPIO_DeInit(GPIOA);
GPIO_DeInit(GPIOB);
GPIO_DeInit(GPIOC);
GPIO_DeInit(GPIOD);
TIM_Cmd(TIM6,DISABLE);
TIM_DeInit(TIM6);
TIM_Cmd(TIM7,DISABLE);
TIM_DeInit(TIM7);
EXTI_DeInit();
USART_Cmd(USART1, DISABLE);
USART_DeInit(USART1);
SPI_I2S_DeInit(SPI2);
NVIC_DisableIRQ(TIM6_IRQn);
NVIC_DisableIRQ(TIM7_IRQn);
NVIC_DisableIRQ(EXTI_Line13);
NVIC_DisableIRQ(USART1_IRQn);
NVIC->ICPR[ 0 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 1 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 2 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 3 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 4 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 5 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 6 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 7 ] = 0xFFFFFFFF ;
and here is my bootloader code
#include "common.h"
#include "main.h"
#include "flash.h"
#include "spiflash.h"
//**********************************************************************************
#define ADDRESS_spi_flash_last_address_flag 40000
#define ADDRESS_BootLoader_Flag 20000
#define PACKET_DATA_INDEX ((uint32_t)4)
#define Ymodem_Packet_Size 0x400
//**********************************************************************************
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;
_Bool flag_external_intrrupt = 0;
uint8_t Rd_Buf[2048];
int i;
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
int main()
{
__enable_irq();
uint8_t BootLoader_Flag[1];
uint8_t spi_flash_last_address_flag[1];
uint32_t flashdestination=0x8008000, ramsource;
Rcc_Configuration();
Gpio_Configuration();
UART1_Configuration();
SPI2_Init();
Serial_PutString("BootLoader Start");
df_read_open(ADDRESS_spi_flash_last_address_flag);
df_read(&spi_flash_last_address_flag[0],1);
df_read_open(ADDRESS_BootLoader_Flag);
df_read(&BootLoader_Flag[0],1);
Serial_PutString("begin\n\r");
if(BootLoader_Flag[0] == 0)
{
Jump();
}
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
FLASH_If_Init();
for(i=0;i<spi_flash_last_address_flag[0];i++)
{
FLASH_If_Erase(APPLICATION_ADDRESS+((2*i)*Ymodem_Packet_Size));
//FLASH_EraseAllPages();
}
Serial_PutString("Updating frimware.....\n\r");
for(i=0;i<spi_flash_last_address_flag[0];i++)
{
df_read_open((i*0x400));
for(int k=0;k<1023;k++)
{
df_read(&Rd_Buf[k],1);
}
ramsource = (uint32_t) &Rd_Buf[PACKET_DATA_INDEX];
if (FLASH_If_Write(flashdestination, (uint32_t*) ramsource, 0x400/4) == FLASHIF_OK)
{
flashdestination += 0x400;
Serial_PutString("FLASHIF_OK\n\r");
}
else
{
Serial_PutString("FLASHIF_NOT_OK\n\r");
}
}
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
BootLoader_Flag[0] = 0;
df_write_open(ADDRESS_BootLoader_Flag);
df_write(&BootLoader_Flag[0],1);
df_write_close();
Serial_PutString("Update done\n\r");
Jump();
while(1)
{
}
}
pelese if some one knows where the problem may been help me iam seach alot but steel my bootloader dosent work correct
thanks
iam writing a simple bootloader on a stm32f103ve microcontroller from address 0x8008000 and a userapp code from address 0x8008000
my bootloader code include uart1 configuratin for show some massages and spi2 configuration for communication to a spiflash and my userapp code include timer6 , timer 7 configuration for two led blink with interrupt and uart1 interrupt for ymodem protocol and spi2 configuration and external interrupt for a push button.
frist iam program bootloader code with jlink to micro and second program userapp code with jlink too. in bootloader code after uart and spi2 configuration a bit in spiflash will be
checked and if the bit is equal to zero then code jump to userapp. i used below code for jumping.
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
JumpToApplication();
in userapp code for changing vector table of interrupt first i used below code
SCB->VTOR = 0x8008000 | 0x8000;
__enable_irq();
after that i configure all peripheral and interrupt i need. if by putty send a update command for my application a uart interrupt genarate and using ymodem protocol i write a bin file
to spiflash. when i push the pushbutton an external interrupt generate and in irq i set a bit in spiflash and jump to bootloader code for updating frimeware. and then with the bin file
in spi flash i update moico flash. but this application sometimes work and sometimes disent work. for example if i add a new interrupt to userapp or remove someting from it userapp may dosent work after update or timer interrupt may work but uart interrupt dosent work.
here my code befor i wanna jump between codes(i disable evrything)
NVIC->ICER[ 0 ] = 0xFFFFFFFF ;
NVIC->ICER[ 1 ] = 0xFFFFFFFF ;
NVIC->ICER[ 2 ] = 0xFFFFFFFF ;
NVIC->ICER[ 3 ] = 0xFFFFFFFF ;
NVIC->ICER[ 4 ] = 0xFFFFFFFF ;
NVIC->ICER[ 5 ] = 0xFFFFFFFF ;
NVIC->ICER[ 6 ] = 0xFFFFFFFF ;
NVIC->ICER[ 7 ] = 0xFFFFFFFF ;
TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
TIM_ClearITPendingBit(TIM7,TIM_IT_Update);
EXTI_ClearITPendingBit(EXTI_Line13);
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, DISABLE);
RCC_DeInit();
GPIO_DeInit(GPIOA);
GPIO_DeInit(GPIOB);
GPIO_DeInit(GPIOC);
GPIO_DeInit(GPIOD);
TIM_Cmd(TIM6,DISABLE);
TIM_DeInit(TIM6);
TIM_Cmd(TIM7,DISABLE);
TIM_DeInit(TIM7);
EXTI_DeInit();
USART_Cmd(USART1, DISABLE);
USART_DeInit(USART1);
SPI_I2S_DeInit(SPI2);
NVIC_DisableIRQ(TIM6_IRQn);
NVIC_DisableIRQ(TIM7_IRQn);
NVIC_DisableIRQ(EXTI_Line13);
NVIC_DisableIRQ(USART1_IRQn);
NVIC->ICPR[ 0 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 1 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 2 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 3 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 4 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 5 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 6 ] = 0xFFFFFFFF ;
NVIC->ICPR[ 7 ] = 0xFFFFFFFF ;
and here is my bootloader code
#include "common.h"
#include "main.h"
#include "flash.h"
#include "spiflash.h"
//**********************************************************************************
#define ADDRESS_spi_flash_last_address_flag 40000
#define ADDRESS_BootLoader_Flag 20000
#define PACKET_DATA_INDEX ((uint32_t)4)
#define Ymodem_Packet_Size 0x400
//**********************************************************************************
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;
_Bool flag_external_intrrupt = 0;
uint8_t Rd_Buf[2048];
int i;
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
int main()
{
__enable_irq();
uint8_t BootLoader_Flag[1];
uint8_t spi_flash_last_address_flag[1];
uint32_t flashdestination=0x8008000, ramsource;
Rcc_Configuration();
Gpio_Configuration();
UART1_Configuration();
SPI2_Init();
Serial_PutString("BootLoader Start");
df_read_open(ADDRESS_spi_flash_last_address_flag);
df_read(&spi_flash_last_address_flag[0],1);
df_read_open(ADDRESS_BootLoader_Flag);
df_read(&BootLoader_Flag[0],1);
Serial_PutString("begin\n\r");
if(BootLoader_Flag[0] == 0)
{
Jump();
}
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
FLASH_If_Init();
for(i=0;i<spi_flash_last_address_flag[0];i++)
{
FLASH_If_Erase(APPLICATION_ADDRESS+((2*i)*Ymodem_Packet_Size));
//FLASH_EraseAllPages();
}
Serial_PutString("Updating frimware.....\n\r");
for(i=0;i<spi_flash_last_address_flag[0];i++)
{
df_read_open((i*0x400));
for(int k=0;k<1023;k++)
{
df_read(&Rd_Buf[k],1);
}
ramsource = (uint32_t) &Rd_Buf[PACKET_DATA_INDEX];
if (FLASH_If_Write(flashdestination, (uint32_t*) ramsource, 0x400/4) == FLASHIF_OK)
{
flashdestination += 0x400;
Serial_PutString("FLASHIF_OK\n\r");
}
else
{
Serial_PutString("FLASHIF_NOT_OK\n\r");
}
}
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
//**********************************************************************************
BootLoader_Flag[0] = 0;
df_write_open(ADDRESS_BootLoader_Flag);
df_write(&BootLoader_Flag[0],1);
df_write_close();
Serial_PutString("Update done\n\r");
Jump();
while(1)
{
}
}
pelese if some one knows where the problem may been help me iam seach alot but steel my bootloader dosent work correct
thanks