ArduPilot存储管理 Storage EEPROM Flash
发布时间:2020-12-15 19:51:47 所属栏目:百科 来源:网络整理
导读:AP_HAL::Storage 此类可以应用于所有平台。PX4v1平台支持8k的EEPROM,Pixhawk平台支持16k的FRAM铁电存储器 存储大小定义: libraries/AP_HAL/AP_HAL_Boards.h 中HAL_STORAGE_SIZE The DataFlash library DataFlash是用来存储日志的。日志有固定的格式,固定
AP_HAL::Storage 存储大小定义: The DataFlash library //`日志头格式`
// 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;
日志举例 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,NULL,0,n);
df_BufferIdx += n;
}
size -= n;
pBuffer = (const void *)(n + (uintptr_t)pBuffer);
if (df_BufferIdx == df_PageSize) {
FinishWrite();
df_FilePage++;
}
}
return true;
}
日志按块读写 日志本身是通过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 failedn");
}
}
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],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,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],size+hdr_size);
if (hdr_size) {
memcpy(&buffer[BufferNum][IntPageAdr],pHeader,hdr_size);
}
memcpy(&buffer[BufferNum][IntPageAdr+hdr_size],size);
}
//从缓冲区读取数据
bool DataFlash_Flash::BlockRead(uint8_t BufferNum,void *pBuffer,uint16_t size)
{
memset(pBuffer,size);
memcpy(pBuffer,&buffer[BufferNum][IntPageAdr],size);
return true;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |