WXK
2025-02-05 961c1174bbf1aaae5fa2f672806ed4eaf2f917be
01_SDK/nimble/mcu_boot/src/flash_manager.c
@@ -1,117 +1,119 @@
/*
 * Copyright (c) 2020-2021 Shanghai Panchip Microelectronics Co.,Ltd.
 * Copyright (c) 2020-2025 Shanghai Panchip Microelectronics Co.,Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include "soc_api.h"
#include "app_log.h"
#include "flash_manager.h"
static uint32_t m_erased_area;
void fm_status_refresh(void)
{
   m_erased_area = FLASH_AREA_IMAGE_START;
    m_erased_area = FLASH_AREA_IMAGE_START;
}
void fm_write_flash(unsigned int addr, unsigned char *buf, unsigned int len)
{
   if ((addr + len) <= m_erased_area) { /* means the specified flash has be erased before */
      FMC_WriteStream(FLCTL, addr, buf, len); /* todo chao*/
   } else {
      if (FMC_EraseSector(FLCTL, m_erased_area) == 0) {
         m_erased_area += SECTOR_SIZE;
         FMC_WriteStream(FLCTL, addr, buf, len);
      } else {
         ASSERT;
      }
   }
{
    if ((addr + len) <= m_erased_area) { /* means the specified flash has be erased before */
        FMC_WriteStream(FLCTL, addr, buf, len); /* todo chao*/
    } else {
        if (FMC_EraseSector(FLCTL, m_erased_area) == 0) {
            m_erased_area += SECTOR_SIZE;
            FMC_WriteStream(FLCTL, addr, buf, len);
        } else {
            // Error occurs
            while (1);
        }
    }
}
int fm_read_flash(unsigned int addr, unsigned char *buf, unsigned int len)
{
   return FMC_ReadStream(FLCTL, addr, CMD_FAST_READ, buf, len);
    return FMC_ReadStream(FLCTL, addr, CMD_DREAD, buf, len);
}
static void check_sum_add(uint32_t *init_val, uint8_t *val, uint16_t len)
{
   for (uint16_t i =0 ; i < len; i++) {
      *init_val += *(val + i);
   }
    for (uint16_t i =0 ; i < len; i++) {
        *init_val += *(val + i);
    }
}
int fm_image_make_invalid(uint32_t im_addr)
{
   return FMC_EraseSector(FLCTL, im_addr);
    return FMC_EraseSector(FLCTL, im_addr);
}
static uint8_t read_value[256];
void fm_image_move(uint32_t src_addr, uint32_t dst_addr)
{
   uint32_t current_index = 0;
   image_header_t header;
   /* fm write to image area, should handle one time fm_status_refresh */
   fm_status_refresh();
   /* move header */
   fm_read_flash(src_addr, (unsigned char *)&header, sizeof(image_header_t));
   fm_write_flash(dst_addr, (unsigned char *)&header, sizeof(image_header_t));
   src_addr += sizeof(image_header_t);
   dst_addr += sizeof(image_header_t);
   header.ih_img_size += 40; /*smp signed related*/
   /* move completed image*/
   while(current_index < header.ih_img_size) {
      if (current_index + 256 <= header.ih_img_size){ /* remaining packets over than 256 bytes */
         fm_read_flash(src_addr + current_index, read_value, 256);
         fm_write_flash(dst_addr+ current_index, read_value, 256);
         current_index += 256;
      }
      else {
         fm_read_flash(src_addr + current_index, read_value, header.ih_img_size - current_index); /* remaining packets less than 256 bytes */
         fm_write_flash(dst_addr+ current_index, read_value, header.ih_img_size - current_index);
         current_index = header.ih_img_size;
      }
   }
   /* escape move at next time, should be make it invalid */
   fm_image_make_invalid(src_addr);
    uint32_t current_index = 0;
    image_header_t header;
    /* fm write to image area, should handle one time fm_status_refresh */
    fm_status_refresh();
    /* move header */
    fm_read_flash(src_addr, (unsigned char *)&header, sizeof(image_header_t));
    fm_write_flash(dst_addr, (unsigned char *)&header, sizeof(image_header_t));
    src_addr += sizeof(image_header_t);
    dst_addr += sizeof(image_header_t);
    header.ih_img_size += 40; /*smp signed related*/
    /* move completed image*/
    while(current_index < header.ih_img_size) {
        if (current_index + 256 <= header.ih_img_size){ /* remaining packets over than 256 bytes */
            fm_read_flash(src_addr + current_index, read_value, 256);
            fm_write_flash(dst_addr+ current_index, read_value, 256);
            current_index += 256;
        }
        else {
            fm_read_flash(src_addr + current_index, read_value, header.ih_img_size - current_index); /* remaining packets less than 256 bytes */
            fm_write_flash(dst_addr+ current_index, read_value, header.ih_img_size - current_index);
            current_index = header.ih_img_size;
        }
    }
    /* escape move at next time, should be make it invalid */
    fm_image_make_invalid(src_addr);
}
bool fm_image_completed_check(uint32_t im_addr)
{
   uint32_t check_sum = 0;
   uint32_t current_index = 0;
   image_header_t header;
   fm_read_flash(im_addr, (unsigned char *)&header, sizeof(image_header_t));
   if (header.ih_img_size > FLASH_IMAGE_MAX_SIZE  || header.ih_img_size <= 256) /* image size should be obtained a basic rules */
      return false;
   im_addr += sizeof(image_header_t);
   while(current_index < header.ih_img_size) {
      if (current_index + 256 <= header.ih_img_size){ /* remaining packets over than 256 bytes */
         fm_read_flash(im_addr + current_index, read_value, 256);
         current_index += 256;
         check_sum_add(&check_sum, read_value, 256);
      }
      else {
         fm_read_flash(im_addr + current_index, read_value, header.ih_img_size - current_index); /* remaining packets less than 256 bytes */
         check_sum_add(&check_sum, read_value, header.ih_img_size - current_index);
         current_index = header.ih_img_size;
      }
   }
   if (header.checksum == check_sum) {
      return true;
   } else
      return false;
    uint32_t check_sum = 0;
    uint32_t current_index = 0;
    image_header_t header;
    fm_read_flash(im_addr, (unsigned char *)&header, sizeof(image_header_t));
    if (header.ih_img_size > FLASH_IMAGE_MAX_SIZE  || header.ih_img_size <= 256) /* image size should be obtained a basic rules */
        return false;
    im_addr += sizeof(image_header_t);
    while(current_index < header.ih_img_size) {
        if (current_index + 256 <= header.ih_img_size){ /* remaining packets over than 256 bytes */
            fm_read_flash(im_addr + current_index, read_value, 256);
            current_index += 256;
            check_sum_add(&check_sum, read_value, 256);
        }
        else {
            fm_read_flash(im_addr + current_index, read_value, header.ih_img_size - current_index); /* remaining packets less than 256 bytes */
            check_sum_add(&check_sum, read_value, header.ih_img_size - current_index);
            current_index = header.ih_img_size;
        }
    }
    if (header.checksum == check_sum) {
        return true;
    } else
        return false;
}
#if false
#if 0
const uint8_t flash_image[] = {
0x1, 0x2, 0x3, 0x4,
0x1, 0x1, 0x0, 0x0,
@@ -142,17 +144,16 @@
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
};
void t_fm_image_completed_check_test(void)
{
   bool ret;
   ret = fm_image_completed_check((uint32_t)flash_image);
   if (ret) {
      while(1);
   }
    bool ret;
    ret = fm_image_completed_check((uint32_t)flash_image);
    if (ret) {
        while(1);
    }
}
#endif