ARM体系结构下浮点数的Middle-Endian存储问题
老猫 2022-11-30

  由于可移植性好,相当一部分都是用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软件通过第三方库GDAL/OGR,提供对多种格式(如Shapefile、mapinfo)等矢量电子地图的读取操作。

  嵌入式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之间转换不当的问题。

  使用简单的二进制数据文件模拟x8

6下的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)应用程序中添加Middle-Endian处理

  同Little-Endian和Big-Endian的处理类似,在底层代码中,凡是涉及double类型的数据读/写操作,都要事先对double类型的数据进行调换,以保证double类型数据存储的跨体系结构一致性。

  嵌入式GIS软件是通过调用GDAL/OGR中的shpopen.c文件提供的函数对Shapefile文件进行读/写操作的。所以在shpopen.c文件中添加对Middle-Endian字节顺序进行判断的函数void EndianType(void。

  通过对浮点数1.982031在软件运行平台下的十六进制数值和其在x86下十六进制数值的比较,确定该运行平台是何种字节顺序。

  经过验证,一旦该平台采用Middle-Endian字节顺序存储double类型数据,则可利用函数“void SwapWord(int length,dout)e*dValue);”对double类型数据进行交换,以获取正确的存储顺序。

  经过修改后的sbpopen.c文件,增加了对ARM体系结构下Middle-Endian字节顺序的支持,最终解决了Micidle-

  Endian的问题,能够正确显示电子地图数据。

  4 小 结

  本文描述了嵌入式GIS软件从x86平台移植到ARM体系结构平台的过程中遇到的浮点数存储字节顺序问题,并对该问题进行了详细分析,最终确定是ARM体系结构下浮点数的Middle-Endian存储问题,并提供了解决方案。希望本文的开发经验可以对嵌入式GIS软件开发者提供一些有用的帮助。

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 基于STC89C52MCU的无线测温系统

    本51项目基于STC89C52MCU,温度传感器为DS18B20,显示模块用的是LCD1602,无线模块用的是Nodemcu。项目用到的编程语言:C,C++,L

    12小时前
  • 单片机系统的扩展和配置原则

    一个单片机硬件系统的硬件电路设计包含两部分内容:一是系统扩展,即单片机内部的功能单元,如ROM、RAM、I/O、定时器/计数器、中断系统等不能满足应用系统的要求

    12小时前
  • 深入linux内核架构 Linux内核架构分析解读

      概述  通常地,Linux操作系统如下图所示,由四大子系统组成:    用户应用层:特定Linux系统上使用的应用程序集会有所不同,具体取决于计算机系统的用

    昨天
  • 一文详解Linux的内存管理机制

    在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然。这是Linux内存管理的一个优秀特性,在这方面,区别于Win

    昨天
  • 详细介绍Linux文件I/O的基本情况

    文件描述符(FileDescriptor)asmall,nonnegativeintegerforuseinsubsequentsystemcalls(read

    昨天
  • STM32主存储块擦除编程操作的一些疑问

    说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置、芯片ID、自举程序等等。当然,FL

    昨天
  • 理解 stm32 SPI 接口

    SPI是一种高速的,全双工同步的通信总线,在芯片管脚上占用了四根线,节约了芯片的管脚,同时为PCB的布局节省了空间,提供了方便,因此越来越多的芯片集成了这种通信

    昨天
  • 单片机ISP下载线设计

    本文首先介绍了在线编程技术,然后给出了基于两种下载线设计电路,最后阐述了的性能特点。实践表明:本设计具有低成本、高灵活性,对单片机爱好者,尤其是初学者,具有很强

    昨天
  • ARM Cortex-M3的六个知识点

    1.不再像别的ARM7那样从thumb状态和ARM状态来回切换Thumb-2指令集横空出世,Cortex-M3不支持ARM指令集2.BKP备份寄存器(42个16

    昨天
  • stm32 SPI 内部结构及配置过程

    SPI(SerialPeripheralinterface),顾名思义就是串行外围设备接口。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用

    昨天
  • 如何使用硬件浮点单元以及相关数学运算

    一.前言有工程师反应说Keil下无法使用STM32F4xx硬件浮点单元,导致当运算浮点时运算时间过长,还有一些人反应不知如何使用芯片芯片内部的复杂数学运算,比如

    昨天
  • 使用FSMC可能遇到的问题

    本文将就使用FSMC可能遇到的问题进行说明。希望能对大家的学习有所帮助。一、端口配置1、由于FSMC写NOR时序与8080接口的时序十分相识,因此我们采用模拟8

    昨天
下载排行榜
更多
广告