#include #include "nv_storage.h" #include "bsp/AT24CXX.h" #include "app/sox/soc.h" #include "libs/logger.h" #include "libs/shark_utils.h" #if 0 static void backup_timer_hander(shark_timer_t *timer); static void nv_save_soc_by_backup(int index); #endif static void nv_save_soc_task(shark_timer_t *timer); #define SOC_ADDR 0 static shark_timer_t _save_backup_timer = {.handler = nv_save_soc_task}; #define SOC_SIZE (((sizeof(soc_t) + sizeof(uint16_t)) + 0xF)&(0xFFF0)) //需要16字节对齐 #define SN_ADDR (SOC_ADDR + (SOC_SIZE * 2)) static uint8_t soc_write_pending = 0; static uint8_t soc_write_backup_index = 0; static uint8_t soc_write_index = 0; static uint8_t soc_data[(sizeof(soc_t) + sizeof(uint16_t))]; int nv_read_write_test(void){ uint8_t data[32]; memset(data, 0x5a, sizeof(data)); AT24CXX_Write(0, data, sizeof(data)); memset(data, 0x0, sizeof(data)); AT24CXX_Read(0, data, sizeof(data)); for (int i = 0; i < sizeof(data); i++){ if (data[i] != 0x5a) { return 0; } } return 1; } int nv_save_sn(uint8_t *sn, int len){ sn_t sn_info; if (len > sizeof(sn_info.sn)){ return -1; } memcpy(sn_info.sn, sn, len); sn_info.len = len; sn_info.crc = shark_crc16_update(0, (const u8 *)sn_info.sn, len); return AT24CXX_Write(SN_ADDR, (uint8_t *)&sn_info, sizeof(sn_info)); } int nv_read_sn(uint8_t *sn, int len){ sn_t sn_info; if (len < sizeof(sn_info.sn)){ return -1; } if (AT24CXX_Read(SN_ADDR, (uint8_t *)&sn_info, sizeof(sn_info)) < 0) { return -1; } if (sn_info.len > sizeof(sn_info.sn)){ return -1; } uint16_t crc = shark_crc16_update(0, (const u8 *)sn_info.sn, sn_info.len); if (crc != sn_info.crc){ return -1; } memcpy(sn, sn_info.sn, sn_info.len); return sn_info.len; } /* soc 保存,拆分每次保存一个byte,确保e2rom写操作不会占用太长时间 */ void nv_save_soc(void){ #if 0 nv_save_soc_by_backup(0); shark_timer_post(&_save_backup_timer, 10); #else if (soc_write_pending == 0){ soc_write_pending = 1; memcpy(soc_data, (void *)get_soc(), sizeof(soc_t)); soc_write_backup_index = 0; soc_write_index = 0; uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc_data, sizeof(soc_t)); shark_encode_u16(soc_data + sizeof(soc_t), crc16); shark_timer_post(&_save_backup_timer, 0); } #endif } static void nv_save_soc_task(shark_timer_t *timer){ if (soc_write_pending == 0) { return; } if (soc_write_index < sizeof(soc_data)){ AT24CXX_Write(SOC_ADDR + SOC_SIZE * soc_write_backup_index + soc_write_index, soc_data + soc_write_index, 1); soc_write_index ++; }else { soc_write_index = 0; soc_write_backup_index ++; if (soc_write_backup_index == 2){ soc_write_pending = 0; sys_debug("write soc to nv OK\n"); return; } } shark_timer_post(&_save_backup_timer, 0); } #if 0 static void backup_timer_hander(shark_timer_t *timer){ nv_save_soc_by_backup(1); } #endif static void nv_save_soc_by_backup(int index){ uint16_t nv_addr = SOC_ADDR + SOC_SIZE * index; soc_t *soc = get_soc(); uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t)); AT24CXX_Write(nv_addr ,(uint8_t *)soc, sizeof(soc_t)); AT24CXX_Write(nv_addr + sizeof(soc_t),(uint8_t *)&crc16, sizeof(crc16)); } void nv_erase(void){ uint8_t data = 0xFF; for (int i = 0; i < sizeof(soc_t) + sizeof(uint16_t); i++){ AT24CXX_Write(SOC_ADDR + i, &data, 1); } for (int i = 0; i < sizeof(soc_t) + sizeof(uint16_t); i++){ AT24CXX_Write(SOC_ADDR + SOC_SIZE + i, &data, 1); } } int nv_restore_soc_by_backup(int index, soc_t *soc){ uint16_t crc_nv; uint16_t nv_addr = SOC_ADDR + SOC_SIZE * index; AT24CXX_Read(nv_addr , (uint8_t *)soc, sizeof(soc_t)); AT24CXX_Read(nv_addr + sizeof(soc_t), (uint8_t *)&crc_nv, sizeof(crc_nv)); if (shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t)) != crc_nv){ return -1; } return 0; } int nv_restore_soc(void){ soc_t soc0, soc1; int success0, success1; success0 = nv_restore_soc_by_backup(0, &soc0); success1 = nv_restore_soc_by_backup(1, &soc1); if (success0 == 0 || success1 == 0){ if (success1 != 0){ nv_save_soc_by_backup(1); } if (success0 != 0){ nv_save_soc_by_backup(0); } if (success0 == 0){ *get_soc() = soc0; }else if (success1 == 0){ *get_soc() = soc1; } } return ((success0 == 0) || (success1 == 0))?0:-1; }