瑞萨 E2 Studio O2 编译等级下 I2C 收发无 ACK 回复问题解决经验
一、编译优化简介
在瑞萨官方的 IDE E2 Studio 中,可以通过【Optimization(优化)】选项对软件编译进行优化。IDE 提供了若干不同的优化模式,用户可以根据实际需求选择不同程度的优化。优化的主要目的是让代码执行得更快,占用空间更小,让变量访问、循环、函数调用变得更高效等。
举个例子:
在 C 语言中,如下伪代码存在着重复和冗余:
{ int a = 0; //定义一个a,赋初始值为0
int b = 1; //定义一个b,赋初始为1
a = b; //把b的值赋值到a
a = b; //把b的值赋值到a again
}
其中 b 赋值到 a,且出现了两次,但效果上与一次赋值相同,而且实际上也无需定义变量 b,通过优化编译等级后,上述代码可能变成:
{
a = 1;
}
以上是优化功能的一个例子。在 E2 Studio 中,优化选项的设置路径为:【选择工程点击右键】→【属性】→【C/C++ 构建】→【设置】→【优化】。
一般情况下,最常见的是两种选择:一个是 O0,这个在 debug 调试中常被使用;另一个是 O2,在正式版本的编译时会选择,构建的选项中的 release 版本对应的就是 O2 优化等级。
二、问题现象及排查过程
近期有一位客户在使用瑞萨 RA2L1 芯片,基于 E2 Studio 环境开发。当他把编译等级设置为 O2 后,完成编译并调试 I2C 读写功能时,出现了没有收到 ACK 应答的现象。而同样的代码,在 O0 编译模式下,I2C 通信完全正常。
排查经过
客户使用的底层驱动是 E2 Studio 智能配置工具自动配置生成的,通常情况下,只要不手动修改自动生成的代码,驱动本身不会出现问题。经过排查,对应的配置也确实没有问题。
因此,问题很可能出在用户的应用代码上。考虑到应用代码可能在不同平台间被迁移或修改,存在在新平台下运行异常的可能性。检查Hal_Entry.c 发现关键代码如下图(图2)所示:
从代码中可以看到, i2c_event 变量的作用是在主循环里轮询读取,而它的值会在中断回调里被修改,重点是在中断回调以及被修改这两个点上。
而在用户代码的下面,有如下语句:
while(i2c_event == I2C_MASTER_EVENT_ABORTED)
这是一个循环的判断语句。
在 O2 等级编译器下,编译器会认为,这段循环不会被外界修改,所以会判定这个是死循环。
原因是:I2C_MASTER_EVENT_ABORTED 是个枚举常量,i2c_event 是一个普通变量,在当前函数中没有任何对它的写操作,也没有被传给其他函数(它不知道外部代码更新),源代码里也没有显示提示有中断修改它。所以编译器理所当然地推断:“这个变量不会在循环中被改变,可以优化掉重复读取。”于是 O2 会把这段编译成以下实际效果:
if (i2c_event == ABORTED)
while(1); // 死循环
这导致:O2 优化会把 i2c_event 缓存在寄存器,主循环永远读不到回调写进去的 event,所以一直读不到读不到 ACK 事件。
所以,之所以编译等级 O0 可以读到的原因是,O0 优化比较“佛系”,不会硬要去断舍离一些东西。
目前问题已经被确定,剩下的就是让这段代码不要被编译器处理掉,这在 C 语言中有专门的手段去实现,那就是增加一个 volatile 关键字。
* volatile 关键字:volatile 是 C 语言中的一个关键字,用来告诉编译器,“这个变量的值随时可能被外部改掉,不要优化它”, 它是禁止编译器对变量做危险优化的一个重要标记。
解决办法
将上述代码加入 volatile 变量(其实最关键的是 i2c_event,buf 可加可不加,但是顺手加上也无妨),如下:
static volatile i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
static volatile unsigned char buf[8] = {0};
然后重新编译,通过调试实测后,发现问题解决。
因此,在选择比较高的编译等级时,开发者需要注意,如果中断里会修改变量的情况,这种情况下需要加上 volatile 关键字,以增加代码的鲁棒性。
三、总结
本文介绍了在瑞萨 E2 Studio 开发环境中,使用 O2 编译优化等级时,因编译器优化导致 I2C 通信无法收到 ACK 应答的问题。通过分析中断回调与主循环共享变量的优化机制,给出添加 volatile 关键字的解决方案,确保代码在不同优化等级下稳定运行。
欲了解关于更多瑞萨相关方案或技术信息,请与骏龙科技当地的办事处联系或点击下方「联系我们」,提交您的需求,骏龙科技公司愿意为您提供更详细的技术解答。
更多信息: