在旧的嵌入式c / c ++代码上启用现代代码分析工具的使用 [英] Enable usage of modern code analysis tools on old-ish embedded c/c++ code

查看:120
本文介绍了在旧的嵌入式c / c ++代码上启用现代代码分析工具的使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在较旧的嵌入式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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