ARM体系下浮点数Middle-Endian问题的处理
发布时间:2008/5/27 0:00:00 访问次数:577
由于可移植性好,相当一部分嵌入式软件都是用c/c++语言开发的,而c/c++语言编写的程序中数据存储字节顺序是与编译平台所用的cpu相关的,所以嵌入式软件移植过程中,数据存储字节顺序是需要重点处理的地方。
在嵌入式gis软件从x86体系结构下移植到arm体系结构的过程中,遇到了浮点数据存储字节顺序的问题。该问题既不是big-endian,也不是little-endian,而是middle-endian字节顺序。本文先介绍该嵌入式gis软件开发平台和运行平台,再对移植过程中遇到的问题进行跟踪和分析。找到问题根源,最终给出两种解决方案。
1 嵌入式gis软件
嵌入式gis软件是用c++语言开发的,运行在pda上的嵌入式软件。
在以嵌入式硬件设备为硬件平台的基础上,内核版本为2.4.30的嵌入式linux操作系统和qt/embedded图形界面开发包构成了嵌入式gis软件的
嵌入式gis软件的运行平台是以arm920t为处理器的三星公司的smdk开发板。电子地图数据来自官方发布的某区域电子地图数据。
嵌入式gis软件在x86上调试通过后,使用2.95.3版本的arm-linux-gcc编译器交义编译嵌入式gis软件和其他组件;最终将该软件移植到smdk上运行。
移植到smdk开发板上之后,嵌入式gis软件能够正常显示软件框架;在读取shapefile格式电子地图时,进入死循环状态。根据debug信息显示,嵌入式gis软件所读取的shapefile电子地图显示范围的4个double类型数值,与x86下读取的数值不一致。例如,shapefile文件中的数据为-3.383 700,而在arm平台下凄出的数值则为7.49530le+68。arm体系结构下读出的错误数据将导致嵌入式gis软件运行时逻辑出错,不能正确最示电子地图。
2 middle-endian
在不同的体系结构之问移植嵌入式软件时,数据存储字节顺序是需要处理的问题之一。
提到数据存储字节顺序,就要提到big-endian和little-endian。在各个体系结构处理器设计之初,big-endian和little-endian的分歧就一直存在,它们代表着每个字节在不同体系结构下的不同存储方式。如图2所示,数值0x1234abcd在不同的字节顺序下具有不同存储顺序。
字节顺序的不同,经常导致读取跨平台的文件数据不一致。针对嵌入式gis软件移植过程中发生的数据不一致问题,对arm体系结构的字节顺序进行了测试,方法如下:
return(htonl(1)==1)?big:little;
测试结果显示,arm同x86一样.采用的是little-endian字节顺序存储数据,并不存在big-endilan和lit-tle-endian之间转换不当的问题。
使用简单的二进制数据文件模拟x86下的shapefile 文件。在x86体系结构下,分别在二进制文件中写入int、f1oat和double类型数据,得到x86下的数据文件。将该数据文件转移到smdk开发板上,读取该数据文件中的数值并打印。
测试结果显示arm体系结构下读取x86体系结构下生成的二进制文件,int和float类型数据与x86体系结构下一致,只有double类型数据不一致。经过进一步验证,将double类型数据以十六进制形式打印,就可以发现问题的关键,如图3所示。
同样的double类型数据0x1234 abcd,在arm体系结构下读出变成0xabcd1234。所以在arm平台下读取的地图数据发生了变化,导致嵌入式gis软件逻辑判断出错,不能正确运行。
原来arm处理器对浮点数double类型的存储不支持ieee标准,既不是litrlc-endian字节顺序,也不是big-endian字节顺序。在arm平台下,每个double类型分为两个字,每个字内部采用little endian字节顺序,而两个字之间采用big endian字节顺序组织,即middleendian字节顺序。
目前还不能通过硬件或者软件调节改变arm体系结构对double类型数据的存储顺序,因此,对于类似嵌入式gis软件这样需要读取其他体系结构平台下生成的二进制文件的程序,都需要对double类型数据的存储顺序进行处理。
3 解决方案
针对arm体系结构下double类型数据存储的middle-endian问题,有两种解决方案。
(1)修改跨体系结构数据文件
将跨体系结构文件中的double类型数据改成用文本格式存储。文本格式在跨体系结构的传输中不会改变其存储格式,从而保证读取的数据一致。但是嵌入式gis软件的数据是官方发布的数据,很难对其进行修改,所以在本软件中这种方法不适用。
(2)应用
由于可移植性好,相当一部分嵌入式软件都是用c/c++语言开发的,而c/c++语言编写的程序中数据存储字节顺序是与编译平台所用的cpu相关的,所以嵌入式软件移植过程中,数据存储字节顺序是需要重点处理的地方。
在嵌入式gis软件从x86体系结构下移植到arm体系结构的过程中,遇到了浮点数据存储字节顺序的问题。该问题既不是big-endian,也不是little-endian,而是middle-endian字节顺序。本文先介绍该嵌入式gis软件开发平台和运行平台,再对移植过程中遇到的问题进行跟踪和分析。找到问题根源,最终给出两种解决方案。
1 嵌入式gis软件
嵌入式gis软件是用c++语言开发的,运行在pda上的嵌入式软件。
在以嵌入式硬件设备为硬件平台的基础上,内核版本为2.4.30的嵌入式linux操作系统和qt/embedded图形界面开发包构成了嵌入式gis软件的
嵌入式gis软件的运行平台是以arm920t为处理器的三星公司的smdk开发板。电子地图数据来自官方发布的某区域电子地图数据。
嵌入式gis软件在x86上调试通过后,使用2.95.3版本的arm-linux-gcc编译器交义编译嵌入式gis软件和其他组件;最终将该软件移植到smdk上运行。
移植到smdk开发板上之后,嵌入式gis软件能够正常显示软件框架;在读取shapefile格式电子地图时,进入死循环状态。根据debug信息显示,嵌入式gis软件所读取的shapefile电子地图显示范围的4个double类型数值,与x86下读取的数值不一致。例如,shapefile文件中的数据为-3.383 700,而在arm平台下凄出的数值则为7.49530le+68。arm体系结构下读出的错误数据将导致嵌入式gis软件运行时逻辑出错,不能正确最示电子地图。
2 middle-endian
在不同的体系结构之问移植嵌入式软件时,数据存储字节顺序是需要处理的问题之一。
提到数据存储字节顺序,就要提到big-endian和little-endian。在各个体系结构处理器设计之初,big-endian和little-endian的分歧就一直存在,它们代表着每个字节在不同体系结构下的不同存储方式。如图2所示,数值0x1234abcd在不同的字节顺序下具有不同存储顺序。
字节顺序的不同,经常导致读取跨平台的文件数据不一致。针对嵌入式gis软件移植过程中发生的数据不一致问题,对arm体系结构的字节顺序进行了测试,方法如下:
return(htonl(1)==1)?big:little;
测试结果显示,arm同x86一样.采用的是little-endian字节顺序存储数据,并不存在big-endilan和lit-tle-endian之间转换不当的问题。
使用简单的二进制数据文件模拟x86下的shapefile 文件。在x86体系结构下,分别在二进制文件中写入int、f1oat和double类型数据,得到x86下的数据文件。将该数据文件转移到smdk开发板上,读取该数据文件中的数值并打印。
测试结果显示arm体系结构下读取x86体系结构下生成的二进制文件,int和float类型数据与x86体系结构下一致,只有double类型数据不一致。经过进一步验证,将double类型数据以十六进制形式打印,就可以发现问题的关键,如图3所示。
同样的double类型数据0x1234 abcd,在arm体系结构下读出变成0xabcd1234。所以在arm平台下读取的地图数据发生了变化,导致嵌入式gis软件逻辑判断出错,不能正确运行。
原来arm处理器对浮点数double类型的存储不支持ieee标准,既不是litrlc-endian字节顺序,也不是big-endian字节顺序。在arm平台下,每个double类型分为两个字,每个字内部采用little endian字节顺序,而两个字之间采用big endian字节顺序组织,即middleendian字节顺序。
目前还不能通过硬件或者软件调节改变arm体系结构对double类型数据的存储顺序,因此,对于类似嵌入式gis软件这样需要读取其他体系结构平台下生成的二进制文件的程序,都需要对double类型数据的存储顺序进行处理。
3 解决方案
针对arm体系结构下double类型数据存储的middle-endian问题,有两种解决方案。
(1)修改跨体系结构数据文件
将跨体系结构文件中的double类型数据改成用文本格式存储。文本格式在跨体系结构的传输中不会改变其存储格式,从而保证读取的数据一致。但是嵌入式gis软件的数据是官方发布的数据,很难对其进行修改,所以在本软件中这种方法不适用。
(2)应用