首页/新闻资讯/正文详情

eCos flash模拟EEPROM实现NV系统

发布时间:2026/9/24 10:53:00 来源:云帆数科 栏目:资讯中心
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

相关推荐

基于脑电信号深度迁移学习的驾驶疲劳检测:从电极-频率分布图到残差CNN的完整技术路线
基于脑电信号深度迁移学习的驾驶疲劳检测:从电极-频率分布图到残差CNN的完整技术路线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:52:47

四路CAN FD+LTE云调试:汽车电子逆向移动工作站
四路CAN FD+LTE云调试:汽车电子逆向移动工作站

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 10:52:41

焕新版特斯拉ModelY音响升级推荐:森索姆14单元方案
焕新版特斯拉ModelY音响升级推荐:森索姆14单元方案

面向焕新版特斯拉 Model Y 后轮驱动版(原车 9 扬声器)的原厂音响升级方案解析先给结论:焕新版特斯拉 Model Y 后驱版的原车音响,短板集中在三处——没有独立功放、后备箱没有超低音炮、原车中低音在大音量下容易破音。森索姆&… · 2026/9/24 10:52:35

职场沟通技巧:如何应对棘手的对话
职场沟通技巧:如何应对棘手的对话

科技行业归根结底离不开人与人之间的协作,而要把工作做好,就需要持续沟通。从日常交流到重要讨论,大大小小的对话贯穿我们的工作,帮助我们携手解决问题、取得成果。可如果对话并不顺利呢?如果一场谈话让你心跳加速、脸… · 2026/9/24 12:03:46

TC3xx SWAP机制详解:SOTA升级与ECU回滚的可靠实现
TC3xx SWAP机制详解:SOTA升级与ECU回滚的可靠实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 12:03:34

以 DESIGN.md 为入口构建 Agent 可读的持久化设计决策体系:learn-harness-engineering 仓库模板实战
以 DESIGN.md 为入口构建 Agent 可读的持久化设计决策体系:learn-harness-engineering 仓库模板实战

【免费下载链接】learn-harness-engineering Harness engineering beginner tutorial, from 0 to 1 项目地址: https://gitcode.com/gh_mirrors/le/learn-harness-engineering 点击查看 免费下载 导读 本指南聚焦 learn-harness-engineering 仓库中 repo-template… · 2026/9/24 12:03:21

Yii 2 RESTful API 快速上手:从零搭建一套完整可用的用户数据接口
Yii 2 RESTful API 快速上手:从零搭建一套完整可用的用户数据接口

后端Web框架 【免费下载链接】yii2 Yii 2: The Fast, Secure and Professional PHP Framework 项目地址: https://gitcode.com/gh_mirrors/yi/yii2 点击查看 免费下载 Yii 2 内置了一套面向 RESTful API 的完整组件链,从控制器、路由规则、内容协商到序… · 2026/9/24 12:03:09

基于STM32的大棚温湿度智能测控系统设计(DHT11 + 分级调控 + 多级报警)
基于STM32的大棚温湿度智能测控系统设计(DHT11 + 分级调控 + 多级报警)

基于STM32的大棚温湿度智能测控系统设计(DHT11 分级调控 多级报警) 一、系统功能总览二、核心模块选型对比 2.1 主控模块2.2 温湿度检测模块2.3 数据显示模块2.4 报警通知模块2.5 执行控制模块 三、系统接线总表四、系统软件设计 4.1 主程序流程设计4.… · 2026/9/24 12:02:50

微信表情有哪几种?分别怎么保存到手机相册
微信表情有哪几种?分别怎么保存到手机相册

微信里的表情看着都差不多,细分下来其实来自三个地方。微信表情可以分为三种:别人发给你的、自己添加进面板的、以及收藏起来的。三种来路出现的位置不同,但保存到相册的方式一致——发给「表情保存助手」,点它回复的下载地址。搞… · 2026/9/24 12:02:44

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码