FLASH仿真EEPROM---基于智芯Z20K11XM
一、介绍
电可擦和可编程只读存储器(EEPROM)可以对字节或字编程和擦除。EEPROM中的数据即使断电也能保持,但Z20K1xx芯片不含EEPROM。然而,闪存可以通过EEPROM仿真软件来模拟EEPROM。Z20K1xx包含两个flash阵列。编程和擦除操作可以在一个数组上进行,同时在另一个数组上执行代码。
二、存储原理
EEPROM仿真包含两个或多个扇区,每个扇区都包含一组闪存扇区。只有一个扇区被选为活动块。存储在活动扇区中的记录列表用于访问数据。每条记录都有一个ID,用来区别于其他记录。记录是一组变量。数据记录的长度是可变的。
记录按顺序编入活动扇区。为了更新记录,软件将新版本的记录写入活动扇区中下一个可用的位置。当读取记录时,软件检索具有匹配ID的最近写入的记录。当活动扇区没有足够的空间容纳新记录时,软件将活动扇区内的所有有效记录复制到其他EE扇区之一。这个新扇区成为活动扇区,之前的活动扇区失效。由于旧记录在交换期间被清除,新的活动扇区应该有空间用于记录更新。交换后,新记录将被写入新的活动扇区。 后续会详细描述,这一交换原理。
三、内存组成
下图为扇区的内存组成列表图包含扇区+记录+数据存储区。


1.扇区
每个扇区包含一个扇区报头,它包括以下部分

sectorlD:扇区标识。每当有一个新的扇区,这个数字就增加1变得活跃。它从1开始。sectorlD最大的部门是活跃的部门。
sectorstart address:扇区起始地址扇区大小:扇区的大小,以字节为单位。checksum:扇区id、扇区起始地址和扇区大小字段之和。
sector valid flag:扇区的有效标志,如果等于一个特殊的值,则表示该扇区有效
sector invalid flag:扇区的无效标志,如果等于特殊值,则表示该扇区为失效。
2.记录
每条记录包含一个记录头,它包括以下部分:

recordlD:记录的标识。
data address:记录的数据地址
record size:记录大小(以字节为单位)。
check sum:recordID、数据地址和记录大小字段之和。
record valid flag:记录的有效标志,如果它等于一个特殊值,则该记录是有效的。record invalid flag:记录的无效标志,如果它等于一个特殊值,则该记录无效。
四、扇区交换
前面提到过存储的原理实际就是活动扇区的交换,实际上扇区的交换就是在活动扇区满足以下这三点时:
①当活动扇区没有足够的空间来写入新记录时
②当在EE初始化期间检测到无效记录头时(可选)。
③当最后一个记录头无效时。
把所有的有效记录从一个活动扇区复制到另一个扇区,下图举例了三个扇区的交换:
初始时,Sector0是活动扇区,
第一次交换后,Sector0变为“invalid”,Sector1变为活动扇区。
第二次交换后,Sector1变为“invalid”,Sector2变为活动扇区。

