#include "pch.h" #include "flash_int.h" extern "C" { #include "boot.h" #include "flash.h" } void FlashInit() { // Flash already init by ChibiOS } blt_addr FlashGetUserProgBaseAddress() { #ifdef STM32H7XX return FLASH_BASE + 128 * 1024; #else // not STM32H7 return FLASH_BASE + 32 * 1024; #endif } blt_bool FlashWrite(blt_addr addr, blt_int32u len, blt_int8u *data) { // don't allow overwriting the bootloader if (addr < FlashGetUserProgBaseAddress()) { return BLT_FALSE; } return (FLASH_RETURN_SUCCESS == intFlashWrite(addr, (const char*)data, len)) ? BLT_TRUE : BLT_FALSE; return BLT_TRUE; } blt_bool FlashErase(blt_addr addr, blt_int32u len) { // don't allow erasing the bootloader if (addr < FlashGetUserProgBaseAddress()) { return BLT_FALSE; } if (!intFlashIsErased(addr, len)) { return (FLASH_RETURN_SUCCESS == intFlashErase(addr, len)) ? BLT_TRUE : BLT_FALSE; } return BLT_TRUE; } blt_bool FlashDone() { return BLT_TRUE; } blt_bool FlashWriteChecksum() { return BLT_TRUE; } blt_bool FlashVerifyChecksum() { // Naive check: if the first block is blank, there's no code there if (intFlashIsErased(FlashGetUserProgBaseAddress(), 4)) { return BLT_FALSE; } static const size_t checksumOffset = 0x1C; // Now do the actual CRC check to ensure we didn't get stuck with a half-written firmware image uint8_t* start = reinterpret_cast(FlashGetUserProgBaseAddress()); size_t imageSize = *reinterpret_cast(start + checksumOffset + 4); if (imageSize > 1024 * 1024) { // impossibly large size, invalid return BLT_FALSE; } // part before checksum+size uint32_t calcChecksum = crc32(start, checksumOffset); // part after checksum+size calcChecksum = crc32inc(start + checksumOffset + 4, calcChecksum, imageSize - (checksumOffset + 4)); uint32_t storedChecksum = *reinterpret_cast(start + checksumOffset); return calcChecksum == storedChecksum ? BLT_TRUE : BLT_FALSE; } blt_bool isFlashDualBank(void) { #ifdef STM32F7XX // cleared bit indicates dual bank return (FLASH->OPTCR & FLASH_OPTCR_nDBANK) == 0 ? BLT_TRUE : BLT_FALSE; #else return BLT_TRUE; #endif }