1.7 处理器工程

用户的目标是创建一个可以在一个单处理器(或多处理器)系统上运行的应用程序。VisualDSP++里所有开发都是在一个工程中进行的,工程就是指源文件和用于创建一个处理器程序的工具配置的集合,工程文件保存了程序创建信息。VisualDSP++提供了建立工程的灵活性,可以配置代码开发工具和配置的设置,可以指定工程和单独文件的创建设置。工程可以包括VDK支持。在工程上下文中可以指定代码开发工具,为工程创建的调试和发布配置指定工程范围和单独文件的选项。本节将介绍工程向导、工程选项、工程组、源代码控制、Makefile、工程配置、工程创建。

1.工程向导

VisualDSP++提供的工程向导(如图1-11所示)简化了新工程的创建,提供了配置新工程选项的页面,根据选择有各种页面和选项可用。向导首先将询问需要什么样的配置,然后基于选择产生一个定制的起始代码文件,并将其添加到工程中,还会修改链接器设置来链接这个定制的LDF文件。

图1-11 例子:打开时的工程向导

起始代码 只能够对Blackfin处理器添加起始代码,它是一个在执行应用程序主函数之前初始化和配置处理器的程序,它将处理器设置为具有一个已知的状态、初始化选择的功能、使能标准的Blackfin实时运行模型。如果要配置处理器的Cache、处理器的时钟和功耗设置、运行时初始化选项或编译器-仪表剖析,就要为工程产生定制的起始代码。如果使用了起始代码,就将用默认的行为来创建应用程序。

LDF文件 只有Blackfin处理器工程才具有通过工程向导添加定制的LDF文件的能力,LDF文件产生的选项涉及用户堆、系统堆栈、系统堆和外部存储器等内容。之后可以通过“Project Options”对话框修改LDF文件。LDF文件中有一些特殊段供用户插入自己的LDF命令、注释等,在重新产生LDF文件时这些段是受保护的,该信息存储在“basiccrt.s”文件里。

2.工程选项

工程选项应用于整个工程,是在“Project Options”对话框里指定的,如图1-12所示为这个多页对话框的例子。它对每个代码开发工具(编译器、汇编器、链接器、分割器和加载器)提供了一个或多个页面上的选项来控制每个工具如何处理输入和产生输出,这些可用的页面取决于用户目标。选项与工具的命令行开关是对应的,可以一次性定义这些选项或之后修改它们来满足开发需要的变化,也可以通过操作系统的命令行来使用这些工具。工程选项也指定了工程目标、工具链、输出文件路径、预创建和后创建选项等信息。

图1-12 例子:显示工程页的工程选项对话框

3.工程组

工程组使得用户可以同时处理多个工程,一个工程组可以是空的也可以包含若干工程,打开一个工程会将其加入工程组,关闭一个工程会将其移出工程组,工程窗口(如图1-13所示)显示了工程组图标和工作空间中打开的工程。每个工作空间都有一个工程组,切换工作空间时将加载对应的工程组,并打开最近关闭该工作空间时的那套工程。在某个时刻只有一个工程是激活的,活动工程响应来自菜单和工具栏的命令和消息,工程窗口里用粗体字显示了活动工程,工具栏按钮里的工程框显示了活动工程的名字,如图1-14所示。尽管命令是发给活动工程的,但这些命令也将被该活动工程的依赖工程所执行。例如,假定工程A是活动的,并依赖于工程B,那么对工程A执行“Rebuild All”命令将先创建工程B。同样的逻辑也适用于“Clean”命令,它将删除中间文件和目标文件。输出Makefile操作将为每个打开的工程输出一个Makefile文件,在一个工程依赖于另一个工程的Makefile文件里,将为工程的每个依赖工程创建一个子目标(Sub-target),这样,创建工程时将先创建其所有的依赖工程。

图1-13 工程窗口(Project Window)

图1-14 工程框显示了活动工程

工程组文件 可以将工程组信息保存到一个文件中,这使得用户可以方便地恢复该工程并共享它。工程组文件(.dpg)是XML格式的,包含了工程项的列表,每个工程项对应着组里的一个工程并包含工程信息,包括工程文件的路径和其依赖工程。可以批量创建说明存储在“.dpg”文件里供以后使用(因此用户可以加载和执行它们而无须重新指定同样的创建目标)。工程窗口里根节点给出了不带扩展名的工程组文件名。

4.源代码控制(SCC)

VisualDSP++包括源代码控制(SCC),它使用户可以使用Microsoft Common Source Code Control(MCSCC)接口连接VisualDSP++ IDDE与安装在用户机器上的SCC应用程序。各种SCC产品(如Microsoft Visual SourceSafe或PVCS版本管理器)都支持MCSCC接口,通过VisualDSP++接口可以使用这些应用程序经常用到的功能而无须离开IDDE,可以从插件程序菜单发起SCC应用程序来使用不支持的功能。

