嵌入式设备组织大量数据的时候,由于先天的不足,在数据组织的时候往往需要自己定义数据结构。在上一个项目中,我尝试使用xml格式对病人信息和心电数据进行组织,使用tinyxml解析库,没想到很容易调通,这里介绍一下我基于fatfs文件系统移植tinyxml,至于tinyxml的使用,网络上很多这方面的资料,就不介绍了。
tinyxml是由C++编写的一个基于文件结构解析的解析库,需要将文件加载到内存,所以在解析的时候往往会占用比较大的内存。所以如果你的设备内存只有几k的话,估计设备内存不够。不过网上有基于数据流解析xml的开源库Expat,Expat不需要将文件加载到内存,对内存要求不高,有兴趣的可以去研究研究。tinyxml说大不大,说小也不小,对于一个长期和C语言打交道的码夫来说,C++确实蛮让人嫌弃的。另外基于C++语言编写,所以你的编译器需要支持C++语言,还好现在主流的GCC和ADS这2款比较大众的交叉编译器都支持C++。
上面说了,tinyxml需要将xml文件加载到内存,所以tinyxml在不同设备下面移植的重点就是怎么把文件加载到内存,如果生产xml文件,则还需要涉及到怎么把数据写入xml文件。从我移植的经验来看,tinyxml只需要修改与文件系统相关的tinyxml.cpp和tinyxml.h这2个文件,以及修改tinystr.h这个文件的一些包含头文件属性。
基于fatfs文件系统,先看看fatfs支持那些文件操作。
f_mount - 注册/注销一个工作区域(Work Area)
f_open - 打开/创建一个文件f_close - 关闭一个文件
f_read - 读文件f_write - 写文件
f_lseek - 移动文件读/写指针
f_truncate - 截断文件
f_sync - 冲洗缓冲数据 Flush Cached Data
f_opendir - 打开一个目录
f_readdir - 读取目录条目
f_getfree - 获取空闲簇 Get Free Clusters
f_stat - 获取文件状态
f_mkdir - 创建一个目录
f_unlink - 删除一个文件或目录
f_chmod - 改变属性(Attribute)
f_utime - 改变时间戳(Timestamp)
f_rename - 重命名/移动一个文件或文件夹
f_mkfs - 在驱动器上创建一个文件系统
f_forward - 直接转移文件数据到一个数据流 Forward file data to the stream directly
f_gets - 读一个字符串
f_putc - 写一个字符
f_puts - 写一个字符传
f_printf - 写一个格式化的字符
上面一看,好像提供的函数还蛮多的,不过我们也要具体问题具体使用,需要提醒 各位的是,上面的接口fatfs都提供了,但是似乎是需要对fatfs进行配置才能使用把,特别是f_printf接口,我们移植tinyxml的时候是需要使用f_printf,但是默认的fatfs配置是没有打开对于f_printf支持的,所以请详细看fatfs配置头文件,修改对应的宏。
好了,看看tinyxml中tinyxml.cpp和tinyxml.h这2个文件。在tinyxml.cpp中,第一个函数是TiXmlFOpen。看到文件指针类型,对文件的操作,好像我们的fatfs并不支持,没错,那就不要在犹豫了,把它改成fatfs支持的文件操作。修改后的代码如下:
FIL TiXmlFOpen( const char* filename, BYTE mode )
{
FRESULT res;
FIL file_handle;
res = f_open(&file_handle, filename, mode);
if(0 == res)
Uart_Printf("create file success!\n");
return file_handle;
}
接着我们看看void TiXmlElement::Print( FIL* cfile, int depth ) const这个函数,函数里面有很多fprintf接口,但是同样是fatfs不支持的,把它换成f_printf。
上面举的是2个例子,tinyxml中有很多这样的文件操作,只需要把他们该成你的文件系统支持的操作就行。特别是tinyxml解析库中包含的Savefile和LoadFile接口。具体的移植过程我就不写了,我将我基于ADS1.2编译器、fatfs文件系统移植的tinyxml上传到csdn,大家可以下载。