完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我把LWIP往ADS工程中移植过程中出现一个问题:
在ip_addr.h中,有以下代码: struct ip_addr2 { PACK_STRUCT_FIELD(u16_t addrw[2]); } PACK_STRUCT_STRUCT; PACK_STRUCT_END 在MDK中对应的宏定义在cc.h中: #if defined(__CC_ARM) /* ARMCC compiler */ #define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) 其中__attribute__ ((__packed__))是表明不让编译器自动填充对齐结构体成员。是个GNU编译器扩展。 mdk支持在结构体最后的位置(;前),但是ADS却要在struct 之后,位置不一样,如下: struct __packed ip_addr2 { PACK_STRUCT_FIELD(u16_t addrw[2]); }; 这样,我就没有办法不改动源代码,只通过修改宏定义的方法实现。难道真的要把所有结构体定义的代码修改一遍吗?是不是有我不知道的方法可以只修改宏定义就可以?请大家指点。 |
|
相关推荐
8个回答
|
|
我把LWIP往ADS工程中移植过程中出现一个问题:
在ip_addr.h中,有以下代码: struct ip_addr2 { PACK_STRUCT_FIELD(u16_t addrw[2]); } PACK_STRUCT_STRUCT; PACK_STRUCT_END 在MDK中对应的宏定义在cc.h中: #if defined(__CC_ARM) /* ARMCC compiler */ #define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) 其中__attribute__ ((__packed__))是表明不让编译器自动填充对齐结构体成员。是个GNU编译器扩展。 mdk支持在结构体最后的位置(;前),但是ADS却要在struct 之后,位置不一样,如下: struct __packed ip_addr2 { PACK_STRUCT_FIELD(u16_t addrw[2]); }; 这样,我就没有办法不改动源代码,只通过修改宏定义的方法实现。难道真的要把所有结构体定义的代码修改一遍吗?是不是有我不知道的方法可以只修改宏定义就可以?请大家指点。 |
|
|
|
果然通过了。谢谢。
ADS编译器的宏是不是指附件图中的这些?它也包含__CC_ARM,另外__ARMCC_VERSION=1应该也可以用吧(不知道MDK这里定义的是几)。 我的这个ADS工程已经搞不清楚来源了。应该不是自己定义的这些预定义宏。或者是ADS模板工程里的东西,应该比较通用吧。 |
|
|
|
原来是1
这个好办,改成 if (__ARMCC_VERSION == 1) 的宏即可 高版本的,定义是 __ARMCC_VERSION = 350000 这样的 arm.com上面的说法: __ARMCC_VERSION 一个十进制数字,可确保随着版本的更新而增加。格式为 PVbbbb,其中: P 是主版本 V 是次版本 bbbb 是内部版本号。 |
|
|
|
问题基本搞定,剩余最后一个,在ipv4的ip_frag.c中,出现以下错误提示:
Error : C2510E: Definition of 'struct pbuf' not '__packed': qualifier ignored ip_frag.c line 91 对应代码: PACK_STRUCT_BEGIN struct ip_reass_helper { PACK_STRUCT_FIELD(struct pbuf *next_pbuf); PACK_STRUCT_FIELD(u16_t start); PACK_STRUCT_FIELD(u16_t end); } PACK_STRUCT_STRUCT; PACK_STRUCT_END 直接去掉红字部分的PACK_STRUCT_FIELD是否会出现问题?编译肯定是能过,但LWIP万一在这里出问题,以后都不知道该怎么查这个问题,所以要慎重。 这个地方理解的有些不是很清楚。 既然PACK_STRUCT_FIELD已经定义了整个结构体为__packed,那么结构体成员中的PACK_STRUCT_FIELD定义( #define PACK_STRUCT_FIELD(x) __packed x )是否可以去掉?他们的作用域是怎样的。结构体外的定义应该对整个结构体成员起作用,但是否对结构体中成员又是结构体里面的成员起作用呢? 这个地方报错是为什么?格式不对还是不能重复定义?或者不支持指针定义? |
|
|
|
按照上面的宏展开
PACK_STRUCT_FIELD(struct pbuf *next_pbuf); 展开以后就是 __packed struct pbuf *next_pbuf; __packed变成了pbuf的限定,而事实上应该是 struct pbuf * __packed next_pbuf; 才对。 |
|
|
|
不是吧,你看代码最开始的地方:
PACK_STRUCT_BEGIN struct ip_reass_helper { 把PACK_STRUCT_BEGIN替换成__packed,它的位置也是在struct 前面的。 我现在只定义PACK_STRUCT_BEGIN,不定义PACK_STRUCT_FIELD了。应该也没有问题。 |
|
|
|
我是说上面你贴出来的错误是因为__packed限定词修饰对象错误导致的。另外这里没有嵌套结构体,那只是个指针。本身那个结构体不是__packed的,所以也不能用__packed来修饰。
但是这个指针应该是__packed的。虽然在这个地方去掉可以,因为外面结构体还套着packed限定。但是我觉得把整个宏定义成空不合适。 如果外面结构体没有定义packed而只限定了packed field,那就会出问题。比如 struct foo { char a; __packed short b; char c; }; |
|
|
|
谢谢。经过仔细筛查,发现LWIP中所有用到PACK_STRUCT_FIELD的地方都是形如:
PACK_STRUCT_BEGIN struct xxx{ PACK_STRUCT_FIELD(xxx); } PACK_STRUCT_STRUCT; PACK_STRUCT_END 的格式。 我想源码作者这样写是方便各种编译器语法的支持。这4个选项不需要都使用,根据编译器选择其中的一个或几个即可。 在ADS中,只使用PACK_STRUCT_BEGIN就可以了。过后再在调试过程中验证。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
786 浏览 0 评论
4210 浏览 0 评论
如何使用python调起UDE STK5.2进行下载自动化下载呢?
2520 浏览 0 评论
开启全新AI时代 智能嵌入式系统快速发展——“第六届国产嵌入式操作系统技术与产业发展论坛”圆满结束
2926 浏览 0 评论
获奖公布!2024 RT-Thread全球巡回线下培训火热来袭!报名提问有奖!
31442 浏览 11 评论
72894 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 00:56 , Processed in 0.637937 second(s), Total 55, Slave 49 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号