Nordic nRF芯片FDS模块学习

news/2024/4/19 13:45:03/文章来源:https://blog.csdn.net/weixin_45825276/article/details/129182147

FDS系统学习

文章目录

    • FDS系统学习
      • 一、ROM,RAM,FLASH作用
      • 二、ROM,RAM和FLASH在单片中的运作原理
      • 三、Flash访问模块FDS用法
        • 1. FDS在sdk_config.h中的配置
        • 2. fds_register()注册
        • 3. fds_record_write()写记录
        • 4. fds_record_find()查找
        • 5. fds_record_open()读记录/fds_record_close()结束访问flash
        • 6. fds_record_update()更新记录
        • 7. fds_record_delete()删除操作
        • 8. fds_gc()垃圾回收
        • 9. fds_stat()FDS状态获取

参考: https://blog.csdn.net/android_lover2014/article/details/88658883
https://zhaoch.cn/2020/07/11/Nordic-FDS/

一、ROM,RAM,FLASH作用

ROM——存储固化程序的(存放指令代码和一些固定数值,程序运行后不可改动) c文件及h文件中所有代码、全局变量、局部变量、’const’限定符定义的常量数据、startup.asm文件中的代码(类似ARM中的bootloader或者X86中的BIOS,一些低端的单片机是没有这个的)通通都存储在ROM中。
RAM——程序运行中数据的随机存取(掉电后数据消失)
整个程序中,所用到的需要被改写的量,都存储在RAM中,“被改变的量”包括全局变量、局部变量、堆栈段。
FLASH——存储用户程序和需要永久保存的数据。
例如:现在家用的电子式电度表,它的内核是一款单片机,该单片机的程序就是存放在ROM里的。电度表在工作过程中,是要运算数据的,要采集电压和电流,并根据电压和电流计算出电度来。电压和电流时一个适时的数据,用户不关心,它只是用来计算电度用,计算完后该次采集的数据就用完了,然后再采集下一次,因此这些值就没必要永久存储,就把它放在RAM里边。然而计算完的电度,是需要永久保存的,单片机会定时或者在停电的瞬间将电度数存入到FLASH里。

二、ROM,RAM和FLASH在单片中的运作原理

1、程序经过编译、汇编、链接后,生成hex文件;
2、用专用的烧录软件,通过烧录器将hex文件烧录到ROM中
注:这个时候的ROM中,包含所有的程序内容:一行一行的程序代码、函数中用到的局部变量、头文件中所声明的全局变量,const声明的只读常量等,都被生成了二进制数据。
Q:既然所有的数据在ROM中,那RAM中的数据从哪里来?什么时候CPU将数据加载到RAM中?会不会是在烧录的时候,已经将需要放在RAM中数据烧录到了RAM中?
A:
(1)ROM是只读存储器,CPU只能从里面读数据,而不能往里面写数据,掉电后数据依然保存在存储器中;RAM是随机存储器,CPU既可以从里面读出数据,又可以往里面写入数据,掉电后数据不保存,这是条永恒的真理,始终记挂在心。
(2)RAM中的数据不是在烧录的时候写入的,因为烧录完毕后,拔掉电源,当再给MCU上电后,CPU能正常执行动作,RAM中照样有数据,这就说明:RAM中的数据不是在烧录的时候写入的,同时也说明,在CPU运行时,RAM中已经写入了数据。

三、Flash访问模块FDS用法

https://www.cnblogs.com/iini/p/9338169.html
在这里插入图片描述

FDS用来访问芯片内部Flash的。把数据存储在Flash中,或者读取Flash中的用户数据,或者更新或者删除Flash中的数据,FDS模块是最好的选择。
FDS采用文件和记录方式来组织Flash数据,也就是说,真正的数据是放在一条记录中,而多条记录组成一个文件。根据应用的需要,整个系统可以只有一个文件,也可以包含多个文件。文件采用文件ID来标示,文件ID为2个字节(注:不能取值为0xFFFF)。一个文件下面可以放一条记录,也可以放多条记录,记录是通过记录key来标示的,记录key也是2个字节长度(注:不能取值为0x0000)。这里需要注意的是,同一个文件下面的两条或者多条记录他们的key可以是一样的,比如我们可以建立如下文件系统:文件1包含2条记录,文件2包含3条记录,文件2包含2条key为0x0003的记录

