爱悠闲 > Q24Plus ARM 字节对齐

Q24Plus ARM 字节对齐

分类: OpenAT  |  标签: header,struct,数据结构,算法,优化,网络  |  作者: xunpo 相关  |  发布日期 : 2014-09-02  |  热度 : 871°

最近在做一个基于Q24plus的网络数据通信,用的是 ADS1.2的编译环境,期间涉及到一个校验位,此校验算法为CheckSum 异或方式,在做数据校验时,模块即异常重启,开始还以为

是程序哪里不对,后来经过仔细检查才发现问题出在字节对齐上,我的通信方式为UDP,数据格式如下数据结构:

 

//Udp发送jpg Header
typedef  struct udp_jpt_header{
 u16 len; //总帧长
 u16 type;//图片类型
 u16 id; //图片ID
 u8  ver;
}UDP_JPG_HEADER_T;
//Udp jpg data
typedef  struct udp_jpg_data
{
 char deviceID[10];
 u16 blockcount;//总帧数
 u16 cuID;   //当前帧数
 char time[15];
 u16 datalen;//当前帧长
 
     
 char data[512];   //图片数据
}UDP_JPG_DATA;
//一个实际有效的JPGUDP包
typedef  struct udp_jpg_block
{
 UDP_JPG_HEADER_T header;
 UDP_JPG_DATA data;
 u8 check;//此位不用做checksum
}UDP_JPG_BLOCK,*pUDP_JPG_BLOCK;

//异或运算函数
u8 CheckSum(u8 *data,u32 len)
{
   u8 checksum1;
   u32 i; 
 checksum1=data[0];
   for(i=1;i<len;i++)
   {
  checksum1^=data[i];
   }
 return checksum1; 
}

粗略一看,这些结构都正确,但实际上这些结构中都涉及到字节对齐问题,如果不加以处理,其结果并不是我们所想要的,当程序处理这些结构时,会发生异常。
有如下代码:
UDP_JPG_BLOCK jpgblock;
char *p;
p=&jpgblock;
//此函数是我自定义的,用来做调试输出
Debug_Printf("jpbblock=%d jpgblock.header=%d jpgblock.data=%d /r/n",
sizeof(jpgblock),
sizeof(jpgblock.header),
sizeof(jpgblock.data)
);
此时输出的结果并不是我们所想要的
jpgblock=551
jpgblock.header=7
jpgblock.data=543
而是每个结构的大小都比实际输出要大,正好是将单字节补成双字节的大小。看到这个后,立即明白了,将问题锁定在了ARM的编译优化上,即字节对齐,在每个结构体前面加了一

个修饰符__packed,然后再执行,现在输出的结构大小到是正确了,但还是不能正常进行字节求异或和,看来问题还是出在这个上面。随即在网上搜索一通:
比较有帮助的网址:
http://blog.csdn.net/xhfwr/archive/2006/07/23/963793.aspx
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348bc/CJAFJHJD.html

现在处理的方法是:
在这三个结构开始处加:
#pragma pack(push) //压栈保存
#pragma pack(1)// 设置1字节对齐
在每个结构体定义前加:__packed
在结构体最后加
#pragma pack(pop) // 恢复先前设置


经过这样处理后,还不能完成按字节操作jpgblock
须将UDP_JPG_BLOCK jpgblock;定义改为:
static UDP_JPG_BLOCK jpgblock;

现在即解决了上述问题.