嵌入式技术william hill官网
直播中

siyugege

9年用户 766经验值
擅长:可编程逻辑
私信 关注
[问答]

LWIP往ADS工程中移植过程中出现的问题解析

我把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)

英雄孤寂

2022-4-1 14:08:06
我把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]);
};
这样,我就没有办法不改动源代码,只通过修改宏定义的方法实现。难道真的要把所有结构体定义的代码修改一遍吗?是不是有我不知道的方法可以只修改宏定义就可以?请大家指点。



举报

siyugege

2022-4-1 14:08:51
果然通过了。谢谢。
ADS编译器的宏是不是指附件图中的这些?它也包含__CC_ARM,另外__ARMCC_VERSION=1应该也可以用吧(不知道MDK这里定义的是几)。
我的这个ADS工程已经搞不清楚来源了。应该不是自己定义的这些预定义宏。或者是ADS模板工程里的东西,应该比较通用吧。
举报

CDCNKA

2022-4-1 14:09:18
原来是1

这个好办,改成

if (__ARMCC_VERSION == 1)

的宏即可

高版本的,定义是

__ARMCC_VERSION = 350000

这样的

arm.com上面的说法:

__ARMCC_VERSION 一个十进制数字,可确保随着版本的更新而增加。格式为 PVbbbb,其中:

P 是主版本

V 是次版本

bbbb 是内部版本号。
举报

siyugege

2022-4-1 14:09:45
问题基本搞定,剩余最后一个,在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  )是否可以去掉?他们的作用域是怎样的。结构体外的定义应该对整个结构体成员起作用,但是否对结构体中成员又是结构体里面的成员起作用呢?

这个地方报错是为什么?格式不对还是不能重复定义?或者不支持指针定义?
举报

熊本熊

2022-4-1 14:10:17
按照上面的宏展开
PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
展开以后就是 __packed struct pbuf *next_pbuf;
__packed变成了pbuf的限定,而事实上应该是
struct pbuf * __packed next_pbuf; 才对。
举报

siyugege

2022-4-1 14:10:48
不是吧,你看代码最开始的地方:

PACK_STRUCT_BEGIN

struct ip_reass_helper {

把PACK_STRUCT_BEGIN替换成__packed,它的位置也是在struct 前面的。

我现在只定义PACK_STRUCT_BEGIN,不定义PACK_STRUCT_FIELD了。应该也没有问题。
举报

熊本熊

2022-4-1 14:11:28
我是说上面你贴出来的错误是因为__packed限定词修饰对象错误导致的。另外这里没有嵌套结构体,那只是个指针。本身那个结构体不是__packed的,所以也不能用__packed来修饰。

但是这个指针应该是__packed的。虽然在这个地方去掉可以,因为外面结构体还套着packed限定。但是我觉得把整个宏定义成空不合适。

如果外面结构体没有定义packed而只限定了packed field,那就会出问题。比如

struct foo

{

char a;

__packed short b;

char c;

};
举报

siyugege

2022-4-1 14:11:56
谢谢。经过仔细筛查,发现LWIP中所有用到PACK_STRUCT_FIELD的地方都是形如:

PACK_STRUCT_BEGIN

struct xxx{

  PACK_STRUCT_FIELD(xxx);

} PACK_STRUCT_STRUCT;

PACK_STRUCT_END

的格式。

我想源码作者这样写是方便各种编译器语法的支持。这4个选项不需要都使用,根据编译器选择其中的一个或几个即可。

在ADS中,只使用PACK_STRUCT_BEGIN就可以了。过后再在调试过程中验证。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分