1. FDS在sdk_config.h中的配置

[图片]

2. fds_register()注册

通过fds_register注册FDS事件回调函数及通过fds_init初始化FDS模块。FDS模块的初始化,写记录,更新记录,删除记录以及垃圾回收,这些API都是异步的。也就是说调用这些FDS操作的API,只是把相应操作放入队列然后立即返回(队列大小由上述的FDS_OP_QUEUE_SIZE控制),真正的Flash操作结果是通过事件回调函数通知你的;

3. fds_record_write()写记录

ret_code_t  fds_record_write(fds_record_desc_t * const p_desc,fds_record_t      const * const p_record);

参数及说明: 必须保证输入的参数是全局变量或者static的局部变量; p_record:需要给出要写入的记录的FILE ID,record
key以及记录的内容指针; p_desc:是fds返回该记录的描述符 ,为fds模块内部使用;因为file id和record
key不要求唯一性,所以fds模块内部定义了一个record id 来保证每个记录块的唯一性,内部可以通过record id来区分;

4. fds_record_find()查找

ret_code_t fds_record_find(uint16_t file_id, uint16_t record_key,  fds_record_desc_t * const p_desc,  fds_find_token_t  * const p_token);

参数及说明: 通过file id和record key找到flash中符合的第一个记录,并通过p_desc返回这个记录的描述符
Q:那如何找到剩下的相同file id和record
key的记录呢?A:这就需要用到第四个参数p_token,这个结构体变量保存的是找到的这个记录所在的页和地址。
找到了第一个记录并获取到了该记录所在的页和地址,那么下一个直接从前一个开始找即可;综上只需要设置p——token初始值为0,memset(&p_token,0x00,sizeof(fds_find_token_t));,然后循环迭代使用fds_record_find()函数就可以找全所有相同file
id和record key的记录了;

5. fds_record_open()读记录/fds_record_close()结束访问flash

ret_code_t fds_record_open(fds_record_desc_t  * const p_desc,fds_flash_record_t * const p_flash_record);ret_code_t fds_record_close(fds_record_desc_t * const p_desc);

参数及说明:
读记录之前必须先通过fds_record_find找到该记录;fds_record_open通过唯一的p_desc描述符去打开这个记录,并通过p_flash_record这个结构体返回这个记录数据,包括file
id,record key,长度,实际内容,(CRC)。对flash访问结束后通过fds_record_close结束访问。

6. fds_record_update()更新记录

ret_code_t  fds_record_update(fds_record_desc_t * const  p_desc,fds_record_t const * const p_record);

参数及说明: 更新记录内容实际上是重新写入一个记录,新建的记录的file id和record
key可以和旧记录一样也可以不一样;然后通过旧的记录描述符找到旧记录去无效它即可;新建的记录的描述符会存在p_desc变量中。

7. fds_record_delete()删除操作

ret_code_t fds_record_delete(fds_record_desc_t * const p_desc);

参数及说明: 删除某个记录,并不是真正的删除,实际上fds内部是使这个记录无效;删除依靠具有唯一标识的参数p_desc中的record
id进行;
delete并不会回收Flash空间,无效记录仍然占据着Flash空间,这些无效的记录占据着的Flash空间只有经过垃圾回收才能再次给新记录使用;

8. fds_gc()垃圾回收

ret_code_t fds_gc(void);

参数及说明:
垃圾回收机制会将所有没有打开记录的的脏页都做一次回收处理,释放其中的无效记录所占的flash空间,所以fds的垃圾回收比较耗时,因此fds不会主动做垃圾回收的处理;

9. fds_stat()FDS状态获取

ret_code_t fds_stat(fds_stat_t * const p_stat);

