I am trying to write a bootloader application for STM32F030x8. I write the bin file to the controller via UART. when data is present on the UART RDR register, I put it in a globally declared buffer of 1Kb. Everytime the buffer is full, I am trying to write it to FLASH. After writing to FLASH, the app gives an acknowledge to the PC software and it is ready to accept a new 1Kb block. So the buffer isn't written to while accessed for writing to FLASH. when I try to write the global buffer to FLASH, the application goes into Hardfault handler.
But when I copy the buffer into a locally declared buffer of 1Kb using memcpy(), and try to write that buffer to FLASH, it gives no problem whatsoever.
Why can't I just write the globally declared buffer right to FLASH? Why is there no problem when the locally declared buffer is written to FLASH?
Thanks in advance!
EDIT:
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint16_t DataLength)
{
uint32_t i = 0;
for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++)
{
/* the operation will be done by word */
if (FLASH_Program(FLASH_TYPEPROGRAM_WORD, *FlashAddress, *(uint32_t*)(Data+i)) == 1)
{
/* Check the written value */
if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))
{
/* Flash content doesn't match SRAM content */
return(2);
}
/* Increment FLASH destination address */
*FlashAddress += 4;
}
else
{
/* Error occurred while writing data in Flash memory */
return (1);
}
}
return (0);
}
The Hardfault seems to happen when this function enters the for loop.
When in hardfault exception the LR register is 0xFFFFFFF9, SP = 0x200011E8
What's strange is that in the for loop, there isn't any reference to the buffer, so it's actually never accessed. But it does work when the buffer is copied into a local one. What am I missing here?
EDIT 2:
globally declared buffers:
in globals.c:
uint8_t rec_buffer_uart1[REC_BUFFER_SIZE] = {0};
uint8_t send_buffer_uart1[SEND_BUFFER_SIZE] = {0};
in globals.h:
#define REC_BUFFER_SIZE 1029
extern uint8_t rec_buffer_uart1[REC_BUFFER_SIZE];
#define SEND_BUFFER_SIZE 1031
extern uint8_t send_buffer_uart1[SEND_BUFFER_SIZE];
on buffer received event:
uint32_t flashdestination = APPLICATION_ADDRESS;
uint8_t *buf_ptr = &buf; // buf is locally declared buffer
// every time buffer is full:
{
memcpy(buf_ptr, &rec_buffer_uart1[3], 1024);
// works:
ramsource = (uint32_t)&buf;
// generates Hardfault:
ramsource = (uint32_t)&rec_buffer_uart1[3];
/* Write received data in Flash */
if (FLASH_If_Write(&flashdestination, (uint32_t*) ramsource , (uint16_t) 1024/4) == 0)
{
// send acknowledge
}
}