Chinaunix首页 | 论坛 | 博客
  • 博客访问: 50342
  • 博文数量: 5
  • 博客积分: 83
  • 博客等级: 民兵
  • 技术积分: 91
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-03 10:07
文章分类

全部博文(5)

文章存档

2013年(1)

2012年(4)

我的朋友

分类: 嵌入式

2012-05-03 14:02:17

硬件环境 arm s3c2410a-20  
交叉编译环境
CT_BINUTILS_VERSION=2.19.1   
CT_KERNEL_VERSION=2.6.29.4
CT_LIBC_VERSION=2.9
[DEBUG] CT_ARCH_TARGET_CFLAGS=' -mlittle-endian -march=armv4t -mcpu=arm9tdmi -mtune=arm920t -msoft-float'
[DEBUG] CT_ARCH_TARGET_LDFLAGS=' -EL'
[DEBUG] CT_ARCH_TUNE=arm920t
gcc-4.3.2

出现问题的代码如下

点击(此处)折叠或打开

  1. int main(int argc, char *argv[])
  2. {
  3.     U8 testBuf[100]= {0};
  4.     //memset( testBuf,0,100 );
  5.     U16 *len = (U16*)testBuf;
  6.     U8 *ver = testBuf+2;
  7.     U8 *msgType = testBuf+3;
  8.     U8 *flag = testBuf+4;
  9.     U32 *data = (U32*)(testBuf+5);

  10.     *len = 4;
  11.     *ver = 1;
  12.     *msgType = 2;
  13.     *flag = 3;
  14.     
  15.     int dataLen(0);
  16.     bool reVal = true;
  17.     //for (int i = 0; i < 100; ++i)
  18.     //{
  19.         *data = 0xFFFFFFFF;
  20.     //}

  21.     return 0;
  22. }


GDB调试日志如下


点击(此处)折叠或打开

  1. Breakpoint 1, main (argc=1, argv=0xbec05db4) at test.cpp:5
  2. 5 U8 testBuf[100]= {0};
  3. 1: /x *testBuf @ 30 = {0xd8, 0xd0, 0x2, 0x40, 0xb0, 0xda, 0xf9, 0xe, 0xd8,
  4. 0xee, 0x2, 0x40, 0xe8, 0xdd, 0x1, 0x40, 0x50, 0xe5, 0x1, 0x40, 0x6c, 0xbd,
  5. 0x1c, 0x40, 0xc0, 0xd7, 0x1, 0x40, 0x0, 0x50}
  6. 7 U16 *len = (U16*)testBuf;
  7. 1: /x *testBuf @ 30 = {0x0 }
  8. 8 U8 *ver = testBuf+2;
  9. 1: /x *testBuf @ 30 = {0x0 }
  10. 9 U8 *msgType = testBuf+3;
  11. 1: /x *testBuf @ 30 = {0x0 }
  12. 10 U8 *flag = testBuf+4;
  13. 1: /x *testBuf @ 30 = {0x0 }
  14. 11 U32 *data = (U32*)(testBuf+5);
  15. 1: /x *testBuf @ 30 = {0x0 }
  16. 13 *len = 4;
  17. 1: /x *testBuf @ 30 = {0x0 }
  18. 14 *ver = 1;
  19. 1: /x *testBuf @ 30 = {0x4, 0x0 }
  20. 15 *msgType = 2;
  21. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x0 }
  22. 16 *flag = 3;
  23. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x2, 0x0 }
  24. 18 int dataLen(0);
  25. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x2, 0x3, 0x0 }
  26. 19 bool reVal = true;
  27. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x2, 0x3, 0x0 }
  28. 22 *data = 0xFFFFFFFF;
  29. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x2, 0x3, 0x0 }
  30. 25 return 0;
  31. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x2,[color=#FF0000] 0xff, 0xff, 0xff, 0xff, [/color]
  32. 0x0 }
  33. 26 }
  34. 1: /x *testBuf @ 30 = {0x4, 0x0, 0x1, 0x2, 0xff, 0xff, 0xff, 0xff,
  35. 0x0 }
  36. 0x401d5004 in __libc_start_main () from /lib/libc.so.6
  37. Single stepping until exit from function __libc_start_main,
  38. which has no line number information.
  39. Program exited normally.
问题是 为什么U32 *data = (U32*)(testBuf+5);的数值会把U8 *flag = testBuf+4;的数值3覆盖掉 此代码在x86下运行正常

问题出在ARM 架构CPU的内存对齐问题上面
arm架构CPU为了性能上的考虑,会对目标数据长度的整数倍取整对齐(有人说四字节),所以不应该用U32 *data指针直接存储数据,由于是非专业ARM程序员再加上项目紧迫,没有深究其原因。
在GCC编译的时候加上 -Wcast-align 参数既可以发出内存对齐问题的警告
后来编写了模板方法应对此问题。




点击(此处)折叠或打开

  1. template<typename T>
  2. static void lfb(T* val,const void * const pBuf)
  3. {
  4.     memcpy((U8 *)val,(U8 *)pBuf,sizeof(T));
  5. }

  6. template<typename T>
  7. static void stb(T *val,const void *pBuf)
  8. {
  9.     memcpy((U8 *)pBuf,(U8 *)val,sizeof(T));
  10. }

阅读(2091) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

十七岁的回忆2012-05-06 10:52:16

ARM2410烧写问题出现的错误怎么去解决啊?

☆彼岸★花开2012-05-04 21:57:55

哦哦~有点意思啊~楼主很强大嘛,拜读了