2

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

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

为什么我不能只将全局声明的缓冲区权限写入 FLASH?为什么本地声明的buffer写入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
    }
}
4

1 回答 1

8

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

它只是巧合地适用于本地缓冲区 - 它与 4 字节边界对齐,而全局缓冲区则不是。如果它正确对齐,它也可以与全局缓冲区一起使用 - 再次纯属巧合。

于 2017-01-27T13:14:11.820 回答