在旧的嵌入式c / c ++代码上启用现代代码分析工具的使用 [英] Enable usage of modern code analysis tools on old-ish embedded c/c++ code
问题描述
如何在较旧的嵌入式c / c ++源代码上使用现代代码分析工具,例如 SourceTrail ,最初用于诸如Micro-Controller的Hi-Tech C,PIC C,IAR Workbench之类的编译器,不仅限于Microchip的PIC,PIC16和PIC18系列。
How to use modern code analysis tools, such as SourceTrail on old-ish embedded c/c++ source code, originally for compilers such as Hi-Tech C, PIC C, IAR Workbench for a number of Microcontrollers not only limited to PIC, PIC16, and PIC18 series from Microchip.
由于微型微控制器的有限体系结构,嵌入式编译器的供应商不得不提出对c / c ++语言的扩展,这些扩展已经(或尚未在c语言规范中)。
In order to support the limited architectures of the tiny microcontrollers, the vendors of the embedded compilers have had to come up with extensions to the c/c++ language, which were (or are not yet) in the c language specifications.
这将导致特定于微控制器的头文件包含以下内容:
This results in the microcontroller specific header files containing stuff like this:
// Register: ANSELA
extern volatile unsigned char ANSELA @ 0xF38;
#ifndef _LIB_BUILD
asm("ANSELA equ 0F38h");
#endif
typedef union {
struct {
unsigned ANSB0 :1;
unsigned ANSB1 :1;
unsigned ANSB2 :1;
unsigned ANSB3 :1;
unsigned ANSB4 :1;
unsigned ANSB5 :1;
};
} ANSELBbits_t;
extern volatile ANSELBbits_t ANSELBbits @ 0xF39;
extern volatile unsigned short long TBLPTR @ 0xFF6;
extern volatile __bit ABDEN1 @ (((unsigned) &BAUDCON1)*8) + 0;
和代码文件包括以下内容:
and code files include things like this:
void interrupt high_priority InterruptVectorHigh(void)
{
}
void interrupt low_priority InterruptVectorLow(void)
{
}
用现代工具支持此源的最简单方法是什么,同时还要确保该源仍可与原始编译器一起使用?
What is the easiest method to support this source with modern tools, while ensuring that the source can still be used with the original compilers?
编辑:
下面提供了一个答案。
推荐答案
下面的修复将使所有支持C18或C2x规范的编译器都可以理解c代码。我还没有机会进行c ++测试,因此它们可能不完全符合任何C ++规范。
The fix below will enable c code to be understood by any compiler supporting the C18 or C2x specifications. I've not (yet) had the opportunity to test with c++, so they may not fully comply with any of the C++ specifications.
感谢@Antti Haapala,@这样的人克利福德和@anastaciu在此处和此处,并启用了更完整的答案。
Thank you to people such as @Antti Haapala, @Clifford, and @anastaciu who answered my related questions here and here and enabled this more complete answer.
首先, 24位 short long
类型是一个问题,因为在c规范中不存在等效项,并且因为该类型的两个单词不能用<$ c寻址$ c> #define 。最初,我使用Perl来简单地将所有供应商特定头文件的字符串 short long
修改为 long
First, the 24-bit short long
type was a problem, as no equivalent exists in the c-specifications, and because the two words of the type could not be addressed with a #define
. At first, I used Perl to simply modify the string short long
into long
of all the vendor-specific header files like this:
perl -pi -e "s/(short long)/long/g" .h
注意,对于Windows上的Microchip MPLAB CX8编译器,头文件位于以下文件夹和子文件夹:c:\Program Files(x86)\Microchip\xc8\v1.33\include
Note, for the Microchip MPLAB CX8 compiler on Windows the header files are located in the following folder and sub-folders: c:\Program Files (x86)\Microchip\xc8\v1.33\include
但是后来我意识到 short
类型永远不会被单独使用,所以我决定简单地删除 short
部分使用 #define short
。请注意,这将影响使用 short
的任何内容,因此我在此答案中保留了这两种方法。
But then I realized that the short
type is never used on its own, so I decided to simply remove the short
part using a #define short
. Do note that this will affect anything using short
so I left both methods in this answer.
@符号是一个特定的问题,因为无法使用 #define
重新定义它们,因此请再次进行救援,这次使用两次传递来解决两种不同的语法:
@-signs were a specific problem, as they could not be redefined using #define
, so perl to the rescue again, this time using two passes to address the two different syntaxes:
perl -pi -e "s/@\s*([0-9a-fA-FxX]+)/AT($1)/g" .h
perl -pi -e "s/[@] ?+([^;]*)/AT($1)/g" .h
这些基本上是将 @
之后的所有内容包装在 AT()
,允许对常规定义进行操作。
These essentially wrap anything following a @
in AT()
, allowing a normal define to operate on it.
最后一点是在编译器供应商提供的每个头文件中插入一个宏头。我最后得到了以下宏标头:
The final touch is to insert a macro header into each of the header files provided by the compiler vendor. I ended up with the following macro header:
// Hack to allow SourceTrail to be used on this source
#if defined __XC8
#define AT(address) @ address
#else
#define AT(address)
#define __bit _Bool
#define asm(assembly)
#define interrupt
#define short
#define high_priority
#define low_priority
#endif
可以看出,任何非标准的东西都会被删除,除非MPLAB XC8编译器使用了头文件。唯一的例外是 __ bit
类型,该类型被重新定义为 _Bool
类型-似乎可行。
As can be seen, anything non-standard is simply removed, except when the header files are used by the MPLAB XC8 compiler. The only exception is the __bit
type, which is redefined as a _Bool
type - it seems to work.
当我在Windows上运行所有这些程序时,Perl单行代码实际上无法正常工作与在Linux上一样,因此为了处理每个头文件,我不得不将Perl命令包装在批处理for循环中,这非常慢。为了弥补这一点,我将所有内容合并为一个名为 fix.cmd
的批处理,该批处理放置在include文件夹中(请参见上面的路径):
As I'm running all of this on windows, Perl one-liners don't really work as on Linux, so in order to process each and every header file, I had to wrap the Perl command in a batch for-loop, which is pretty slow. To make up for it, I combined everything in a single batch called fix.cmd
, which is placed in the include folder (see path above):
:: Fix to allow SourceTrail to analyze MPLAB CX8 source code.
@echo off
setlocal enabledelayedexpansion
:: Run in the folder where the script exists.
pushd "%~dp0"
echo:Fixing MPLAB global include files to be used by SourceTrail and other analysis tools.
:: Loop each directory recrusively
set DirCounter=0
set FileCounter=0
for /r %%d in (.) do (
set /A DirCounter=DirCounter+1
pushd %%d
echo | set /p=Processing:
cd
for %%f in (*.h) do (
set /A FileCounter=FileCounter+1
set /A ModValue=FileCounter%%25
if !ModValue!==0 ( echo | set /p=* )
call :ProcessFile %%f
)
popd
echo *
)
echo:Processed %FileCounter% files in %DirCounter% folders.
echo Done
exit /b 0
:ProcessFile
:: filename is in %1
:: Remove short from short long. (Done with a define instead)
:: perl -pi -e "s/(short long)/long/g" %1
:: Replace the simple @ lines with AT().
perl -pi -e "s/@\s*([0-9a-fA-FxX]+)/AT($1)/g" %1
:: Exchange @ and wrap in parenthesis for any substring starting with @ and ending with ; in each header file.
perl -pi -e "s/[@] ?+([^;]*)/AT($1)/g" %1
:: Insert defines before first line in each header files:
perl -pi -e "print \"// Hack to allow SourceTrail to be used on this source\n#if defined __XC8\n #define AT(address) @ address\n#else\n #define AT(address)\n #define __bit _Bool\n #define asm(assembly)\n #define interrupt\n #define short\n#define high_priority\n #define low_priority\n#endif\n\n\" if $. == 1" %1
::Exit subroutine
exit /b
执行修改,打开提升的提示符,cd到包含文件,然后执行 fix.cmd
To perform the modification, open an elevated prompt, cd to the include files, and execute the fix.cmd
Perl必须安装在Windows计算机上。我使用 StrawberryPerl
Perl must be installed on the Windows computer. I use StrawberryPerl
编辑:
多数是固定错别字。
阐明了如何处理短多头
这篇关于在旧的嵌入式c / c ++代码上启用现代代码分析工具的使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!