创建工程时将提示用户添加该工程到SCC。在IDDE里打开工程时,SCC插件程序将连接到选择的SCC应用程序并定位工程及其源文件的一个受控复件。如果没有定位受控复件,则SCC程序必须定位它,通常将询问用户来选择它;如果受控复件成功找到或添加了,插件程序将在工程文件里保留它的应用程序特定的路径,并在未来将用该路径重新连接。执行大量文件操作需要很长时间才能完成,可以用一个显示当前执行操作的消息框提供状态信息。输出窗口的控制台视图显示已完成的操作,也会出现警告和错误消息。SCC应用程序提供了对话框,显示一些文件操作,如显示历史、展示不同操作和显示属性,这些操作可以在VisualDSP++中运行。

5.Makefile

VisualDSP++内部使用Makefile文件(.mak或.mk)来自动创建工程的,Make规则与Gnumake工具(GNU Make V3.77或更高)或其他Make工具兼容。VisualDSP++产生一个工程Makefile文件来控制目标中代码产生的顺序序列,用户也可以输出一个Makefile文件在VisualDSP++之外使用。关于Makefile文件的更多信息,参见http://www.gnu.org/manual/make/。一个工程可以有多个Makefile文件,但只能激活其中一个。如图1-15所示的工程包括了一个使能的Makefile文件(由标示)。激活的Makefile文件用其明确的Gmake命令行来创建工程,当没有为工程使能一个Makefile文件时,VisualDSP++将使用工程选项对话框里配置的规范。用户可以查看Makefile的命令行,要改变Makefile的目标,请使用配置框,如图1-16所示。关闭工程时,关联每个Makefile文件的Make命令和目标列表都将连续地记入工程文件里。

图1-15 工程窗口中的Makefile文件

图1-16 配置框里的Makefile

规则 创建工程时只能使能一个Makefile文件;在用一个外部Makefile创建工程后,不会自动加载可执行文件(即使配置了该功能)。

输出窗口 Make命令错误消息和标准输出将出现在输出窗口里,双击一个错误消息将打开Makefile文件并指到产生该错误的那行代码上。双击错误消息时将正确分析Gmake的错误消息格式,如果使用了另外的Make工具,双击操作将不起作用。一个Makefile例子如下所示:

        # Generated by the VisualDSP++ IDDE
        # Note: Any changes made to this Makefile will be lost the next
        # time the matching project file is loaded into the IDDE. If you
        # wish to preserve changes, rename this file and run it
        # externally to the IDDE.
        # The syntax of this Makefile is such that GNU Make v3.77 or
        # higher is required.
        # The current working directory should be the directory in which
        # this Makefile resides.
        # Supported targets:
        # Debug
        # Debug_clean
        # Release
        # Release_clean
        # Define ADI_DSP if it is not already defined. Define this
        # variable if you wish to run this Makefile on a host other than
        # the host that created it and VisualDSP++ may be installed in a
        # different directory.
        ifndef ADI_DSP
        ADI_DSP=C:\Program Files\Analog Devices\VisualDSP
        endif
        # $VDSP is a gmake-friendly version of ADI_DIR
        empty:=
        space:= $(empty) $(empty)
        VDSP_INTERMEDIATE=$(subst \,/,$(ADI_DSP))
        VDSP=$(subst $(space),\$(space),$(VDSP_INTERMEDIATE))
        # Define the command to use to delete files (which is different
        # on Win95/98 and Windows NT/2000)
        ifeq ($(OS),Windows_NT)
        RM=cmd /C del /F /Q
        else
        RM=command /C del
        endif
        #
        # Begin "Debug" configuration
        #
        ifeq ($(MAKECMDGOALS),Debug)
        Debug : ./debug/mean.dxe
        ./debug/mean.doj :./mean.c ../../../include/stdio.h
        $(VDSP)/cc21k -c .\Mean.c -g -proc ADSP-21062-o
        .\Debug\Mean.doj
        ./debug/benchmark.doj :./benchmark.asm
        ../../../include/asm_sprt.h ../../../include/def21060.h
        $(VDSP)/easm21k.exe -proc ADSP-21062-o
        .\Debug\benchmark.doj -g .\benchmark.asm
        ./debug/mean.dxe :./debug/mean.doj ./debug/benchmark.doj
        $(VDSP)/cc21k.exe .\Debug\Mean.doj .\Debug\benchmark.doj -proc
        ADSP-21062-L .\Debug -flags-link -od,.\Debug -o .\Debug\Mean.dxe
        endif
        ifeq ($(MAKECMDGOALS),Debug_clean)
        Debug_clean:$(RM) ".\Debug\Mean.doj"
            $(RM) ".\Debug\benchmark.doj"
            $(RM) ".\Debug\Mean.dxe"
            $(RM) ".\Debug\*.ipa"
            $(RM) ".\Debug\*.opa"
            $(RM) ".\Debug\*.ti"
        endif
        # Begin "Release" configuration
        #
        ifeq ($(MAKECMDGOALS),Release)
        Release : ./release/mean.dxe
        ./release/mean.doj :./mean.c
        $(VDSP)/cc21k -c .\Mean.c -O1-proc ADSP-21062-o
        .\Release\Mean.doj
        ./release/benchmark.doj :./benchmark.asm
        $(VDSP)/easm21k.exe -proc ADSP-21062-o .\Release\benchmark.doj
        .\benchmark.asm
        ./release/mean.dxe :./release/mean.doj ./release/benchmark.doj
        $(VDSP)/cc21k.exe .\Release\Mean.doj .\Release\benchmark.doj
        -proc ADSP-21062-L .\Release -flags-link -od,.\Release -o
        .\Release\Mean.dxe
        endif
        ifeq ($(MAKECMDGOALS),Release_clean)
        Release_clean:
            $(RM) ".\Release\Mean.doj"
            $(RM) ".\Release\benchmark.doj"
            $(RM) ".\Release\Mean.dxe"
            $(RM) ".\Release\*.ipa"
            $(RM) ".\Release\*.opa"
            $(RM) ".\Release\*.ti"
        endif

