尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

eCos flash模拟EEPROM实现NV系统

发布时间:2026/9/24 10:53:02

资讯中心
01
ARTICLE

eCos flash模拟EEPROM实现NV系统

eCos flash模拟EEPROM实现NV系统
Flash需要擦除的原因先擦除后写入的原因是为了工业上制作方便即物理实现方便。#include cyg/infra/diag.h#include cyg/io/flash.h#include stdarg.h#include stdio.h#include stdlib.h// SPI flash size 4 MBstatic 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.cstatic 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 datastatus 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 datastatus 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 datastatus cyg_flash_program(flash_base flash_offset 2,e2prom_buf 2, 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%x\n, ((unsigned int*)e2prom_buf)[0]);if (((unsigned int *)e2prom_buf)[0] 0xaaaa5555) {oem_printf([OEM] i: %d, logical_e2prom_cur_idx: %d\n, 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%x\n, 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: 512Boem_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 - 320Koem_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 writeoem_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 Bytes\n, get_nvm_size());///////////////////////////// Initializing the FLASH librarycyg_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 1nr_logical_e2prom blk_sz / e2prom_sz;oem_printf([OEM] nr_logical_e2prom: %d\n, nr_logical_e2prom);oem_printf([OEM] start_addr: 0x%x, end_addr: 0x%x, num_block_infos: %d, block_size: %d, blocks: %d\n,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, e2prom_buf, e2prom_sz, 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: %d\n,__func__, logical_e2prom_cur_idx);break;}}oem_printf([OEM][%s] before chng, logical e2prom idx: %d\n,__func__, logical_e2prom_cur_idx);if (logical_e2prom_cur_idx nr_logical_e2prom) {cyg_flash_erase(flash_base, blk_sz, 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: %d\n, __func__, id, nv_sz,logical_e2prom_cur_idx);return nv_sz;err:cyg_mutex_unlock(nv_mutex);return -1;}API int nv_write(nv_items_enum_t id, u8 *buf, int len){unsigned char magic[] {0x55, 0x55, 0xaa, 0xaa};cyg_flashaddr_t err_addr;// flash_base is where in the flash to write 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, e2prom_buf, e2prom_sz, err_addr);if (status ! CYG_FLASH_ERR_OK) {oem_printf([OEM][%s] flash read err!!\n, __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 hereif (0 logical_e2prom_cur_idx) {status cyg_flash_read(flash_base, buf, 4, err_addr);if (status ! CYG_FLASH_ERR_OK) {oem_printf([OEM][%s] Oops here, check it manually\n, __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 index\n, __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, blk_sz, err_addr);}if (program_data() 0) {goto err;}cyg_mutex_unlock(nv_mutex);return nv_sz;#endiferr: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, so check hereif (0 logical_e2prom_cur_idx) {status cyg_flash_read(flash_base, buf, 4, err_addr);if (status ! CYG_FLASH_ERR_OK) {oem_printf([OEM][%s] Oops here, check it manually\n, __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 index\n, __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, logical_e2prom_cur_idx: %d\n,__func__, logical_e2prom_cur_idx);logical_e2prom_cur_idx 0;cyg_flash_erase(flash_base, blk_sz, err_addr);}// 3M 0x300000// spi rd 300000 64// spi wr 300000 55 55 aa aa// spi er 300000 65536if (program_data() 0) {goto err;}cyg_mutex_unlock(nv_mutex);oem_printf([OEM][%s] succeeded in updating logical_e2prom_cur_idx: %d\n,__func__, logical_e2prom_cur_idx);return 0;err:cyg_mutex_unlock(nv_mutex);return -1;}#elseAPI int nv_commit(void){return 0;}#endif
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。