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的更多相关文章

  1. 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 ...

  2. [转]查看Flash Log输出

    1.安装Debug版本的FlashPlayer 2.mm.cfg配置文件 xp:C:\Documents and Settings\username\mm.cfg Vista/7: C:\users\ ...

  3. Flash Memory 简介【转】

    本文转载自:https://linux.codingbelief.com/zh/storage/emmc/ Flash Memory 是一种非易失性的存储器.在嵌入式系统中通常用于存放系统.应用和数据 ...

  4. HTML5本地存储(Local Storage) 的前世今生

    长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据 例如(用户配置信息或者运行时状态等). 常 ...

  5. Linux下编译内核配置选项简介

    Code maturity level options代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完 ...

  6. MON166 User's Guide

    MON166 is a debug monitor for C16x and ST10 user programs. It consists of: A configurable monitor pr ...

  7. 痞子衡嵌入式:恩智浦MCU安全加密启动一站式工具NXP-MCUBootUtility用户指南

    NXP MCU Boot Utility English | 中文 1 软件概览 1.1 介绍 NXP-MCUBootUtility是一个专为NXP MCU安全加密启动而设计的工具,其特性与NXP M ...

  8. Linux: 介绍make menuconfig中的每个选项含义【转】

    转自:http://blog.csdn.net/gaoyuanlinkconcept/article/details/8810468 介绍make menuconfig中的每个选项含义 Linux 2 ...

  9. 【内核】linux2.6版本内核编译配置选项(二)

    目录 Linux2.6版本内核编译配置选项(一):http://infohacker.blog.51cto.com/6751239/1203633 Linux2.6版本内核编译配置选项(二):http ...

随机推荐

  1. Spring cloud微服务安全实战-6-6jwt改造之日志及错误处理(2)

    第一次请求失败了 打印出了403,第二次更新成功 现在只处理了403这种情况,还有一种情况就是401,就是当前用户需要做身份认证,你没有做身份认证. 401的处理 与403类似,也是在这里配置.Ent ...

  2. Qt编写数据可视化大屏界面电子看板13-基础版

    一.前言 之前发布的Qt编写的可视化大屏电子看板系统,很多开发者比较感兴趣,也收到了很多反馈意见,纵观市面上的大屏系统,基本上都是B/S结构的web版本,需要在后台进行自定义配置模块,绑定数据源等,其 ...

  3. LabWindows/CVI入门之第四章:库文件(转)

    按语: 在参考CVI参考书使用CVI生成动态库后,在另一工程中调用DLL ,编译通不过,后参考此文,豁然开朗. http://blog.sina.com.cn/s/blog_6373e9e60101b ...

  4. Java Thread Local – How to use and code sample(转)

    转载自:https://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/ Thread Local ...

  5. 【Anaconda】关于conda使用环境未被激活的问题

    前言 在win10系统中安装Anaconda,并创建虚拟环境,但是不明白为什么切换环境之后并未激活要使用的虚拟环境. conda常用命令 activate // 切换到base环境 activate ...

  6. Meta标签中的http-equiv属性

    http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变 ...

  7. [Attention Is All You Need]论文笔记

    主流的序列到序列模型都是基于含有encoder和decoder的复杂的循环或者卷积网络.而性能最好的模型在encoder和decoder之间加了attentnion机制.本文提出一种新的网络结构,摒弃 ...

  8. Linux中执行 .sh 的方法

    linux下执行.sh文件的方法 .sh文件就是文本文件,如果要执行,需要使用chmod a+x xxx.sh来给可执行权限. 是bash脚本么 可以用touch test.sh #创建test.sh ...

  9. Mstar方案软件运行基本原理

    1. MApp_Main.c里有个while(1)循环: 2. 通过 while(1)循环MApp_MultiTasks 里面的 MApp_ProcessUserInput 可以 得到 当前的 u8K ...

  10. Linux如何查看进程、杀死进程、启动进程

    1.查看进程:ps命令 下面的命令还没实践,仅仅供你参考:可以用man ps查看格式,只不过是一个小工具而已! ps a 显示现行终端机下的所有程序,包括其他用户的程序.    ps -A 显示所有程 ...