ArduPilot存储管理 Storage EEPROM Flash
AP_HAL::Storage
此类可以应用于所有平台。PX4v1平台支持8k的EEPROM,Pixhawk平台支持16k的FRAM铁电存储器
存储大小定义:libraries/AP_HAL/AP_HAL_Boards.h中HAL_STORAGE_SIZE
The DataFlash library
DataFlash是用来存储日志的。日志有固定的格式,固定的日志头和日志包头
//`日志头格式`
// structure used to define logging format
struct LogStructure {
uint8_t msg_type;
uint8_t msg_len;
const char name[5];
const char format[16];
const char labels[64];
};
//`日志包头`
#define LOG_PACKET_HEADER uint8_t head1, head2, msgid;
日志举例
libraries/DataFlash/examples/DataFlash_test/DataFlash_test.cpp
struct PACKED log_Test {
LOG_PACKET_HEADER;
uint16_t v1, v2, v3, v4;
int32_t l1, l2;
};
日志是以文件的形式存储到microSD card,可以直接拔出SD卡拷贝到PC
每个页首都有“日志文件的编号”和“日志文件的页号”。当用户下载日志时,非常有用
bool DataFlash_Block::WritePrioritisedBlock(const void *pBuffer, uint16_t size,
bool is_critical)
{
// is_critical is ignored - we're a ring buffer and never run out
// of space. possibly if we do more complicated bandwidth
// limiting we can reservice bandwidth based on is_critical
if (!CardInserted() || !log_write_started || !_writes_enabled) {
return false;
}
if (! WriteBlockCheckStartupMessages()) {
return false;
}
while (size > 0) {//while 判断条件
uint16_t n = df_PageSize - df_BufferIdx;
if (n > size) {
n = size;
}
if (df_BufferIdx == 0) {
// if we are at the start of a page we need to insert a
// page header
if (n > df_PageSize - sizeof(struct PageHeader)) {
n = df_PageSize - sizeof(struct PageHeader);
}
struct PageHeader ph = { df_FileNumber, df_FilePage };// df_FileNumber, df_FilePage 初始化中从SD卡中读回 add 0xff
BlockWrite(df_BufferNum, df_BufferIdx, &ph, sizeof(ph), pBuffer, n);//df_BufferNum 缓存区编号 0/1
df_BufferIdx += n + sizeof(ph);
} else {
BlockWrite(df_BufferNum, df_BufferIdx, NULL, 0, pBuffer, n);
df_BufferIdx += n;
}
size -= n;
pBuffer = (const void *)(n + (uintptr_t)pBuffer);
if (df_BufferIdx == df_PageSize) {
FinishWrite();
df_FilePage++;
}
}
return true;
}
日志按块读写
用户需要设置page大小512 byte,当写满一页以后告诉芯片复制一页
日志本身是通过DataFlash_File.cpp写到SD卡,还提供了DataFlash_Empty.cpp的块设备读写接口,下面是应用铁电的读写实例
//缓冲区buffer
static uint8_t buffer[2][DF_PAGE_SIZE];
void DataFlash_Flash::Init(const struct LogStructure *structure, uint8_t num_types)
{
DataFlash_Backend::Init(structure, num_types);
if (flash_fd == 0) {
flash_fd = open(MTD_LOG_FILE, O_RDWR, 0777);
if (flash_fd == -1) {
printf("DataFlash_Flash init failed\n");
}
}
df_PageSize = DF_PAGE_SIZE; //页大小
df_NumPages = DF_NUM_PAGES - 1; //页数量
}
//读取flash数据到buffer
void DataFlash_Flash::PageToBuffer(unsigned char BufferNum, uint16_t PageAdr)
{
PageAdr -= 1;
uint16_t ofs = PageAdr * DF_PAGE_SIZE;
memset(buffer[BufferNum], 0, DF_PAGE_SIZE);
if (lseek(flash_fd, ofs, SEEK_SET) != ofs) {
printf("PageToBuffer lseek err.\n");
return;
}
if (read(flash_fd, buffer[BufferNum], DF_PAGE_SIZE) != DF_PAGE_SIZE)
{
printf("PageToBuffer read err.\n");
return;
}
}
//记录需要写入flash的页地址和缓冲区编号
void DataFlash_Flash::BufferToPage (unsigned char BufferNum, uint16_t PageAdr, unsigned char wait)
{
PageAdr -= 1;
uint16_t ofs = PageAdr * DF_PAGE_SIZE;
if(flash_fd < 0) return;
if (lseek(flash_fd, ofs, SEEK_SET) != ofs) {
printf("BufferToPage lseek err.\n");
return;
}
if (::write(flash_fd, &buffer[BufferNum], DF_PAGE_SIZE) != DF_PAGE_SIZE)
{
printf("BufferToPage write err.\n");
return;
}
}
//数据写入缓冲区
void DataFlash_Flash::BlockWrite(uint8_t BufferNum, uint16_t IntPageAdr,
const void *pHeader, uint8_t hdr_size,
const void *pBuffer, uint16_t size)
{
if (!_writes_enabled) {
return;
}
memset(&buffer[BufferNum][IntPageAdr], 0, size+hdr_size);
if (hdr_size) {
memcpy(&buffer[BufferNum][IntPageAdr],
pHeader,
hdr_size);
}
memcpy(&buffer[BufferNum][IntPageAdr+hdr_size],
pBuffer,
size);
}
//从缓冲区读取数据
bool DataFlash_Flash::BlockRead(uint8_t BufferNum, uint16_t IntPageAdr, void *pBuffer, uint16_t size)
{
memset(pBuffer, 0, size);
memcpy(pBuffer, &buffer[BufferNum][IntPageAdr], size);
return true;
}
ArduPilot存储管理 Storage EEPROM Flash的更多相关文章
- LPCScrypt, DFUSec : USB FLASH download, programming, and security tool, LPC-Link 2 Configuration tool, Firmware Programming
What does this tool do? The LPC18xx/43xx DFUSec utility is a Windows PC tool that provides support f ...
- [转]查看Flash Log输出
1.安装Debug版本的FlashPlayer 2.mm.cfg配置文件 xp:C:\Documents and Settings\username\mm.cfg Vista/7: C:\users\ ...
- Flash Memory 简介【转】
本文转载自:https://linux.codingbelief.com/zh/storage/emmc/ Flash Memory 是一种非易失性的存储器.在嵌入式系统中通常用于存放系统.应用和数据 ...
- HTML5本地存储(Local Storage) 的前世今生
长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据 例如(用户配置信息或者运行时状态等). 常 ...
- Linux下编译内核配置选项简介
Code maturity level options代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完 ...
- MON166 User's Guide
MON166 is a debug monitor for C16x and ST10 user programs. It consists of: A configurable monitor pr ...
- 痞子衡嵌入式:恩智浦MCU安全加密启动一站式工具NXP-MCUBootUtility用户指南
NXP MCU Boot Utility English | 中文 1 软件概览 1.1 介绍 NXP-MCUBootUtility是一个专为NXP MCU安全加密启动而设计的工具,其特性与NXP M ...
- Linux: 介绍make menuconfig中的每个选项含义【转】
转自:http://blog.csdn.net/gaoyuanlinkconcept/article/details/8810468 介绍make menuconfig中的每个选项含义 Linux 2 ...
- 【内核】linux2.6版本内核编译配置选项(二)
目录 Linux2.6版本内核编译配置选项(一):http://infohacker.blog.51cto.com/6751239/1203633 Linux2.6版本内核编译配置选项(二):http ...
随机推荐
- JS语言中的JSON.parse()和JSON.stringify()
parse()用于从一个字符串中解析出json对象,如 var str = '{"name":"huangxiaojian","age":& ...
- Spring MVC 数据模型与视图
从控制器获取数据后,会装载数据到数据模型和视图中,然后将视图名称转发到视图解析器中,通过解析器解析后得到最终视图,最后将数据模型渲染到视图中,展示最终的结果给用户. 用ModelAndView来定 ...
- Flink 自定义source和sink,获取kafka的key,输出指定key
--------20190905更新------- 沙雕了,可以用 JSONKeyValueDeserializationSchema,接收ObjectNode的数据,如果有key,会放在Objec ...
- 最新CSS兼容方案
CSS兼容方案,让你的样式完美兼容各大浏览器,这个方案主要是用来解决Safari的,Opear是在测试的时候顺带试了一下,结果发现竟然也行,所以顺便也解决了. .e {/*FF OP*/ color: ...
- CF1266C Diverse Matrix
思路:构造题. 实现: #include <bits/stdc++.h> using namespace std; ][]; int main() { int r, c; while (c ...
- AtCoder Beginner Contest 147 E. Balanced Path
思路: dp,使用了bitset优化. 实现: #include <bits/stdc++.h> using namespace std; ; const int INF = 0x3f3f ...
- [计算机视觉][ARM-Linux开发]OpenCV 3.1下载 ippicv_linux_20151201失败
安装OpenCV 3.1的过程中要下载ippicv_linux_20151201,由于网络的原因,这个文件经常会下载失败. 解决的办法是手动下载: 先下载 OpenCV 3.1 Download MD ...
- C++ 顺序容器(vector,list、deque,stack,queue)
顺序容器的种类有:vector,list.deque 顺序容器适配器: stack //先进后出 栈 queue //先进先出 队列 priority_queue //也优先管 ...
- Linux(Ubuntu)下的OpenGl的环境安装, 在qt程序中使用opengl库
OpenGl的环境安装 以下参考自:https://blog.csdn.net/wasaiheihei/article/details/52085397 1. 建立基本编译环境 首先不可或缺的,就是编 ...
- Flink状态管理和容错机制介绍
本文主要内容如下: 有状态的流数据处理: Flink中的状态接口: 状态管理和容错机制实现: 阿里相关工作介绍: 一.有状态的流数据处理# 1.1.什么是有状态的计算# 计算任务的结果不仅仅依赖于输入 ...