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 ...
随机推荐
- NodeVisitor
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source ...
- STM32---喜提点灯
一:编译第一个程序 int main() //主函数 { } void SystemInit() //在执行主函数前,会被调用.不进行实现.在启动文件中被调用 { } ; Reset handler ...
- Qt编写气体安全管理系统25-位置调整
一.前言 位置调整功能,以前是直接写在设备按钮这个自定义控件类中,核心就是安装事件过滤器,识别鼠标按下.鼠标移动.鼠标松开,这三个event,做出相应的处理即可,后面发现这个功能其实很多自定义控件或者 ...
- sql 获取某一时段中每一天中最大的时间的一条记录
SELECT *FROM ( SELECT ROW_NUMBER() OVER( PARTITION BY CONVERT(CHAR(10), DataTime, 120) ORDER BY Data ...
- 【441】JSON format
Ref: json -- JSON encoder and decoder JSON(JavaScript Object Notation) can help us to see data mor ...
- 【Leetcode_easy】874. Walking Robot Simulation
problem 874. Walking Robot Simulation solution1: 思路:1)如何表示移动的方向以及移动的位置坐标; 2)障碍物坐标如何检查;3)求解的是最大距离; cl ...
- robot:根据条件主动判定用例失败或者通过
场景: 当用例中的断言部分需要满足特定条件时才会执行,如果不满足条件时,可以主动判定该用例为passed状态,忽略下面的断言语句. 如上图场景,当每月1号时,表中才会生成上月数据,生成后数据不会再有改 ...
- 微信小程序填坑,wx.request() 内调用setData()方法错误的解决办法
再方法内添加一行代码,把this对象赋值给给一个变量供success()方法内调用 核心代码: var v = this.txt; 完整示例 abc:function(e){//该函数用于和后台交互 ...
- 找出整数数组中出现次数超过数组长度一半的元素(Java)
Question:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字 package com.study.zhipengs.test; import java.util.Arrays; im ...
- jira常用配置
1.关闭注册入口 系统->一般配置->运行模式:私有 2.分享给用户组是,看不到部分用户组的时候,只需要把你的账号添加该分组即可. 3.为项目分配权限,问题-->问题属性——> ...