加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

eCos flash模拟EEPROM读写NV

发布时间:2020-12-15 19:54:48 所属栏目:百科 来源:网络整理
导读:Flash需要擦除的原因: 先擦除后写入的原因是为了工业上制作方便,即物理实现方便。 #include cyg/infra/diag.h #include cyg/io/flash.h #include stdarg.h #include stdio.h #include stdlib.h // SPI flash size = 4 MB static bool init = false; static

Flash需要擦除的原因:先擦除后写入的原因是为了工业上制作方便,即物理实现方便。

#include <cyg/infra/diag.h>

#include <cyg/io/flash.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

// SPI flash size = 4 MB static bool init = false; static cyg_mutex_t nv_mutex; static unsigned char *e2prom_buf = NULL; static unsigned long e2prom_sz = SZ_2K; static unsigned long logical_e2prom_cur_idx = 0; static unsigned long nr_logical_e2prom = 1; static unsigned long blk_sz = SZ_64K; #include "oem-nv-lib.c" static int program_data(void) { ?? ?cyg_flashaddr_t err_addr; ?? ?cyg_flashaddr_t flash_base = NV_FLASH_BYTES_ADDR; ?? ?int status; ??? unsigned long flash_offset; ??? flash_offset = logical_e2prom_cur_idx * e2prom_sz; ??? oem_printf("[OEM][%s] logical_e2prom_cur_idx: %d,flash_offset: 0x%x(%dK)n",??????????? __func__,logical_e2prom_cur_idx,flash_offset,(flash_offset/SZ_1K)); ??? // 1) Mark we will program data ??? status = cyg_flash_program(flash_base + flash_offset,??????????? e2prom_buf,2,&err_addr); ??? if (status != CYG_FLASH_ERR_OK) { ??????? oem_printf("[OEM][%s] 1) flash program err!!n",__func__); ??????? goto err; ??? } ??? // 2) Programming data ??? status = cyg_flash_program(flash_base + flash_offset + SZ_E2PROM_HDR,??????????? e2prom_buf + SZ_E2PROM_HDR,e2prom_sz - SZ_E2PROM_HDR,&err_addr); ??? if (status != CYG_FLASH_ERR_OK) { ??????? oem_printf("[OEM][%s] 2) flash program err!!n",__func__); ??????? goto err; ??? } ??? // 3) Mark we have completed programming data ??? status = cyg_flash_program(flash_base + flash_offset + 2,??????????? e2prom_buf + 2,&err_addr); ??? if (status != CYG_FLASH_ERR_OK) { ??????? oem_printf("[OEM][%s] 3) flash program err!!n",__func__); ??????? goto err; ??? } ??? return 0; err: ??? // TODO: ??? return -1; } static int recovery_of_sudden_power_cut(void) { ?? ?cyg_flashaddr_t err_addr; ?? ?cyg_flashaddr_t flash_base = NV_FLASH_BYTES_ADDR; ??? int i; ?? ?int status; ??? unsigned long flash_offset; ??? for (i = logical_e2prom_cur_idx; i > 0; i--) { ??????? flash_offset = i * e2prom_sz; ??????? status = cyg_flash_read(flash_base + flash_offset,e2prom_buf,e2prom_sz,&err_addr); ??????? if (status != CYG_FLASH_ERR_OK) { ??????????? oem_printf("[OEM][%s] flash read err!!n",__func__); ??????????? goto err; ??????? } ??????? // little endian ??????? //oem_printf("magic: 0x%xn",((unsigned int*)e2prom_buf)[0]); ??????? if (((unsigned int *)e2prom_buf)[0] == 0xaaaa5555) { ??????????? oem_printf("[OEM] i: %d,logical_e2prom_cur_idx: %dn",i,logical_e2prom_cur_idx); ??????????? break; ??????? } ??? } ??? if (i != logical_e2prom_cur_idx) { ??????? oem_printf("[OEM][%s] call cyg_flash_erase()n",__func__); ??????? cyg_flash_erase(flash_base,blk_sz,&err_addr); ??????? logical_e2prom_cur_idx = 0; ??????? if (program_data() < 0) { ??????????? goto err; ??????? } ??? } ??? return 0; err: ??? return -1; } static void show_flash_ptn(void) { ??? // uboot ??? // offset: 0,size: 192K ??? // for CFG_set & CFG_get(User config,Switch parameter) ??? // Bottom-Boot flsh_cfg_off: 16K,flsh_cfg_sz: 20K ??? // Top-Boot flsh_cfg_off: 4M - 20K,flsh_cfg_sz: 20K ??? // !!No-Boot flsh_cfg_off: 196K(0x31000),flsh_cfg_sz: 20K ??? //oem_printf("[OEM] flsh_cfg_off: 0x%x,flsh_cfg_sz: 0x%xn",flsh_cfg_off,flsh_cfg_sz); ??? // for emulating eeprom to save MAC ADDR(RF parameter) ??? // Bottom-Boot flsh_cfg_boot_off: 12K ??? // Top-Boot flsh_cfg_boot_off: 60K ??? // !!No-Boot flsh_cfg_boot_off: 256K(0x40000),size: 512B ??? oem_printf("[OEM] flsh_cfg_boot_off: 0x%x(%dK)n",flsh_cfg_boot_off,??????? (flsh_cfg_boot_off/SZ_1K)); ??? // for eCos firmware and size ??? // Bottom-Boot flsh_cfg_fwm_off: 64K,flsh_cfg_fwm_sz: 4M - 64K ??? // Top-Boot flsh_cfg_fwm_off: 64K,flsh_cfg_sz: 4M - 64K - 20K ??? // !!No-Boot flsh_cfg_fwm_off: 320K(0x50000),flsh_cfg_sz: 4M - 320K ??? oem_printf("[OEM] flsh_cfg_fwm_off: 0x%x(%dK),flsh_cfg_fwm_sz: 0x%x(%dK)n",??????????? flsh_cfg_fwm_off,(flsh_cfg_fwm_off/SZ_1K),??????????? flsh_cfg_fwm_sz,(flsh_cfg_fwm_sz/SZ_1K)); ??? // for OEM NV read & write ??? oem_printf("[OEM] flsh_nv_off: 0x%x(%dK)n",NV_FLASH_BYTES_ADDR,??????????? NV_FLASH_BYTES_ADDR/SZ_1K); } API int nv_init(void) { ??? cyg_flash_info_t cfi; ?? ?cyg_flashaddr_t err_addr; ?? ?cyg_flashaddr_t flash_base = NV_FLASH_BYTES_ADDR; ?? ?int status; ??? unsigned long flash_offset; ??? /////////////////////////// ??? show_flash_ptn(); ??? oem_printf("[OEM] nv memory used size: %d Bytesn",get_nvm_size()); ??? /////////////////////////// ??? // Initializing the FLASH library ??? cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf); ??? cyg_flash_init(NULL); ??? if (cyg_flash_get_info(0,&cfi) == CYG_FLASH_ERR_OK) { ??????? if (cfi.block_info) { ??????????? blk_sz = cfi.block_info->block_size; ??????????? // nr_logical_e2prom should be >= 1 ??????????? nr_logical_e2prom = blk_sz / e2prom_sz; ??????????? oem_printf("[OEM] nr_logical_e2prom: %dn",nr_logical_e2prom); ??????????? oem_printf("[OEM] start_addr: 0x%x,end_addr: 0x%x,num_block_infos: %d," ??????????????????? "block_size: %d,blocks: %dn",??????????????????? cfi.start,cfi.end,cfi.num_block_infos,??????????????????? cfi.block_info->block_size,cfi.block_info->blocks); ??????????? if (!e2prom_buf) { ??????????????? e2prom_buf = (unsigned char *)malloc(e2prom_sz); ??????????????? if (!e2prom_buf) { ??????????????????? oem_printf("[OEM][%s] Can not allocate memory for e2prom_buf!!n",__func__); ??????????????????? goto err; ??????????????? } ??????????? } ??????????? for (logical_e2prom_cur_idx = 0; logical_e2prom_cur_idx < nr_logical_e2prom; ??????????????????? logical_e2prom_cur_idx++) { ??????????????? flash_offset = logical_e2prom_cur_idx * e2prom_sz; ??????????????? status = cyg_flash_read(flash_base + flash_offset,&err_addr); ??????????????? if (status != CYG_FLASH_ERR_OK) { ??????????????????? logical_e2prom_cur_idx = 0; ??????????????????? oem_printf("[OEM][%s] flash read err!!n",__func__); ??????????????????? goto err; ??????????????? } ??????????????? if (e2prom_buf[0] == 0xff && ??????????????????? e2prom_buf[1] == 0xff && ??????????????????? e2prom_buf[2] == 0xff && ??????????????????? e2prom_buf[3] == 0xff) { ??????????????????? oem_printf("[OEM][%s] Got a free logical e2prom idx: %dn",??????????????????????? __func__,logical_e2prom_cur_idx); ??????????????????? break; ??????????????? } ??????????? } ??????????? oem_printf("[OEM][%s] before chng,logical e2prom idx: %dn",??????????????????? __func__,logical_e2prom_cur_idx); ??????????? if (logical_e2prom_cur_idx == nr_logical_e2prom) { ??????????????? cyg_flash_erase(flash_base,&err_addr); ??????????????? logical_e2prom_cur_idx = 0; ??????????????? if (program_data() < 0) { ??????????????????? goto err; ??????????????? } ??????????? } else if (logical_e2prom_cur_idx > 0 && logical_e2prom_cur_idx < nr_logical_e2prom) { ??????????????? logical_e2prom_cur_idx--; ??????????? } ??????????? if (recovery_of_sudden_power_cut() < 0) { ??????????????? goto err; ??????????? } ??????????? init = true; ??????? } ??? } ??? cyg_mutex_init(&nv_mutex); ??? return 0; err: ??? return -1; } API int nv_read(nv_items_enum_t id,u8 *buf,int len) { ?? ?cyg_flashaddr_t err_addr; ??? // flash_base is where in the flash to read from,it is a byte address,??? // not sector address. ?? ?cyg_flashaddr_t flash_base = NV_FLASH_BYTES_ADDR; ?? ?int status; ??? unsigned long flash_offset = 0; ??? long nv_offset = NV_OFFSET(id); ??? unsigned long nv_sz = NV_SZ(id); ??? cyg_mutex_lock(&nv_mutex); ??? if (!init) { ??????? if (false == nv_init()) { ??????????? goto err; ??????? } ??? } ??? if (nv_offset < 0) { ??????? goto err; ??? } ??? if (nv_sz > len) { ??????? nv_sz = len; ??? } ??? flash_offset = logical_e2prom_cur_idx * e2prom_sz; ?? ?status = cyg_flash_read(flash_base + flash_offset + nv_offset,(void *)buf,nv_sz,&err_addr); ?? ?if (status != CYG_FLASH_ERR_OK) { ?? ??? ?oem_printf("[OEM][%s] flash read err!!n",__func__); ??????? goto err; ?? ?} ??? cyg_mutex_unlock(&nv_mutex); ??? oem_printf("[OEM][%s] succeeded in reading nv_%d,nv_sz: %d Bytes " ??????????? "@logical_e2prom_cur_idx: %dn",__func__,id,??????????? logical_e2prom_cur_idx); ?? ?return nv_sz; err: ??? cyg_mutex_unlock(&nv_mutex); ??? return -1; } API int nv_write(nv_items_enum_t id,int len) { ??? unsigned char magic[] = {0x55,0x55,0xaa,0xaa}; ?? ?cyg_flashaddr_t err_addr; ??? // flash_base is where in the flash to write from,??? // not sector address. ?? ?cyg_flashaddr_t flash_base = NV_FLASH_BYTES_ADDR; ?? ?int status; ??? unsigned long flash_offset = 0; ??? long nv_offset = NV_OFFSET(id); ??? unsigned long nv_sz = NV_SZ(id); ??? cyg_mutex_lock(&nv_mutex); ??? if (!init) { ??????? if (false == nv_init()) { ??????????? goto err; ??????? } ??? } ??? if (nv_offset < 0) { ??????? goto err; ??? } ??? if (nv_sz > len) { ??????? nv_sz = len; ??? } ??? flash_offset = logical_e2prom_cur_idx * e2prom_sz; ?? ?status = cyg_flash_read(flash_base + flash_offset,__func__); ?? ??? ?goto err; ?? ?} ??? memcpy(e2prom_buf,magic,sizeof(magic)); ??? memcpy(e2prom_buf + nv_offset,buf,nv_sz); #if defined(BATCH_COMMIT) ??? cyg_mutex_unlock(&nv_mutex); ??? return nv_sz; #else ??? // No any data in e2prom,so check here ??? if (0 == logical_e2prom_cur_idx) { ??????? status = cyg_flash_read(flash_base,4,&err_addr); ??????? if (status != CYG_FLASH_ERR_OK) { ??????????? oem_printf("[OEM][%s] Oops here,check it manuallyn",__func__); ??????? } else if (CYG_FLASH_ERR_OK == status && buf[0] == 0xff && ??????????????? buf[1] == 0xff && ??????????????? buf[2] == 0xff && ??????????????? buf[3] == 0xff) { ??????????? oem_printf("[OEM][%s] do not add e2prom cur indexn",__func__); ??????? } else { ??????????? logical_e2prom_cur_idx++; ??????? } ??? } else { ??????? logical_e2prom_cur_idx++; ??? } ??? if (logical_e2prom_cur_idx >= nr_logical_e2prom) { ??????? logical_e2prom_cur_idx = 0; ??????? cyg_flash_erase(flash_base,&err_addr); ??? } ??? if (program_data() < 0) { ??????? goto err; ??? } ??? cyg_mutex_unlock(&nv_mutex); ?? ?return nv_sz; #endif err: ??? cyg_mutex_unlock(&nv_mutex); ??? return -1; } #if defined(BATCH_COMMIT) API int nv_commit(void) { ?? ?cyg_flashaddr_t err_addr; ?? ?cyg_flashaddr_t flash_base = NV_FLASH_BYTES_ADDR; ?? ?int status; ??? u8 buf[4]; ??? cyg_mutex_lock(&nv_mutex); ??? // No any data in e2prom,__func__); ??????? } else { ??????????? logical_e2prom_cur_idx++; ??????? } ??? } else { ??????? logical_e2prom_cur_idx++; ??? } ??? if (logical_e2prom_cur_idx >= nr_logical_e2prom) { ??????? oem_printf("[OEM][%s] need erase block,??????????????? __func__,logical_e2prom_cur_idx); ??????? logical_e2prom_cur_idx = 0; ??????? cyg_flash_erase(flash_base,&err_addr); ??? } ??? // 3M = 0x300000 ??? // spi rd 300000 64 ??? // spi wr 300000 55 55 aa aa ??? // spi er 300000 65536 ??? if (program_data() < 0) { ??????? goto err; ??? } ??? cyg_mutex_unlock(&nv_mutex); ??? oem_printf("[OEM][%s] succeeded in updating logical_e2prom_cur_idx: %dn",logical_e2prom_cur_idx); ??? return 0; err: ??? cyg_mutex_unlock(&nv_mutex); ??? return -1; } #else API int nv_commit(void) { ??? return 0; } #endif

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读