1. 引言
C语言在嵌入式领域应用非常广泛,其主要优点是灵活和高效,但若在使用过程中不加以规范,容易引入各种潜在的代码问题。
先来看一段C代码,这段代码中有多少C语言的使用错误?
uint8_t vFunc(void)
{
uint8_t index = 0;
for (index = 0; index < 5; index++)
{
if (index == 3)
{
vFunc_1(&index);
return true;
}
}
}
比较容易发现的问题有:
● for循环结束后没有返回值
不太容易发现的问题有:
● index初值没有使用
● index值可能在vFunc_2()内被清零,使得循环一直被执行
为了在编码阶段找出这些问题,常用的分析方法有静态代码分析和动态代码分析。有研究表明,使用动态代码分析找到的问题中的95%都可以用静态代码分析找到。
中小型嵌入式软件项目一般使用静态代码分析工具作为主要分析手段,其中最常见的工具是PClint。PCLint是GIMPEL SOFTWARE 公司研发的C/C++软件代码静态分析工具,支持几乎所有流行的编辑环境和编译器。PC-lint不但可以检测单个文件,也可以从整个项目的角度来检测问题。支持Scott Meyes的名著(Effective C++/More Effective C++)中说描述的各种提高效率和防止错误的方法。
在我们的项目中,使用C语言作为PIC32单片机的编程语言,开发环境是MPLABX,代码查看工具是source insight。本文的主要内容就是如何将PCLint工具集成到上述两种工具中。集成完成后,可通过快捷键调用lint工具,对目标代码进行静态分析,再根据分析结果优化代码。
2. 配置PCLint
2.1. 安装PCLint
下载PCLint并安装: http://download.csdn.net/detail/b5110/6966909
升级到最新版本: http://www.gimpel.com/html/ptch90.htm , 下载下列文件:
![如何用PCLint检查PIC32单片机的C代码](http://imgtec.eetrend.com/sites/imgtec.eetrend.com/files/201702/forum/9309-25644-1.png)
● 复制升级包和lpatch到安装路径(C:\lint)
● 按住shift+右键,打开快捷菜单,选择“在此处打开命令窗口”
● 输入命令并执行:lpatch l9-a-b.lp, …, 依次类推直到l9-K-L.lp(每次输入一条执行)
● 输入命令lint-nt -v,完成上述步骤后,显示当前版本是9.00L
2.2. 下载xc32编译器共用的文件
打开 http://www.gimpel.com/html/ptch90.htm ,下载Compiler Options files:
● co-cci.lnt
● co-xc32.lnt
将上述文件存放在lint安装路径下的lnt文件夹中(c:\lint\lnt)。
2.3. 生成编译器专用的文件
打开co-xc32.lnt文件,将line 12 ~ line 23替换成如下内容:
-header(C:\lint\lnt\lint-cmac.h) // preprocessor macro definitions. Use -E -dM together with your other compilation options
// to generate all preprocessor macro definitions
// xc32-gcc -mprocessor=processor_name -E -dM empty.c (empty file)
// Any options used in the compilation and that would potentially define certain macros
// should be passed as well.
C:\lint\lnt\include-path.lnt // path to header files. Use -v option with xc32-gcc.exe to find the path to include files.
// xc32-gcc -mprocessor=processor_name -v empty.c (empty file)
// Use these paths as an argument to -i option.
// Common C Interface
C:\lint\lnt\co-cci.lnt
上述co-cci.lnt就是2.3中下载的文件,需要指定一个索引路径。lint-cmac.h和include-path.lnt需要我们自己生成。
2.3.1. lint-cmac.h
● 找到PIC32单片机的编译器xc32-gcc.exe的路径(C:\Program Files (x86)\Microchip\xc32\v1.40\bin)
● 在相同路径下创建空文件empty.c
● 按住shift+右键打开控制台,输入如下命令:
xc32-gcc -mprocessor=PIC32MX470F512L -E -dM empty.c
● 输出结果复制到lint-cmac.h文件并保存。如果输出结果不能全部显示,可以加大控制台的缓冲区,方法如下:
右击控制台标题栏,选择属性
选择布局选项卡,屏幕缓冲区大小的高度改成1000
2.3.2. include-path.lnt
● 相同路径下输入如下命令:
xc32-gcc -mprocessor=PIC32MX470F512L -v empty.c
● 从输出结果中找到编译器include文件路径:
#include "..." search starts here:
#include <...> search starts here:
c:\program files (x86)\microchip\xc32\v1.40\bin\bin\../../lib/gcc/pic32mx/4.8.3/include
c:\program files (x86)\microchip\xc32\v1.40\bin\bin\../../lib/gcc/pic32mx/4.8.3/include-fixed
c:\program files (x86)\microchip\xc32\v1.40\bin\bin\../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/include
End of search list.
复制这些路径到include-path.lnt并保存:
-i"c:\program files (x86)\microchip\xc32\v1.40\bin\bin\../../lib/gcc/pic32mx/4.8.3/include"
-i"c:\program files (x86)\microchip\xc32\v1.40\bin\bin\../../lib/gcc/pic32mx/4.8.3/include-fixed"
-i"c:\program files (x86)\microchip\xc32\v1.40\bin\bin\../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/include"
2.4. 生成工程专用的文件
完成上述步骤后,创建工程专用的文件project_name.lnt,示例代码如下:
C:\lint\lnt\co-xc32.lnt
C:\lint\lnt\options.lnt -si4 -sp4
-dXXXXXX
-i"E:\svn\branches\harmony\apps\YYYY_Project\firmware\src"
-i"E:\svn\branches\harmony\apps\YYYY_Project\firmware\src\cypress_boot"
-i"E:\svn\branches\harmony\apps\YYYY_Project\firmware\src\system_config\config_M1"
-i"E:\svn\branches\harmony\apps\YYYY_Project\firmware\src\system_config\config_M1\framework"
-i"E:\svn\branches\harmony\third_party\rtos\FreeRTOS\Source\include"
-i"E:\svn\branches\harmony\third_party\rtos\FreeRTOS\Source\portable\MPLAB\PIC32MX"
-i"E:\svn\branches\harmony\framework"
上述代码主要包含四部分内容:
● 编译器lnt文件(co-xc32.lnt),参考2.2章
● 错误抑制lnt文件(options.lnt),不希望在lint结果中输出的错误。
● 专用的宏定义。必须与定义在开发环境的编译器选项里的宏定义保持一致。
● 代码的头文件路径。lint时如果提示“找不到头文件错误”,就将这个头文件的路径写入此文件中。
2.5. 小结
章2.2、2.3、2.4提到的文件都要放在lint安装路径下的lnt文件夹内(c:\lint\lnt)。
有两种情况需要重新执行上述步骤:
● 编译器或芯片型号变更
● 安装路径变更
3. 配置开发环境
3.1. MPLABX lint插件
3.1.1. 安装PCLint插件
● 打开MPLAB X IDE,选择菜单Tools->Available Plugins
● 选中PCLint插件并安装,安装后重启MPLAB X IDE
● 选择菜单Tools->Options->Embedded->PCLint,按照下图配置:
![如何用PCLint检查PIC32单片机的C代码](http://imgtec.eetrend.com/sites/imgtec.eetrend.com/files/201702/forum/9309-25645-2.png)
● User option Function选项内容就是2.4章中讲到的project_name.lnt
● 待检查工程设为主工程:右击工程名,快捷菜单选择“set as main project
● 右击工程名,快捷菜单选择“Lint this project”
● 查看输出结果。可以在MPLABX的“lint output”窗口查看,也可以打开Log File指定的文件查看结果。
3.2. Source insight用户命令
● 打开source insight工程,选择菜单Options->Custom commands
● 点击add添加1个command,命名为PCLint-Check
● 配置用户命令,参考下图(灰色区域是命令名称,蓝色区域填入project_name.lnt)
![如何用PCLint检查PIC32单片机的C代码](http://imgtec.eetrend.com/sites/imgtec.eetrend.com/files/201702/forum/9309-25646-3.png)
● 点击Keys,为这个命令创建快捷键(设成shift+ctrl+1)
● 关闭窗口,在工程代码查看界面按下快捷键(shift+ctrl+1),弹出lnt结果输出窗口,即可查看代码分析结果。
3.3. 两种环境的对比
● MPLABX
优点:开发环境动态添加或移除所需检查的.c文件;点击错误提示可以直接跳转到出错位置
缺点:切换工程需要重新配置plugin,浪费时间;每个.c文件都要检查,不够灵活
● source insight
优点:灵活选择所需检查的.c文件;执行速度快;可为每个工程定制快捷键
缺点:错误信息显示在控制台,阅读不便
4. 对抑制警告的一些建议
● 尽量少用全局抑制命令,例如-eXXX(XXX代表警告号),具体问题具体分析
● 如果库文件警告太多,可以用-wlib(0)命令抑制所有库文件警告
● 抑制警告不是目的,写出规范的代码才是最终目的
5. 参考文献
● PCLint选项详解
http://wenku.baidu.com/link?url=NBimAZeHDwjJR7V1RiDaZmnsC5553bxf7KM1Z4ZF...
● PCLint用法
http://www.cnblogs.com/zhoug2020/p/5030624.html
● 安装路径(C:\lint\PC-lint.pdf)
● PCLint解压包路径(PC-Lint+9.0e破解版\pc_lint经验.pdf)
作者: wzz4420381
来源: http://blog.csdn.net/wzz4420381/article/details/55000084