6.工程配置

默认情况下工程包括两种配置:“Debug”和“Release”,见表1-5。在先前软件发布中,术语“Configuration”称为“创建类型”,可用配置出现在配置框里,默认情况下它位于工程工具栏里,如图1-17所示,用户不能删除“Release”或“Debug”配置。

表1-5 默认的工程配置

图1-17 配置框

定制工程配置 可以为工程添加配置,定制的工程配置可以包括各种工程选项,也可以创建选项来帮助工程开发。如图1-18所示为一个列在配置框里的定制配置(Version 2)。

图1-18 选择一个工程配置

7.工程创建

术语“Build”(创建)是指对工程和文件执行操作(如预处理、汇编和连接)的过程。在创建过程中,VisualDSP++将处理自上一次创建后被修改过的工程文件以及包含(#include)一个修改文件的工程文件(这些文件都称为过期文件(Outdated File))。例如,如果一个C文件没有修改过,但它包含了一个修改过的头文件,那么这个C文件就是一个过期文件,VisualDSP++使用dependency信息来决定哪些文件在创建时必须更新。“Rebuild All”(重新全部创建)不同于“Build”,它将处理工程里的所有文件,不管是否修改过。还要注意如下事项:

① 创建时将忽略扩展名不识别的文件。

② 工程窗口里的文件图标指示了文件状态(如排除在外的文件或具有重载工程设置的特定选项的文件)。

创建选项 可以为整个工程和单独文件指定选项,表1-6列出了这些创建选项。

表1-6 创建选项

文件创建 创建一个文件将编译或汇编该文件并定位和排除错误。可以创建一个单独文件或多个选定的文件,创建过程中将更新选择的源文件的输出文件以及输出文件的调试信息。创建一个单独文件非常快,然而创建大的工程可能非常耗时。如果改变了一个要求完全创建的共同头文件,则只需要创建当前文件并确保修复当前文件改变部分中的错误。

批量创建 执行批量创建将在打开的工程组里创建一个或多个创建目标。必须在创建前配置批量创建,工程组里的创建目标是由工程和工程配置(如发布配置)形成的。

预创建和后创建选项 预创建和后创建选项是典型的在工程创建前和成功创建后要执行的DOS命令,这些命令将调用外部工具,可以通过“Project Options”对话框来配置这些选项。例如,可以使用后创建命令来将最终输出文件复制到硬盘上的另一位置或自动调用一个应用程序,在创建成功后自动复制文件和清除中间文件是非常有用的。其命令语法是将“c:\windows\command.com /C”放置在每个DOS命令行的开始。例如,执行“copy a.txt b.txt”,应输入:“c:\windows\command.com /C copy a.txt b.txt”,反斜杠字符后的字母“C”必须大写。

工程依赖 依赖数据决定了哪些文件必须在创建时更新,下面是依赖信息的例子:

        ..\.\.\include\cplus\cstddef
        ..\.\.\include\cplus\exception
        ..\.\.\include\cplus\new
        ..\.\.\include\cplus\xstddef
        ..\.\.\include\def21060.h
        ..\.\.\include\limits.h
        ..\.\.\include\cplus\stddef
        ..\.\.\include\stdio.h
        ..\.\.\include\string.h
        ..\.\.\include\VDK_Internals.h
        ..\.\.\include\VDK_Public.h
        ..\.\.\include\yvals.h