微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > IAR9202 编译优化问题

IAR9202 编译优化问题

时间:10-02 整理:3721RD 点击:

遇到一个IAR编译优化的问题:

本想在profile中write callback中做特征值的有效性检查,却发现编译优化“high”和"medium"导致代码流程错误,如下:

#define CONST_DEF 16

//printf("xxxx\n");

if (pValue[0] > CONST_DEF) {
 // do sth
} else {
 // do sth
}

其中pValue[0]为channel数据,当优化选项为"high"时,pValue[0]为17时走的却是else分支,优化选项改为"medium",代码流程就没问题了。

另外在if之前添加一行printf,即便优化选项为"high"也没问题。通过C代码看不出问题。(IAR is cracked,stack is 1.4.1)

还想请问INIT_HEAD_LEN最小设为多大能够保证协议栈稳定运行,因为我需要1.5KB左右的buffer。

你在//do sth 处 加点代码试试看(有用处的代码,比如给一个会用到的全局变量复制等)。协议栈的优化选项默认是High,不要改。

 INIT_HEAD_LEN 是什么?

Hi TY:

  应该是INIT_HEAP_LEN默认的堆大小。

#define CONST_DEF 16

//printf("xxxx\n");

if (pValue[0] > CONST_DEF) {
 // do sth1
} else {
 // do sth2

 printf("pValue[0]=%d, CONST_DEF=%d\n", pValue[0], CONST_DEF);
}

当pValue[0]为十进制17时,上面的打印信息为: "pValue[0]=17, CONST_DEF=16"

当pValue[0]为十进制18时,上面的的判断就没问题。

为什么优化只能是"High"?

谢谢。

你使用的是协议栈,包含Lib,代码是看不到的, 而在编译lib时,我们只能假设他用的优化等级就是high.

我认为是完全没必要去尝试改成另一个优化等级可能存在的问题的。

你的 pvalue是全局变量吗?

我不确定你是在什么代码里实验的,我把你的代码copy到例子代码里,判断完全没有问题。 

pValue[0]=15;

while(pValue[0]++)
{
if (pValue[0] > CONST_DEF) {
                    PRINTF("pValue[0] > 16");
} else {
                  PRINTF("pValue[0] < 16");
}

}

另外,对应的stack用指定的IAR. 我碰到过使用新版本IAR编译没问题,但运行出未知问题的情况。

关于IAR版本比stack指定的版本新,运行出问题,那就是编译器的问题,我现在用的版本比1.4.1推荐的9.10要新。

pValue[0]代码在profile的写回调里面:

static bStatus_t xxx_WriteAttrCB(uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 len, uint16 offset, uint8 method)

                                                                                                                           ****************

代码用于判断数据有效性,现在这种情况API是有问题的。

上面加的打印就是为了排除在判断时内存被篡改,现在可以排除。

所以怀疑编译器的问题,所以才先修改优化选项。Lib是什么优化等级对于最终的linker应该没影响,最终只是静态连接在一起,解决为定义符号。

Hi, TY:

我在官方的SimpleBLEPeripheral测试,问题依然,在SimpleGATTprofile.c中在以下位置添加测试代码:

static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 len, uint16 offset,
uint8 method )
{
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;

// If attribute permissions require authorization to write, return error
if ( gattPermitAuthorWrite( pAttr->permissions ) )
{
// Insufficient authorization
return ( ATT_ERR_INSUFFICIENT_AUTHOR );
}

if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )
{
case SIMPLEPROFILE_CHAR1_UUID:
case SIMPLEPROFILE_CHAR3_UUID:

//Validate the value
// Make sure it's not a blob oper
if ( offset == 0 )
{
if ( len != 1 )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}

//Write the value
if ( status == SUCCESS )
{
checkValue(pValue); <---------------------------------------------测试代码!
#if 0
uint8 *pCurValue = (uint8 *)pAttr->pValue;
*pCurValue = pValue[0];

if( pAttr->pValue == &simpleProfileChar1 )
{
notifyApp = SIMPLEPROFILE_CHAR1;
}
else
{
notifyApp = SIMPLEPROFILE_CHAR3;
}
#endif
}

其中checkValue(uint8* pValue)定义如下:

#define CONST_DEF 16
static bool checkValue(uint8* pValue) {
uint8 value = pValue[0];

if (value > CONST_DEF) {
printf("Invalid value: %d\n", value);
return FALSE;

} else {
printf("value=%d, CONST_DEF=%d\n", value, CONST_DEF);
}

return TRUE;
}

结果向Char1写入0x11,打印为“value=17, CONST_DEF=16”

编译优化改为“meduim”就可以了。

请指教。谢谢

建议用9.10.3的版本尝试看看,我也不清楚编译器具体做了什么优化处理。. 

非常感谢TY的耐心解答。

我用的是9.20,如果改为9.10.3会有编译问题,请问除了重新建立工程,有什么快速修改工程的办法可以兼容低版本的IAR吗?

还有cc2540协议栈稳定运行需要多大内存,如果将INIT_HEAP_LEN堆大小设为2048会影响到协议栈的稳定性吗?

谢谢。

老实讲,没有所谓的快速修复方法,我之前碰到过类似的问题,这个是协议栈和IAR的版本有一定的关联。你只能认为,1.4.1的版本TI只在IAR的9.10.3上做过测试。

最快的方法反而是,你使用IAR9.10.3, 使用STACK的例子,然后把你的程序仔细的挪过来。

INIT_HEAP_LEN是堆,可以动态分配和释放的,你可以考虑改小. 同样要注意的是,协议栈底层也使用了这个堆的(我们也看不到代码,不能确定是怎么使用?用了多少),既然你减小了这个,你的应用就尽量少用或者及时释放。

额,我想知道的就是协议栈Lib会大概能用到多少内存。

不过还是要感谢你的解答,谢谢。

这个问题,可以到e2e去问下. lib里的东西那里可能有人知道。

https://e2e.ti.com/support/wireless_connectivity/

谢谢!

Hi, TY:

    刚刚更换了IAR9.10.3,问题仍然存在,有时候编译出的代码没问题,有时候编译出的还是有问题啊。

    你们没有遇到过吗?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top