c-将全局声明的缓冲区写入FLASH时出现STM32硬故障异常



我正在尝试为STM32F030x8编写一个引导程序应用程序。我通过UART将bin文件写入控制器。当UART RDR寄存器上存在数据时,我将其放入全局声明的1Kb缓冲区。每次缓冲区满了,我都会尝试将其写入FLASH。写入FLASH后,应用程序向PC软件发出确认,并准备接受新的1Kb块。因此,在访问缓冲区以写入FLASH时,缓冲区不会被写入。当我尝试将全局缓冲区写入FLASH时,应用程序会进入Hardfault处理程序。

但是,当我使用memcpy()将缓冲区复制到本地声明的1Kb缓冲区中,并尝试将该缓冲区写入FLASH时,没有任何问题。

为什么我不能直接将全局声明的缓冲区权限写入FLASH?为什么将本地声明的缓冲区写入FLASH时没有问题?

提前感谢!

编辑:

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);
}

当该函数进入for循环时,似乎发生了Hardfault。

当出现硬故障异常时,LR寄存器为0xFFFFFFF9,SP=0x200011E8

奇怪的是,在for循环中,没有任何对缓冲区的引用,所以它实际上从未被访问过。但当缓冲区被复制到本地缓冲区时,它确实有效。我在这里错过了什么?

编辑2:

全局声明缓冲区:

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];

缓冲区接收事件:

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
}
}

请注意,函数在uint32_t上运行,同时向它传递uint8_t缓冲区。ARM Cortex-M0内核(如STM32F0中所示)不支持未对齐访问,任何尝试都会导致故障。

它对局部缓冲区起作用只是巧合——它与4字节边界对齐,而全局缓冲区则不然。如果它正确对齐,它也可以与全局缓冲区一起工作——同样纯属巧合。

最新更新