Flash均衡读写


#define
FLASH_INITIAL_BYTE 0xff

  #define PAGE_NUM_PER_CONFIG              2
  #define CONFIG_FLASH_PAGE_START          508

#define   CONFIG_BUF_SIZE                  sizeof(CFG_CHARGE_ST)/2
#define   CONFIG_FLASH_ADDRESS_START       (FLASH_START_ADDR + PAGE_SIZE * CONFIG_FLASH_PAGE_START) 

static void  _config_default_get(CFG_CHARGE_ST  *p_cfg) {        
    memset((uint8_t*)p_cfg, 0, sizeof(CFG_CHARGE_ST));
    p_cfg->valid        =  CONFIG_VALID_FLAG;                                                             
    p_cfg->charge_curr  =  DEFAULT_CHARGE_CURRENT_MAX;             
    return;
}


//read backward ,last page, last row,  iterate until get the first valid flag
//parameter of len is measure in word, while pos is measure in byte ,so when calculate pos,
// should multiply 2 to get the right pos.
static uint8_t flash_page_read(uint32_t  page_start_addr, uint16_t *p_data, uint16_t len, uint16_t page_leftover){

   uint16_t  cnt = (PAGE_SIZE - page_leftover) / len;
   uint16_t  i = 0;
   uint32_t  pos = 0;
   uint8_t   page = 0;
   uint32_t  page_addr = 0;
   uint8_t   *p_read_byte = NULL;

   cnt /= 2;

   for(page = PAGE_NUM_PER_CONFIG; page > 0; page--){

       page_addr = page_start_addr + (page - 1) * PAGE_SIZE;

       for(i = cnt; i > 0; i--){

          pos = page_addr + (i - 1) * len * 2 + page_leftover;
         
          flash_read(pos, p_data, len); 

          p_read_byte = (uint8_t*)p_data;

          if (p_read_byte[0] == CONFIG_VALID_FLAG){
             
             //cm_printf("flash read 0x%x, p %02x, %d\n", pos, page_addr, i); 
             return true;
          }
       }
   }

   return false;
}


//write forward, from the first page, first row ,iterate until get the first initial byte 
// if not found ,earse the two page, and write from the very beginning
static void  flash_page_write(uint32_t page_start_addr, uint16_t *p_data, uint16_t len, uint16_t page_leftover){

   uint16_t  cnt = (PAGE_SIZE - page_leftover) / len;
   uint8_t   page = 0;
   uint32_t  page_addr = 0;
   uint32_t  pos = 0;
   uint16_t  i = 0;
   uint8_t  read_buf[2] = {0};

   cnt /= 2;

   for(page = 0; page < PAGE_NUM_PER_CONFIG; page++){

      page_addr = page_start_addr + page * PAGE_SIZE;

      for(i = 0; i < cnt; i++){

          pos = page_addr + i * len * 2;
          pos += page_leftover;

          //cm_printf("pos %02x, leftover %02x\n", pos, page_leftover);
          
          flash_read(pos, (uint16_t*)read_buf, 1); 

          if (read_buf[0] == FLASH_INITIAL_BYTE &&
              read_buf[1] == FLASH_INITIAL_BYTE){                       
              
              FLASH_Write_in_ISR(pos, p_data, len);
          
              return;
          }
       }
   }

   FLASH_Page_Erase_direct(page_start_addr);

   FLASH_Page_Erase_direct(page_start_addr + PAGE_SIZE * 1);
   
   FLASH_Write_in_ISR(page_start_addr + page_leftover, p_data, len);
}


static void  config_init(void){
                                
    CFG_CHARGE_ST  cfg_st;
    CFG_CHARGE_ST  *p_cfg;
    uint16_t   ps_buf[CONFIG_BUF_SIZE] = {0};
                        
    flash_page_read(CONFIG_FLASH_ADDRESS_START, ps_buf, CONFIG_BUF_SIZE, 0);
    p_cfg = (CFG_CHARGE_ST*)ps_buf;      
    
    if (p_cfg->valid != CONFIG_VALID_FLAG){
            
        _config_default_get(&cfg_st);
        
        p_cfg = &cfg_st;                     
    } 
          
    memcpy(&g_config_st, p_cfg, sizeof(CFG_CHARGE_ST));        
                                      
    return;    
}


static void  config_save_act(void){

    CFG_CHARGE_ST  *p_cfg;
    
    uint16_t page_leftover = PAGE_SIZE % (sizeof(CFG_CHARGE_ST));
        
    p_cfg = &g_config_st;
    
    flash_page_write(CONFIG_FLASH_ADDRESS_START, (uint16_t*)p_cfg, CONFIG_BUF_SIZE, page_leftover);
 
    return;
}

         Flash均衡读写,每次写配置时,从页面的开始地址,找到一个空的位置写入,当整个页面都已写完时,再擦除一次页面,

         从页面最开始地址写入。读取配置时,从页面的最后面的地址开始向前查找到第一个有效标识位。

        此外,flash执行写入操作时,除了unlock/lock,还需要__disable_irq()  ,   __enable_irq();  关闭中断,写完后再开启中断。

    

posted on 2024-06-23 19:19  wallywl  阅读(56)  评论(0)    收藏  举报