【发布时间】:2017-06-13 00:49:30
【问题描述】:
我正在尝试为 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
}
}
【问题讨论】:
-
您是否将硬故障作为复制操作的直接结果?或者是否可能有一个调度程序(即操作系统)作为您的 SW 的一部分,它可能切换到其他线程,然后导致硬故障?事实上,即使没有操作系统,硬故障是否可能发生在您的一个硬件中断处理程序 (ISR) 中?我建议您在硬故障中断处理程序中放置一个断点,并检查 PC 和 LR 的值,以确保这一点。此外,您可能需要检查其他寄存器的 STM 规范,这可能会为您提供有关问题根源的更多信息。
-
显示完整代码 - 如何声明缓冲区、如何将其传递给函数、如何使用它。
-
顺便说一句-您显示的功能的代码完全是一派胡言。如果这段代码来自 ST 也不足为奇,因为整个 HAL/SPL 表明他们对正确的软件开发一无所知。
-
感谢您的回复。添加代码。
-
另外,你能解释一下为什么这段代码是废话吗?这是我从 HAL 库复制到我自己的库中的函数。
标签: c stm32 bootloader flash-memory stm32f0