参数及说明: 获取当前fds模块的总装图,该函数返回的p_stat记录了fds管理的flash存储空间的状态;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_73092.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常见的排序算法 | 直接插入排序 | 希尔排序 | 选择排序 | 堆排序 | 冒泡排序 | 快速排序 | 归并排序 |(详解,附动图,代码)

思维导图: 一.插入排序 1.直接插入排序(InsertSort) ①手机通讯录时时刻刻都是有序的,新增一个电话号码时,就是使用插入排序的方法将其插入原有的有序序列。 ②打扑克 步骤: ①如果一个序列只有一个数&am…

报表开发难上手?这里有一份 Fastreport 最新中文用户指南,请查收

Fast Reports,Inc.成立于1998年,多年来一直致力于开发快速报表软件,包括应用程序、库和插件。FastReport的报表生成器(VCL平台和.NET平台)、跨平台的多语言脚本引擎FastScript、桌面OLAP FastCube,如今都受到世界各地开…

工赋开发者社区 | 工业数字孪生:西门子工业网络与设备虚拟调试案例(TIA+MCD+SINETPLAN)

PART1案例背景及基本情况新生产系统的设计和实施通常是耗时且高成本的过程,完成设计、采购、安装后,在移交生产运行之前还需要一个阶段,即调试阶段。如果在开发过程中的任何地方出现了错误而没有被发现,那么每个开发阶段的错误成本…

建议收藏!数据可视化大屏设计必备步骤

相信对于从事大数据相关的人员来说,数据的可视化大屏是最能展现自己工作价值的一个途径。可视化大屏就是数据分析的最后成果的展示,而如果能设计出更直观、更酷炫、更具有科技感的大屏,更能获得客户的青睐。 那么客户喜欢的究竟是怎样的可视化…

嵌入式开发:在嵌入式应用程序中混合C和C++

许多嵌入式应用程序仍使用c语言编写,但越来越多的嵌入式开发人员现在使用C语言编写程序。某些应用程序甚至共享这两种语言。这有意义吗?C是嵌入式应用中最常用的编程语言。多年来,人们一直期待着向C过渡,但过渡速度相当缓慢。但是&#xff0…

Appium自动化测试 Inspector定位Webview/H5页面元素

目录操作步骤Python操作该混合App代码Appium在操作混合App或Android App的H5页面时, 常常需要定位H5页面中的元素, 传统方式是 FQ 使用Chrome://inspect来定位元素, 环境准备相当繁琐, 不仅需要想办法FQ, 而且还需要Android设备安装Google框架以及手机版Chrome浏览器以及相应的…

问题记录-网卡丢失导致Temporary failure in name resolution

没网了,ifconfig查看一下 发现是网卡丢失 使用如下命令: sudo ifconfig eth0 up sudo dhclient解决

postgresql 数据库 主从切换 测试

postgresql 数据库 主从切换 测试 文章目录postgresql 数据库 主从切换 测试前言环境:主从切换1. 查看数据库状态:2. 备库切换主库3. 旧主库切换成备库;4 查看状态后记前言 因数据库等保需要,需要对老系统的数据库进行主从切换来…

考出PMP证书到底有没有用?

我们将从三方面分享: 1. PMP 证书在国内的含金量怎么样? 2. HR 如何看待 PMP 证书? 3. 拿到 PMP 证书后,有哪些变化? 一,PMP证书的含金量 说到 PMP 证书的含金量,相信这个问题是所有学员都…

JS语法让人困惑的点 “==与===”

在JS中有很多神奇的语法,非常让人困惑,我们就先一一道来,相信你在开发中或多或少都踩过这些坑,或者让人无法理解。 今天我们就来说下【】和【】 这题对于很多没有系统学过前端开发的技术人员来说,算个重点&#xff0c…

Spring+MVC+MYbatis注解开发

Spring常见注解 注解一:Configuration 用在类上面,加上这个注解的类可以成为一个spring的xml配置文件,使用的是java代码的配置 注解二:ComponentScan 用在类上,加上注解可以指定扫描路径 注解三:创建对…

