stm32l072kz - 在闪存bank2中写入固件并跳转到bank2

问题描述 投票:0回答:1

我正在编写一个通过UART接收的新固件。我使用带中断的 DMA,我的新固件采用 .HEX 格式,我以 1500 个字节为单位接收它,并且我有一个案例执行提取地址、crc、校验和以及实际数据的处理,然后调用businessRules_update_firmware函数。我想使用应用程序代码本身编写固件。然而,我在

0x08018000
之后写作时遇到了问题。我的微控制器是 5 类,具有 192KB 和双组。我的应用程序代码在bank1上运行,我想在bank2上编写新固件。我从
0x08018000
0x080180F0
一直都能正确录制,但是在
0x08018100
之后就永远无法录制,这可能是什么?

处理 .HEX 文件中的数据后,将在循环内调用

businessRules_updateFirmware
函数。

uint32_t flashAddress = 0x08018000;

void businessRules_updateFirmware(void)
{
  uint8_t buffer[FIRMWARE_PACKAGE_SIZE];
  uint32_t pageError;

  if (protocol_feedFirmwareBuffer(buffer))
  {
    HAL_FLASH_Unlock();
    HAL_FLASH_OB_Unlock();

    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_BSY);
    FLASH_EraseInitTypeDef eraseInitStruct;
    eraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
    eraseInitStruct.PageAddress = flashAddress;
    eraseInitStruct.NbPages = 1;

    if (HAL_FLASHEx_Erase(&eraseInitStruct, &pageError) != HAL_OK)
    {
      HAL_FLASH_Lock();
      HAL_FLASH_OB_Lock();
      return;
    }

    uint8_t binaryData[FIRMWARE_PACKAGE_SIZE / 2];

    hexStringToBytes((const char*)buffer, binaryData, FIRMWARE_PACKAGE_SIZE);

    for (uint32_t i = 0; i < FIRMWARE_PACKAGE_SIZE / 2; i += 4)
    {
      uint32_t data = *(uint32_t*)&binaryData[i];

      if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flashAddress , data) != HAL_OK)
      {
        HAL_FLASH_Lock();
        HAL_FLASH_OB_Lock();
        return;
      }

      flashAddress += 4;
    }

    HAL_FLASH_Lock();
    HAL_FLASH_OB_Lock();
  }
}


uint8_t hexCharToValue(char hexChar)
{
  if (isdigit(hexChar))
    return hexChar - '0';
  else
    return tolower(hexChar) - 'a' + 10;
}

void hexStringToBytes(const char *hexString, uint8_t *byteArray, size_t byteArraySize)
{
  for (size_t i = 0; i < byteArraySize / 2; ++i)
  {
    if (2 * i + 1 >= strlen(hexString))
    {
      byteArray[i] = 0x00;
      break;
    }

    byteArray[i] = (hexCharToValue(hexString[2 * i]) << 4) | hexCharToValue(hexString[2 * i + 1]);
  }
}

我尝试了此功能的一些变体,但到目前为止没有成功。

void businessRules_updateFirmware(void)
{

    uint32_t pageAddress;
    uint32_t pageError;
    uint8_t buffer[FIRMWARE_PACKAGE_SIZE];

    bool dataIsReady = false;
    dataIsReady = protocol_feedFirmwareBuffer(buffer);

    if (dataIsReady)
    {
        uint8_t binaryData[FIRMWARE_PACKAGE_SIZE / 2];
        hexStringToBytes((char *)buffer, binaryData, FIRMWARE_PACKAGE_SIZE / 2);

        pageAddress = protocol_getAddressToFirmware();

        HAL_FLASH_Unlock();
        HAL_FLASH_OB_Unlock();


        FLASH_EraseInitTypeDef eraseInitStruct;
        eraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
        eraseInitStruct.PageAddress = pageAddress;
        eraseInitStruct.NbPages = 1;

        if(HAL_FLASHEx_Erase(&eraseInitStruct, &pageError) != HAL_OK){
            HAL_FLASH_Lock();
            HAL_FLASH_OB_Lock();
            return;
        }

        for(uint32_t i = 0; i < FIRMWARE_PACKAGE_SIZE / 2; i += 4){

            uint32_t data = (binaryData[i] << 0) | (binaryData[i + 1] << 8) | (binaryData[i + 2] << 16) | (binaryData[i + 3] << 24);

            if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, pageAddress + i , data) != HAL_OK){
                HAL_FLASH_Lock();
                HAL_FLASH_OB_Lock();
                return;
            }

        }

        pageAddress += FIRMWARE_PACKAGE_SIZE / 2;
        protocol_setAddressToFirmware(pageAddress);

        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
    }

}

uint8_t hexCharToValue(char hexChar) {
    if (isdigit(hexChar))
        return hexChar - '0';
    else
        return tolower(hexChar) - 'a' + 10;
}

void hexStringToBytes(const char *hexString, uint8_t *byteArray, size_t byteArraySize) {
    for (size_t i = 0; i < byteArraySize; ++i) {
        byteArray[i] = (hexCharToValue(hexString[2 * i]) << 4) | hexCharToValue(hexString[2 * i + 1]);
    }
}
c embedded stm32
1个回答
0
投票

我解决了这个问题,因为我使用 DMA,我的循环缓冲区出现问题,该缓冲区已满,无法处理收到的其余数据。然后我调整了指针和计数器以及 HAL_UARTEx_RxEventCallback 函数

© www.soinside.com 2019 - 2024. All rights reserved.