5 存储于EEPROM管理Word文件下载.docx
- 文档编号:19252450
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:7
- 大小:20.04KB
5 存储于EEPROM管理Word文件下载.docx
《5 存储于EEPROM管理Word文件下载.docx》由会员分享,可在线阅读,更多相关《5 存储于EEPROM管理Word文件下载.docx(7页珍藏版)》请在冰豆网上搜索。
hal.storageAPI,非常简单,仅3个函数:
1、init(),初始化存储系统;
2、read_block(),读块数据;
3、write_block(),写块数据。
之所以这么简单,是因为APM团队鼓励开发者使用StorageManagerAPI,而不是hal.storage。
只有在代码移植或调试时,使用hal.storage会比较方便(原文:
Youshouldonlybedelvingintohal.storagewhendoingbringupofanewboard,orwhendebugging.)。
存储空间的大小,在AP_HAL/AP_HAL_Boards.h文件中的HAL_STORAGE_SIZE宏中定义,如下:
#defineCONFIG_HAL_BOARD_SUBTYPEHAL_BOARD_SUBTYPE_PX4_V2
#define
HAL_STORAGE_SIZE
16384
//存储空间16KB
#endif
也就是说,我们不支持动态存储空间的定义。
如果希望使用动态存储空间,可以使用PosixIO。
2、StorageManagerlibrary
在将ArduPilot代码移植到一个新的硬件板上时,hal.storageAPI非常简单,但是在操作存储区时就不那么好使了。
我们会采用StorageManager。
StorageManagerlibrary提供对存储区域“伪连续块”(一般用作不同的功能和目的)的访问。
正因此我们将存储区域分配了不同的功能:
1、参数区;
2、飞行区域限制点数据区;
3、航点数据区;
4、集结点数据区。
参见:
libraries/StorageManager/StorageManager.cpp,我们可以看到存储区域的划分:
constStorageManager:
StorageAreaStorageManager:
layout_copter[STORAGE_NUM_AREAS]PROGMEM={
//------------------------
0-4096
分配给了AVR版本的APM
{StorageParam,
0,
1536},//0x600parambytes
{StorageMission,1536,
2422},
{StorageRally,
3958,
90},//6rallypoints
{StorageFence,
4048,
48},//6fencepoints
#ifSTORAGE_NUM_AREAS>
=8
4096-8192
分配给了PX4版本
4096,
1280},
5376,
300},
5676,
256},
{StorageMission,5932,
2132},//leave128bytegapfor
//expansionandPX4sentinal
=12
//Pixhawk
8192-16384
分配给了Pixhawk版本
8192,
1280},
//类型
偏移量
长度
9472,
9772,
{StorageMission,10028,
6228},//leave128bytegapforexpansion
};
对于上面的存储分布,我们可以观察到AVR版本用到存储地址是0-4095,而PX4用到地址是4096-8191,Pixhawk用到的地址是8192-16383。
这样的结构,是为了更好的与之前的版本兼容。
这样一来,用户在更新最新的固件时,所有之前配置的参数将不会改变,将继续起作用。
StorageManagerAPI也提供对类似整型数的读写访问,AP_Mission中就会利用这个API来存储和恢复航点数据。
相关例程(libraries/StorageManager/examples/StorageTest.pde)对StoageManagerlayer和AP_HAL:
Storageobject进行了测试。
它对随机的偏移量、随机的长度进行了随机的IO操作。
这也就意味可能会出现跨边界访问。
这个例程非常有用,它用于对StorageManagerAPI进行严苛测试,同样对于移植ArduPilot到新硬件平台也是极为有用的,因为它对EEPROM的访问函数进行了很严格的测试。
注意StorageTest是一个毁坏性的测试,它将会删除你之前存储的参数和航点。
一定要记得测试之前,备份你的配置。
存储对象的声明,一般如下:
StorageAccessAP_Param:
_storage(StorageManager:
StorageParam);
又或者
StorageAccessAP_Rally:
StorageRally);
StorageAccessAP_Mission:
StorageMission);
StorageAccessAP_Limit_Geofence:
StorageFence);
3、DataFlashlibrary
另一类存储,就是飞行日志存储,这个基于DataFlashlibrary。
这个库的名字看上去有些怪怪的,实际上这个库最开始是为APM1的DataFlash芯片设计的,它原本是一个硬件驱动库,后来慢慢演变为一个通用日志系统,这个可以在代码中找到蛛丝马迹(这些都是以前的痕迹,不是最好的代码实现方式)。
现在DataFlashAPI主要用于实现日志存储。
它允许你自定义日志消息的数据结构。
例如GPS消息,用于记录GPS传感器的日志数据。
它能够非常有效存储这些数据,它同时也对其他库提供相应的APIs,用来进行日志回传、下载。
LOG数据结构是自定义的,其结构可以查看日志文件的FMT消息。
FMT消息地应以的其他数据的存储格式。
相关例程
libraries/DataFlash/examples/DataFlash_test/DataFlash_test.pde。
这里描述了数据的存储结构和数据格式。
简单列举如下:
第一点,在.log文件中,我们可以看到如下格式的表达:
FMT,128,89,FMT,BBnNZ,Type,Length,Name,Format,Columns
FMT,129,23,PARM,Nf,Name,Value
FMT,130,45,GPS,BIHBcLLeeEefI,Status,TimeMS,Week,NSats,HDop,Lat,Lng,RelAlt,Alt,Spd,GCrs,VZ,T
FMT,131,31,IMU,Iffffff,TimeMS,GyrX,GyrY,GyrZ,AccX,AccY,AccZ
FMT,132,67,MSG,Z,Message
第二点,上述格式,对应的代码(参见DataFlash.h):
LOG_BASE_STRUCTURES
\
{LOG_FORMAT_MSG,sizeof(log_Format),\
"
FMT"
"
BBnNZ"
Type,Length,Name,Format,Columns"
},
{LOG_PARAMETER_MSG,sizeof(log_Parameter),\
PARM"
Nf"
Name,Value"
{LOG_GPS_MSG,sizeof(log_GPS),\
GPS"
BIHBcLLeeEefI"
Status,TimeMS,Week,NSats,HDop,Lat,Lng,RelAlt,Alt,Spd,GCrs,VZ,T"
},\
{LOG_IMU_MSG,sizeof(log_IMU),\
IMU"
Iffffff"
TimeMS,GyrX,GyrY,GyrZ,AccX,AccY,AccZ"
上述结构,以LOG_IMU_MSG为例讲解:
信息类型ID
数据大小
信息名称
数据类型
数据1
数据2
数据3
数据4
数据5
数据6
数据7
LOG_IMU_MSG
sizeof(log_IMU)
IMU
Iffffff
TimeMS
GyrX
GyrY
GyrZ
AccX
AccY
AccZ
131
31(字节)
l:
整型;
f:
浮点
整型
46481
0.000703
-0.000190
-0.000359
-0.133995
0.034236
-9.748702
第三点,日志文件(.log)的一条数据如下:
IMU,46481,0.000703,-0.000190,-0.000359,-0.133995,0.034236,-9.748702
第四点,消息类型的定义:
//messagetypesforcommonmessages
//消息类型,,,对应FMT中的消息类型,,,见日志文件.log文件。
#defineLOG_FORMAT_MSG
128
#defineLOG_PARAMETER_MSG129
#defineLOG_GPS_MSG
130
#defineLOG_IMU_MSG
#defineLOG_MESSAGE_MSG
132
#defineLOG_RCIN_MSG
133
#defineLOG_RCOUT_MSG
134
#defineLOG_IMU2_MSG
135
…
第五点,log_IMU的结构,共占用3+4+12+12=
31字节。
structPACKED
log_IMU
{
LOG_PACKET_HEADER;
//3
uint32_ttimestamp;
//4
floatgyro_x,gyro_y,gyro_z;
//4*3=12
floataccel_x,accel_y,accel_z;
第六点:
如果要增加自定义的数据结构,那么可以像以下代码一样增加。
#defineLOG_TEST_MSG1
structPACKEDlog_Test{
uint16_tv1,v2,v3,v4;
int32_t
l1,l2;
staticconststructLogStructurelog_structure[]PROGMEM={
LOG_COMMON_STRUCTURES,
{LOG_TEST_MSG,sizeof(log_Test),
//
增加自定义格式数据
TEST"
HHHHii"
V1,V2,V3,V4,L1,L2"
}
第七点:
具体的数据结构操作
DataFlash.Init(log_structure,sizeof(log_structure)/sizeof(log_structure[0]));
log_num=DataFlash.StartNewLog();
DataFlash.WriteBlock(&
pkt,sizeof(pkt));
DataFlashAPI隐藏了底层如何存储log文件的细节。
另外,对于PixhawkorLinux这样的支持PosixIO的系统,日志文件是存储在microSD卡的“LOGS”目录中的。
用户可以直接抽出SD卡,直接拷贝到电脑中。
4、PosixIO
有些板子是带操作系统的,支持类似PosixAPI,如Linux和NuttX。
AP_Terrainlibrary就是一个典型的例子。
地形数据对于EEPROM是非常的大,经常要随机的存储。
DataFlashAPI就不够灵活了,同时又了PosixIO支持,也就没必要再用DataFlash了。
查看AP_HAL_Boards.h文件,确认HAL_OS_POSIX_IO宏已定义,如下:
HAL_OS_POSIX_IO
1
//带文件系统,hasposix-likefilesystemIO
下面给出了LOG和TERRAIN文件存放路径:
#defineHAL_BOARD_LOG_DIRECTORY"
/fs/microsd/APM/LOGS"
//LOG日志文件地址
#defineHAL_BOARD_TERRAIN_DIRECTORY"
/fs/microsd/APM/TERRAIN"
//地表、地形文件地址
有上述信息,就表示支持PosixIO功能,另外需要说明的是:
1、PosixIO函数,智能通过IOtimer定时器,或者其他低优先级线程调用。
IO线程优先级59。
2、不要通过其他API直接调用,哪怕是简单stat()函数,都不可以,除非你长得太帅。
3、尽量少存储,存储数据长度小,尽量少用seek(搜寻)功能。
很简单,一个原则,不要太耗时,影响飞控代码执行。
一个简单的针对SD卡的IO操作有可能花上一秒钟,这段时间足够让你的飞行器翻转,垂直掉落,直接炸鸡了。
PixhawkSD卡读写操作一般几毫秒,偶尔花费的时间会很长。
现在在你知道这么做了?
libraries/AP_Terrain/TerrainIO.cpp,我们会发现处理IO的状态机都是通过AP_Terrain:
io_timer调用的。
前面的文章:
Pixhawk源码笔记一:
APM代码基本结构:
Pixhawk源码笔记二:
APM线程:
Pixhawk源码笔记三:
串行接口UART和Console:
Pixhawk源码笔记四:
学习RCInputandOutput
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 存储于EEPROM管理 存储 EEPROM 管理
![提示](https://static.bdocx.com/images/bang_tan.gif)