面试 | 递归乘法【细节决定成败】

不用[ * ]如何使两数相乘❓一、题目明细二、思路罗列 & 代码解析1、野蛮A * B【不符合题意】2、sizeof【可借鉴】解析3、简易递归【推荐】① 解析&#xff08;递归展开图&#xff09;② 时间复杂度分析4、移位<<运算【有挑战性&#x1f4aa;】① 思路顺理② 算法图解…

啥是原神?女友说想要全角色语音+表情包,顺手用python把高清图也整下来了

原神全角色中日语音表情包高清图人生苦短 我用python表情包部分&#xff1a;1. 素材来自&#xff1a;2. 准备模块3. 调用浏览器驱动4. 页面滚动5. 保存数据5. 效果全角色语音高清彩图部分1.准备工具2. 准备模块3. 请求链接4. 本次目标5. 分析数据来源6. 开始代码7. 执行结果8. …

Revit操作 | 门和窗的载入与放置。

想要系统性掌握BIM技能&#xff0c;不能只停留在理论知识上&#xff0c;实操也是关键一步。 拒绝纸上谈兵&#xff0c;提升操作技巧&#xff0c;从点滴开始积累。今天我们来学习Revit实操小技巧之门和窗的载入与放置。 门和窗的载入与放置 门和窗是建筑中最常用的构件。在 Re…

单通道说话人语音分离——Conv-TasNet(Convolutional Time-domain audio separation Network)

单通道说话人语音分离——Conv-TasNet模型(Convolutional Time-domain audio separation Network) 参考文献&#xff1a;《Conv-TasNet: Surpassing Ideal Time-FrequencyMagnitude Masking for Speech Separation》 1.背景 在真实的声学环境中&#xff0c;鲁棒的语音处理通常…

Unity(二)--通过简单例子了解UGUI几个常用对象操作(Text,Image,Button)

目录 文本框等UI对象的添加Canvas 画布给Canvas添加脚本,绑定要操作的对象文本框Text的使用图像Image的使用更换图片Type:显示图片相关按钮Button的使用过渡导航事件绑定文本框等UI对象的添加 Canvas 画布 当创建一个UI元素的时候,如果没有Canvas 画布,就会自动创建一个画布…

PDMS二次开发(一)——PML类型程序类型与概念

目录前言一、PML类型与概念基础知识变量函数小例子注释PML表达式条件判断语句循环skip和break窗口程序在PDMS菜单栏中添加程序窗口自动定位PML常见控件前言 PDMS二次开发需要.net 有自带的PML语言和C# .net一般通常泛指的是C#语言 模型数据借助.NET的接口可以转换成数据库中的…

MSP430F2132IRHBR功能框图TPS259824LNRGER电路保护和电源管理解决方案芯片

概述&#xff1a;MSP430F21x2 16位超低功耗微控制器 (MCU) 是MSP430系列微控制器的一部分。这些MCU采用一种架构&#xff0c;加上5种低功耗模式&#xff0c;能在便携式测量应用中延长电池的使用寿命。这些器件具有一个强大的16位 RISC CPU、16位寄存器和用于获得最大编码效率的…

OpenStack手动分布式部署Glance【Queens版】

目录 Glance简介 1、登录数据库配置&#xff08;在controller执行&#xff09; 1.1登录数据库 1.2数据库里创建glance 1.3授权对glance数据库的正确访问 1.4退出数据库 1.5创建glance用户密码为000000 1.6增加admin角色 1.7创建glance服务 1.8创建镜像服务API端点 2、安装gla…

FinClip 的 2022 与 2023

相比往年&#xff0c;今年复盘去年与展望新年的文章来的稍慢一点。不过也希望能够借这篇文章&#xff0c;和关注 FinClip 的用户朋友们一起聊聊&#xff0c;我们在去年和今年的想法与计划。 2022 在过去的一年中&#xff0c;我们的身边发生了很多事情&#xff0c;这些事情在不…