再了解了存储结构和交换原理后我们就可以理解代码并写一段demo例子了。
五、代码编程
1.结构体初始化
static uint32_t cacheTable[EE_CACHE_RECORD_NUM];
static EE_cache_t cacheConf =
{cacheTable, /* cache 起始地址 */EE_CACHE_RECORD_NUM /* cache 缓存大小 */
};/* 扇区0配置 */
static const EE_SectorConfig_t sectorConf0 =
{EE_SECTOR_0_ADDR, /* 起始地址 */EE_SECTOR_SIZE, /* 大小 */
};/* 扇区1配置 */
static const EE_SectorConfig_t sectorConf1 =
{EE_SECTOR_1_ADDR, /* 起始地址 */EE_SECTOR_SIZE, /* 大小 */
};/* 扇区2配置 */
static const EE_SectorConfig_t sectorConf2 =
{EE_SECTOR_2_ADDR, /* 起始地址 */EE_SECTOR_SIZE, /* 大小 */
};/* 扇区配置数组 */
static const EE_SectorConfig_t* sectorConfig[EE_SECTOR_NUM] =
{§orConf0,§orConf1, §orConf2,
};/* EEPROM配置 */
EE_Config_t eeConf =
{.sectorNum = EE_SECTOR_NUM, /* 扇区数量 */.sectors = sectorConfig, /* 扇区配置 */.cacheEn = ENABLE, /* cache 使能 */.cTable = &cacheConf, /* cache 结构体 */.busyFlag = RESET,.maxRecordId = EE_MAX_RECORD_ID, /* 最大记录ID */
};
2.系统初始化
static void system_init(void)
{ WDOG_Config_t wdogCfg = {.winEnable = DISABLE,.wait = DISABLE,.stop = DISABLE,.debug = DISABLE,.windowValue = 0,.timeoutValue = 9600,.clkSource = WDOG_LPO_CLOCK,.testMode = WDOG_TST_NORMAL, };CLK_SetClkDivider(CLK_CORE, CLK_DIV_1);CLK_SetClkDivider(CLK_BUS, CLK_DIV_1);CLK_SetClkDivider(CLK_SLOW, CLK_DIV_8);if(ERR == WDOG_Init(&wdogCfg)){ErrorTrap();}if(ERR == WDOG_Enable()){ErrorTrap();}
}
3.初始化EEPROM
EEPROM仿真初始化,最多尝试三次,错误处理判断
while ((i < 3U) && (ret != EE_OK))
{ret = EE_Init(&eeConf, ENABLE, &CallBack);i++;
}
if(ret != EE_OK)
{ErrorTrap();
}
4.写入数据到EEPROM
写入数据到EEPROM,每个记录的ID从0到最大记录ID(EE_MAX_RECORD_ID),数据大小从1字节到缓冲区大小(BUFFER_SIZE),验证写入的数据,确保读取的数据与写入的数据一致。
for(id = 0U; id <= eeConf.maxRecordId; id++){size = id + 1U;if(size > BUFFER_SIZE){size = BUFFER_SIZE;}/* Init buffer*/for (i = 0; i < size; i++){buffer[i] = (uint8_t)(i + id);}ret = EE_WriteRecord(&eeConf,id, size, buffer,0, CallBack);if(ret != EE_OK){/* if writing fails, re-initialize and try again */ret = EE_Init(&eeConf, ENABLE, &CallBack);if(ret != EE_OK){ErrorTrap();}else{ret = EE_WriteRecord(&eeConf,id, size, buffer, 0, CallBack);if(ret != EE_OK){/* still error after reinitialization */ErrorTrap();}} }for (i = 0; i < BUFFER_SIZE; i++){buffer[i] = 0U;}ret = EE_ReadRecord(&eeConf,id,size,buffer,&readOutSize,CallBack);if(ret != EE_OK){ErrorTrap();}else{if(size != readOutSize){ErrorTrap();}for(i = 0; i < readOutSize; i++){if(buffer[i] != i + id){ErrorTrap();}}}}
5.验证写入的数据
验证写入的数据,确保读取的数据与写入的数据一致。
ret = EE_DeleteRecord(&eeConf,EE_TEST_RECORD_ID,CallBack);if(ret != EE_OK){ErrorTrap();}for(i = 0; i < BUFFER_SIZE; i++){buffer[i] = 0;}size = BUFFER_SIZE;ret = EE_ReadRecord(&eeConf,EE_TEST_RECORD_ID,size,buffer,&readOutSize,
6.验证删除操作
if(ret != EE_ERROR_DATA_NOT_FOUND){ErrorTrap();}while(true){CallBack();}
7.回调函数与错误处理函数
void CallBack(void);
static void ErrorTrap(void);void CallBack(void)
{WDOG_Refresh();
}static void ErrorTrap(void)
{while(true){CallBack();}
}
相关文章:
FLASH仿真EEPROM---基于智芯Z20K11XM
一、介绍 电可擦和可编程只读存储器(EEPROM)可以对字节或字编程和擦除。EEPROM中的数据即使断电也能保持,但Z20K1xx芯片不含EEPROM。然而,闪存可以通过EEPROM仿真软件来模拟EEPROM。Z20K1xx包含两个flash阵列。编程和擦除操作可以在一个数组上进行&#…...
阿里云PAI大模型评测最佳实践
作者:施晨、之用、南茵、求伯、一耘、临在 背景信息 内容简介 在大模型时代,随着模型效果的显著提升,模型评测的重要性日益凸显。科学、高效的模型评测,不仅能帮助开发者有效地衡量和对比不同模型的性能,更能指导他…...
应用图扑 HT for Web 搭建拓扑关系图
拓扑结构在计算机网络设计和通信领域中非常重要,因为它描述了网络中的设备(即“点”)如何相互连接(即通过“线”)。这种结构不仅涉及物理布局,即物理拓扑,还可以涉及逻辑或虚拟的连接方式&#…...
Django Aggregation 使用指南
Django Aggregation 使用指南 在构建Django应用时,我们经常需要对数据库中的数据进行汇总或聚合操作。例如,计算某个字段的平均值、最大值或最小值。这篇文章将详细介绍如何在Django中使用聚合查询,并结合实例进行说明。 聚合查询简介 Dja…...
嵌入式学习——Linux操作系统——文件编程练习
1.使用fread和fwrite方式完成任意普通文件的拷贝功能。 模拟 文件下载 #include <stdio.h>void do_copy(FILE *fp_s,FILE *fp_d) {char buf[100] {0};int ret;while (ret fread(buf,sizeof(char),sizeof(buf),fp_s))fwrite(buf,sizeof(char),ret,fp_d); }//./a.out sr…...
用JavaScript实现了一个简单的图像坐标点标注工具
这段代码实现了一个简单的图像标注工具,允许用户在加载的图像上进行点选标注,并且通过右键确认一个点序列来形成一个多边形。 标注效果如下 实现代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"U…...
Pytorch深度解析:Transformer嵌入层源码逐行解读
前言 本部分博客需要先阅读博客: 《Transformer实现以及Pytorch源码解读(一)-数据输入篇》 作为知识储备。 Embedding使用方式 如下面的代码中所示,embedding一般是先实例化nn.Embedding(vocab_size, embedding_dim)。实例化的…...
HSP_10章 Python面向对象编程oop_基础部分
文章目录 P107 类与实例的关系1.类与实例的关系示意图2.类与实例的代码分析 P109 对象形式和传参机制1. 类与对象的区别和联系2. 属性/成员变量3. 类的定义和使用4. 对象的传递机制 P110 对象的布尔值P111 成员方法1. 基本介绍2. 成员方法的定义和基本使用3.注意事项和使用细节…...
JavaWeb系列十七: jQuery选择器 上
jQuery选择器 jQuery基本选择器jquery层次选择器基础过滤选择器内容过滤选择器可见度过滤选择器 选择器是jQuery的核心, 在jQuery中, 对事件处理, 遍历 DOM和Ajax 操作都依赖于选择器jQuery选择器的优点 $(“#id”) 等价于 document.getElementById(“id”);$(“tagName”) 等价…...
Gone框架介绍30 - 使用`goner/gin`提供Web服务
gone是可以高效开发Web服务的Golang依赖注入框架 github地址:https://github.com/gone-io/gone 文档地址:https://goner.fun/zh/ 使用goner/gin提供Web服务 文章目录 使用goner/gin提供Web服务注册相关的Goners编写Controller挂载路由路由处理函数io.Rea…...
Lipowerline5.0 雷达电力应用软件下载使用
1.配网数据处理分析 针对配网线路点云数据,优化了分类算法,支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类;一键生成危险点报告和交跨报告;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:289…...
STM32学习之一:什么是STM32
目录 1.什么是STM32 2.STM32命名规则 3.STM32外设资源 4. STM32的系统架构 5. 从0到1搭建一个STM32工程 学习stm32已经很久了,因为种种原因,也有很久一段时间没接触过stm32了。等我捡起来的时候,发现很多都已经忘记了,重新捡…...
AI绘画Stable Diffusion 超强一键去除图片中的物体,免费使用!
大家好,我是设计师阿威 在生成图像时总有一些不完美的小瑕疵,比如多余的物体或碍眼的水印,它们破坏了图片的美感。但别担心,今天我们将介绍一款神奇的工具——sd-webui-cleaner,它可以帮助我们使用Stable Diffusion轻…...
零基础STM32单片机编程入门(一)初识STM32单片机
文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据…...
Github上前十大开源Rust项目
在github上排名前十的Rust开源项目整理出来与大家共享,以当前的Star数为准。 Deno Deno 是 V8 上的安全 TypeScript 运行时。Deno 是一个建立在V8、Rust和Tokio之上的 JavaScript、TypeScript 和 WebAssembly 的运行时环境,具有自带安全的设置和出色的开…...
硬件开发笔记(二十):AD21导入外部下载的元器件原理图库、封装库和3D模型
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/139707771 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
竞赛选题 python opencv 深度学习 指纹识别算法实现
1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python opencv 深度学习 指纹识别算法实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:4分创新点:4分 该项目较为新颖…...
RK3568开发笔记(三):瑞芯微RK3588芯片介绍,入手开发板的核心板介绍
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/139905873 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
EtherCAT主站IgH解析(二)-- 如何将Igh移植到Linux/Windows/RTOS等多操作系统
版权声明:本文为本文为博主原创文章,转载请注明出处 https://www.cnblogs.com/wsg1100 如有错误,欢迎指正。 本文简单介绍如何将 igh 移植到 zephyr、freertos、rtems、rtthread等RTOS ,甚至 windows 上。 ##前言 目前࿰…...
ansible copy模块参选选项
copy模块用于将文件从ansible控制节点(管理主机)或者远程主机复制到远程主机上。其操作类似于scp(secure copy protocol)。 关键参数标红。 参数: src:(source:源) 要复制到远程…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
