IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 实战技能分享,如何让工程代码各种优化等级通吃,含MDK AC5,AC6,IAR和GCC -> 正文阅读

[嵌入式]实战技能分享,如何让工程代码各种优化等级通吃,含MDK AC5,AC6,IAR和GCC

目录

引出问题:

MDK设置方法(AC5和AC6):

1、开启优化后,部分功能不正常

2、开启优化后,直接整体卡死

AC5设置方法:

AC6设置方法:

IAR设置方法:

1、开启优化后,部分功能不正常

2、开启优化后,直接整体卡死

GCC设置方法:

1、开启优化后,部分功能不正常

2、开启优化后,直接整体卡死

不同优化最容易出问题的地方:

不迷信编译器:

各种优化等级通吃的实战案例分享:


引出问题:

一个好的工程项目代码,特别是开源类的,如果能做到各种优化等级通吃,是一种非常好的工程案例,这样别人借鉴的时候,可以方便的适配到自己工程里。但实际项目中,针对一款产品代码,我们一般不会这么干,因为非常耗精力,意义也不大,一般是追求最高性能,最小代码量或者更高的稳定性,我们会选择一个合理的优化等级。

但是随着工程的复杂,特别是一些第3方组件的加入,很容易碰到不耐优化的情况。也就是这个组件没法适配到我们当前的优化等级里面。甚至有时候我们还会遇到高优化等级能用,改成0级优化反倒不能用了。

本期帖子我们就分享一种方法来解决这个问题,合理的设置不同代码的不同优化等级,即一种优化为主优化等级,其它代码设置到能用的优化等级上,以此来达到通吃的目的。

如果采用这种办法可以一步一步的锁定具体问题所在,并将工程文件全部设置到同一个优化等级是最好的。
?

MDK设置方法(AC5和AC6):


分两个方向:

1、开启优化后,部分功能不正常

解决思路是把这部分的文件继续设置为低优化等级,整体工程设置为高优化等级(这种方法可以锁定有问题的文件,然后锁定具体有问题的函数)。

?

2、开启优化后,直接整体卡死

解决思路是整体工程设置为低优化等级,逐步开启工程文件的优化等级。具体到某些函数的优化也是可以单独开启测试的。

AC5设置方法:

比如设置函数优化等级为0
https://www.keil.com/support/man ... hr1359124988971.htm

#pragma push
#pragma O0
void function(void){
    ...                 // Optimized at O0
}
#pragma pop

AC6设置方法:

这里设置无优化

void function(void) _attribute__((optnone))

{
    ...   // Optimized none
}

IAR设置方法:

IAR和MDK的设置是一样的,同样我们也分为两个方向:
?

1、开启优化后,部分功能不正常

解决思路是把这部分的文件继续设置为低优化等级,整体工程设置为高优化等级(这种方法可以锁定有问题的文件,然后锁定具体有问题的函数)。

?


?

2、开启优化后,直接整体卡死

这种的解决思路是整体工程设置为低优化等级,逐步开启工程文件的优化等级。具体到某些函数的优化也是可以单独开启测试的。

比如设置函数无优化:
https://netstorage.iar.com/SuppDB/Public/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf (253页)

#pragma optimize=none
void foo(void)
{
    /* Do something, but don't optimize this function */ 
}

GCC设置方法:

GCC的话,我们这里以Embedded Studio为例进行说明,同样我们也分为两个方向:
?

1、开启优化后,部分功能不正常

解决思路是把这部分的文件继续设置为低优化等级,整体工程设置为高优化等级(这种方法可以锁定有问题的文件,然后锁定具体有问题的函数)。

?


?

2、开启优化后,直接整体卡死

这种的解决思路是整体工程设置为低优化等级,逐步开启工程文件的优化等级。具体到某些函数的优化也是可以单独开启测试的。

比如设置函数无优化:

#pragma GCC push_options
#pragma GCC optimize ("O0")
void foo(void)
{
    /* Do something, but don't optimize this function */
}
#pragma GCC pop_options

不同优化最容易出问题的地方:

延迟类函数最容易出问题,特别是像for循环这种简单实现的延迟。可以考虑使用DWT时钟周期计数器做延迟。

http://www.armbbs.cn/forum.php?mod=viewthread&tid=89128

?

不迷信编译器:

即使再强劲的编译器,有触摸不到的天花板。

MDK AC6的0级优化在这方面的设计问题最明显。比如MDK AC6.14使用0级优化编译HAL库的n级条件表达式会产生巨大的栈需求。

现象:

使用MDK5.30 AC6.14的0级优化测试RTX5的模板程序,发现启动任务需要高达2000字节的栈需求。

原因分析:

通过不断的调试和查看map,htm等文件,最终锁定是H7的HAL库函数UART_SetConfig导致的。

?

进一步的排查,锁定是下面这种n级条件表示导致的,下面这种类型的表达式偏偏在函数UART_SetConfig里面有一大批,导致产生巨大的栈需求。

/** @brief  Get UART clok division factor from clock prescaler value.
  * @param  __CLOCKPRESCALER__ UART prescaler value.
  * @retval UART clock division factor
  */
#define UART_GET_DIV_FACTOR(__CLOCKPRESCALER__) \
  (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1)   ? 1U :       \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2)   ? 2U :       \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4)   ? 4U :       \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6)   ? 6U :       \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8)   ? 8U :       \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10)  ? 10U :      \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12)  ? 12U :      \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16)  ? 16U :      \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32)  ? 32U :      \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64)  ? 64U :      \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) ? 128U :     \
   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV256) ? 256U : 1U)


解决办法:

使用AC6中0以外的其它优化就解决了,或者使用AC5的任何优化等级也都可以解决。

又比如:
如果用AC6的优化等级0,没有选择使用微库的话(底层做了C标准库重定向),偶尔会造成脱机(调试仿真下可以使用,拔掉下载器运行就失败)执行失败,将微库勾上即可解决:

这坑也非常容易遇到。

?

各种优化等级通吃的实战案例分享:

那么问题来了,有没有不需要设置不同优化等级的综合Demo分享???有的,早期为V6板子设计的二代示波器Demo,可以各种优化等级通吃,并且开启了时间优化。无需采用本帖的特别设置方法,直接切换优化等级就可以使用,大家有兴趣可以看看工程代码:地址链接

?

实际项目中让程序代码在所有优化等级下都可以正常运行来检查各种奇葩问题,也是一种非常有效的检测手段,确实可以找到程序里面的一些隐形bug。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-26 09:00:42  更:2021-11-26 09:01:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:32:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码