当前位置:首页 >> 信息与通信 >>

Codewarrior集成开发环境的使用

1. Codewarrior 集成开发环境的使用

1.1. 软件开发与开发工具
嵌入式系统软件开发的目的和环境均比较特殊,通常借助于桌面系统或工作站来进 行,因此必然需要软件开发工具的支持。本章主要讨论嵌入式系统软件开发的一般过程、 开发工具需求和支持 M·CORE 软件开发的工具集。

嵌入式系统软件开发
根据设计人员的喜好和特长,嵌入式系统软件的程序设计可以使用高级语言或汇编 语言编制,也可以一部分模块使用高级语言编制,另一部分模块使用汇编语言编制。其 软件开发的一般过程如图 20.1 所示。 C++语言程序设计 C++编译器 目标文件 C 语言程序设 计 C 编译器 目标文件 汇编语言程序设 计 汇编器 目标文件 第三方提供功能模块

连接器/重定位连接器 可执行代码文件

程序排错

程序下载到目标系统中运行 图 20.1 嵌入式系统软件开发流程 在该流程的虚线以上部分通常是在桌面系统或工作站上进行的,程序排错的过程通 常与系统硬件调试相结合进行,因此程序排错的过程就受到了硬件开发进度的制约,为 了避免出现这种情况,必然需要使用软件或硬件调试支持平台。最后在软硬件开发都完 成后,软件程序就可以下载到实际目标系统中运行和进行系统性能测试了。 嵌入式系统软件开发与一般桌面系统的软件开发相比有很大的区别,主要体现在: 第一,嵌入式系统软件开发通常没有操作系统的支持,一切动作都是由应用程序自行负责。 即使使用了所谓的嵌入式操作系统,许多嵌入式操作系统也是为了节省存储空间而简化了系统

架构,常常由应用程序直接使用外围寄存器来处理系统事件,因此在使用上需要格外注意。 第二,程序编译和程序执行使用两个不同的平台,一个称为宿主平台,另一个称为 目标平台,两个平台之间通过某种通信方式互连。由于使用了两个平台,因此就出现了嵌入式 软件开发的跨平台编译、目标程序下载及远程除错等特殊的环节。 第三,输入/输出界面不同。在嵌入式系统中通常利用按键、触摸屏等作为输入界面,液 晶显示屏或 LED 灯作为输出界面。由于输入输出界面类型的限制,在编制软件时必须要考虑其 特性。 第四,可利用的资源有限,特别是内存空间的限制。嵌入式系统中通常利用微控制器片内 非易失性存储器(如 FI.ASH)存放程序代码,利用片内 SRAM 空间作为程序运行空间。在编制 程序时对其代码长度就要有所考虑,程序运行空间的制约可能是一个更为严重的问题,因此在 程序设计时不仅需要考虑实际代码在存储空间中的安排,还需要考虑如何节约运行空间的开销 和及时释放空闲空间的问题。 第五,与硬件打交道频繁。在嵌入式系统软件中很大一部分程序是硬件设备管理程序及对 硬件事件的处理程序。程序调试过程中有时很难判断是硬件问题还是软件问题,因此软件开发 人员和硬件开发人员必须密切配合、保持良好的互动才能取得事半功倍的效果。 由于应用软件开发越来越复杂,通常需要引入嵌入式操作系统。特别是涉及到内存管理、 多线程管理、外围资源管理的程序,就非常需要一个操作系统来进行统一的调度和管理,这样 就可以大大减少应用程序开发的难度和复杂度。一般嵌入式操作系统主要是提供一个微内核, 其主要的功能包括内存管理、任务管理和外围资源管理等三大项,而图形界面、通信协议等还 需要用户自行开发或购买第三方产品。

嵌入式系统开发工具需求
在当今嵌入式系统市场激烈竞争的今天,要求每一代新产品比以往的产品具有更高的性能 和更低廉的价格,而且由于市场的收缩,使得尽快地把产品推向市场的要求比以往更紧迫。另 一方面,嵌入式系统产品要求的功能越来越复杂,微处理器的功能越来越强大,对嵌入式系统 设计人员提出了越来越高的技术要求,设计人员面临的挑战越来越严峻。同时嵌入式系统设计 过程中,系统软件开发和软硬综合调试的障碍也越来越多,因此对功能强大的软件开发工具的 依赖性也比以往更大。实际上嵌入式系统设计者在挑选微控制器产品时,有没有功能强大的、 界面友好的交互式集成开发系统也是一个重要的选择标准。嵌入式产品开发如果离开调试环境 的帮助,将是一个痛苦而漫长的过程,不仅开发资金和人力资源投入太大,而且往往会因为开 发周期过长而失去占领市场的先机。 嵌入式产品开发人员在产品功能复杂性增加和设计周期缩短的双重压力下,不可能等待硬 件设计完成后再来进行软件设计和系统综合调试,因此借助开发系统的帮助,进行软硬件的同 步设计,一旦实际硬件设计与调试完成,就可以进行软硬件的综合测试,才是正确的做法。 目前的开发工具主要分成 3 大类。第一类是微控制器供应商提供的编译器、程序下载器、 程序调试跟踪器和硬件评估板;第二类是嵌入式实时操作系统;第三类是嵌入式系统软硬件设 计综合平台。在最近的一项 EMF 研究中,专家预测软硬件协同开发工具将以每年 40%的速度 增长。诸多因素将促成这种预期的增长,如知识产权相关产品、片上系统(SoC)设计、软硬件集 成和不断出现的复杂的 64 位设计调试等。 由于嵌入式系统的开发越来越复杂,编译器、程序下载器、程序调试跟踪器和硬件评估板 已成为设计开发人员的必备工具。在要求系统性能最优和程序空间使用最小化的双重利益驱动 下,对高性能编译器的要求越来越强烈,而且为了加快“编辑一编译一调试”的过程,编译器、 下载器和调试 Debug 程序通常都捆绑到了一起。 为了尽可能地缩短产品的开发周期,引入实时操作系统(RTOS)是非常有必要的。引入了 RTOS 以后,软件设计人员可以避免所有的程序开发都从最底层的分支开始编制,而且还可以 使用第三方提供的成熟的功能模块,从而达到缩短开发周期、降低开发风险、节约人力资源的

目的。2003 年实时操作系统的销售额预计将超过 6 亿美元,传统的 RTOS 将持有一定的市场份 额,与此同时新型的、为不断涌现的更高性能微控制器而定制的 RTOS 也将要获得更多的一些 市场份额。 软硬件协同开发平台是嵌入式系统开发人员的最强有力的开发工具。利用软硬件协同开发 平台才能做到软硬件的真正并行开发。软件人员可以脱离实际的硬件系统进行软件的设计与纯 软件的模拟调试,也可以在硬件平台上进行模拟调试。硬件开发人员可以参考平台电路进行电 路的优化设计,从而提供产品的可靠性。 利用软硬件协同平台的开发方式是先进的社会化生产方式,在知识经济下,已形成了一个 重要的产业形式。这种开发方式要求个体产品开发模式转变到平台建设基础上的产品开发思路 上来。软硬件平台将产品软硬件开发所必须的资源最大限度地集合在平台中, 、集合了群体技术 人员大量的智能劳动,把许多产品开发中的基础软硬件工作解决在了平台之中。平台严密的标 准、规范化设计保证有较好的可靠性与简单的使用界面,有利于产品的生产、维修与更新。采 用平台开发模式, 、施行“阶梯模式”可以从根本上解决“板凳模式”的弊端,可以根除产品开 发中大量低水平重复工作;平台最大限度的产品包容性大大缩短了产品开发周期;平台的可靠 性积累,保证基于平台开发的产品具有良好的可靠性。因此利用平台的开发方式是现代电子产 品在现代化大生产方式下产品开发的正确模式。

M·CORE 系统开发工具
Motorola 公司作为一个著名的微控制器生产商,充分认识到了嵌入式系统开发工具对于开 发人员的重要性,因此提供了 M·CORE 系列微处理器的一整套软件开发工具和软硬件协同开 发平台, 同时还制订了应用二进制接口标准(ABI)。 ABI 标准中规定了目标代码文件格式和调 在 试工具 Debug 的信息格式,使得符合 ABI 标准的 M·CORE 微处理器的任何一种开发工具都可 以进行交互调试,同时还解决了产品更新换代时的兼容性问题。 Motorola 公司可以提供高品质的适合 M·CORE 结构的功能强大的产品系列开发工具,这 些开发工具可以互补以支持嵌入式软件开发周期中的每一个环节,因此用户可以放心地认为 M·CORE 结构的微控制器是建立在强大的软件开发工具基础上的产品。 另外 Motorola 公司还密切与第三方软件工具开发商合作,为 M·CORE 结构的微处理器提 供完整的软件开发工具。既有适合 UNIX(SunOS、Solaris、HP—UX)平台的工具,也有适合 Windows95 和 windowsNT Pc 平台的开发工具,用户可以任意选择开发系统的宿主机。 适合 M·CORE 结构微处理器的典型开发工具如表 20.1 所示。

表 20.1

适合 M·CORE 结构的微处理器典型的开发工具
提供者 Diab Data Motorola Software Development Systems Integrated Systems Microtec IxC/OS-Ⅱ网站 Metrowerks Simulation Technologies 宿主机 PC、Sun&HP PC、Sun&HP PC、Sun&HP PC、Sun&HP PC、Sun&HP PC、Sun&HP PC、Sun&HP PC、Sun&HP

开发工具 C 和 c++编译器、连接器、汇编器 GNU C 编译器和 GDB Debugger 程序 SingeStep~单步跟踪 Debugger 程序 pSOSystem~实时操作系统 VRTXmc~实时操作系统 u c/os.II 实时操作系统 CodeWarrior IDE Virtual。CPUTM 的软硬件综合设计平台

1.编译器 Diab Data 公司提供的功能强大的编译软件包含了 c 和 c++编译器、连接器、汇编器,它是

M·CORE 的首选编译器。Diab Data 公司以其先进的技术提供嵌入式目标系统性能最优的、执 行代码最紧凑的编译软件而著称。 这套编译软件可以在 Windows95、 WindowsNT、 SunOS、 Solaris、 HP—UX 等基础平台上运行。 Motorola 公司提供了、GNU C 编译器和 GDB Debugger 程序。这些软件是 M·CORE 的免费支持软件。GNU 编译器与廉价的评价板结合可以为开发者提供一个低成本的解决 方案。GNU 编译软件同样适合在 Windows95、windowsNT、SunOS、Solaris、HP—UX 等 基础平台上运行。 2.程序跟踪器 Software Development Systems 公司提供了一个名为 SingeStep@的程序单步跟踪器,这是一 个使用非常方便的可视化跟踪调试环境。 SingeStep~综合了支持整个工程开发生命周期中每一个 环节的一系列工具: ·指令集模拟器可以在目标硬件完成之前用来帮助调试应用程序和估算性能。目标监视器 和 OnCE 连接器可以用来与嵌入式目标系统相连提供有效的程序追踪。 SingeStep@单步跟踪器适合在 Windows95、WindowsNT、SunOS、Solaris、HP—Ux 等 基础平台上运行。 3.实时操作系统 Integrated Systems 公司提供了一个名为 pSOSystern 的、完善的、可升级的实时操作系统。 pSOSystem~包含了多任务内核、文件系统和广域网协议。另外该公司还提供成熟的综合系统开 发工具包,开发人员在嵌入式系统产品开发整个过程的每一个环节都可以使用。pSOSystem~适 合在 Windows95、WindowsNT、SunOS、Solaris、HP—ux 等基础平台上运行。 Microtec 公司提供了一个名为 VRTXmc~的内核,该系统是 VRTX~实时操作系统产品家族 中的最新成员,在最小化 RAM 和 ROM 空间方面是最优秀的,可以固化支持低功耗模式。 VRTXmc~适合在 Windows95、WindowsNT、SunOS、Solaris、HP—UX 等基础平台上运行。 ?C/os—II 是一个源码公开的实时多任务操作系统,具有内核小、可移植性强、可固化、 可裁减、可确定性好、可靠性高等特点,基本上可以与商业化的操作系统媲美。目前该操作系 统已有几百个成熟的应用范例。在此基础上开发的各种协议栈(如中文平台、蓝牙协议、衄)也比 较丰富。 ?C/OS—II 适合在 Windows95 基础平台上运行, 可以从?C/OS—II 网站上免费下载。

软件综合开发平台
Metrowerks 公司提供了一套称为 CodeWardor IDE(集成开发环境)的软件包,集成 了源代码编辑器、源代码浏览器、C 或 C++编译器、汇编器、连接器、Debuger 程序等工 具软件。CodeWarrior IDE 适合在 Windows95、WindowsNT、Mac OS、Solaris、L,inux 等 基础平台上运行。 OnCE Motorola 公司为 M·CORE 结构的微处理器内置了一个片上 Debug 模块,也称为片 上仿真模块 OnCE(On Chip Emulation)。OnCE 使用标准的 JTAG 接口与芯片相连,允许 开发人员快速建立与目标系统之间的 Debug 链接。OnCE 利用一条对软件跟踪调试特别 有效的扫描链来保证开发系统的高效率。 OnCE 除了普通的 JTAG 接口之外,还提供了一组强有力的 Debug 辅助端口(如 Debug 寄存器),开发人员可以通过监视程序变量的读/写追捕到数据中断问题。 M·CORE 的 ABI 为了保证 M·CORE 结构的系列开发工具能够完全兼容和互操作,Motorola 公司定 义了 M·CORE 结构的 ABI。ABI 标准的定义遵守了两条基本原则:标准接口的使用可

以进一步进行程序运行性能和器件功耗的最优化;标准接口的使用可以尽可能地做到与 M68000 的 c 语言程序保持兼容。 ABI 标准的制定,希望在以下三个层面做到二进制兼容: ·不同编译器生成的目标模块之间; ·目标模块和 M·CORE 处理器之间; ·目标模块和源程序级调试工具之间。 ABI 强制标准定义的内容包括: (1)底层执行代码二进制接口标准,包括: ·微处理器相关的二进制接口:定义了指令集、基本数据类型表示、故障处理。 ·函数调用协议:定义了参数传递和结果返回方法、调用堆栈结构方式。 由于应用程序组件的不确定性,实时操作系统和协议栈对嵌入式系统开发人员变得 越来越重要。为了能够在一个应用系统中方便地、正确地运行第三方提供的组件库中的 程序,ABI 标准函数调用协议中规定了函数入口参数传递寄存器、堆栈指针寄存器和链 接寄存器。 (2)目标文件二进制接口标准,包括: ·文件头协议; ·段落划分; ·符号表格式; ·重定位信息格式; ’ ·Debug 信息格式。 目标模块格式是基于 EL,F2.0 标准定义的, :Debug 信息是基于 DWARF.1.1 标准定义 的,M·COREABI 做了少量修改。 (3)源程序级标准,包括: ·C 语言:规定了预处理器预定义、汇编指令嵌入、符号名映射等内容; ·汇编语言:规定了基本语法和伪指令。 (4)函数库标准,主要定义了浮点表示和长长整数(64 位整数)表示。 Motorola 公司设计了一个工具确认程序,可以用来验证各种工具软件的 ABI 兼容性 及与其它工具软件的互操作性。该测试程序还可以用来测试工具软件的函数正确性、与 行业测试集(例如 C 或 c++的:Plum. .Hall 测试)的兼容性、与运行基准的适合力、使用 方便性、文档资料/安装发布等功能。经过这些测试的工具集基本可以保证是高品质的、 高效率的和方便整合的。 M·CORE 软件开发过程与开发工具的结合 M·CORE 软件开发经历的每个阶段及各阶段可使用的主要开发工具如表 20.2 所示。 表 20.2 M·CORE 软件开发过程及开发工具的使用
┏━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ 步骤 ┃ 任 务 ┃ 建议使用的开发工具 ┃ ┣━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃第一步 ┃源程序编辑 ┃任何类型的文本文件编辑器、CodeWarrior IDE ┃ ┣━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ ┃源程序编译 ┃ ┃ ┃第二步 ┃ ┃GUN 软件包、CodeWarrior IDE、Diab Data 提供的 c,C++编译器 ┃ ┃ ┣━━━━━━━┫ ┃ ┃ ┃源程序汇编 ┃ ┃ ┣━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃第三步 ┃目标代码连接 ┃GUN 软件包、CodeWarrior IDE、Diab Data 提供的连接器 ┃ ┣━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃第四步 ┃源程序调试 ┃GNU-gdb 与 Picobug、CodeWarrior IDE;EVB/CMB3118 开发板┃

┣━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃第五步 ┃目标代码下载 ┃SysDS Loader ┃ ┣━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃第六步 ┃目标代码运行 ┃目标系统(目标系统复位后应用程序自动运行) ┃ ┗━━━━┻━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

1.2. CodeWarrior IDE 的使用

本节简单介绍使用 CodeWarrior IDE 建立工程文件、编辑源程序、进行程序编译一连 接、目标代码下载运行的全过程。

建立 CodeWarrior IDE 工程文件
工程文件包含所有的库和工具设置信息,这些信息是在工程文件创建过程中生成的。创建 工程文件的基本步骤为: 启动 CodeWarrior IDE,点击“文件菜单”(File Menu)项,然后选择“新建’ ’(New)功能,将弹 出一个对话界面。 ②从该窗口的选择列表中选取合适的 M·CORE 开发板,如选定“MCore EABI 2107”开发 平台,指示使用 EVB2107 评估板,并预建了一个用来存放源程序、特殊头文件、运行文件、连 接命令文件和最终工程文件的目录。 ⑨点击工程名输入框,输入工程文件名(如 sample.mcp)。 ④点击定位选项,CodeWarrior 缺省建立一个与工程文件同名目录(如 sample),用于存放该 工程下的源程序文件、头文件和 CodeWarrior 生成的其它文件。也可以使用“Set”按钮选择不 同的目录。 ⑤完成上述设置后点击“OK”按钮,将弹出一个新的工程文件对话框,如图 23.3 所示,其中 包含了一个选择列表,通过这一列表设置工程及 Debug 的接口,这些内容实际上就是工作目录 的层次结构。 在该窗口中 CodeWarrior 要求设置开发板类型(如选 EVB)、Debug 接口(如选 EBDI)和程序 设计语言(如选 C 语言)。完成这些设置后,CodeWarrior 已完成创建工程所需要的全部设置,按 “OK”按钮,将弹出一个以工程名命名的窗口,如图 23.4 所示。 ⑥至此,用户工程文件创建完毕,用户可以浏览该样板工程中的所有资源。在图 23.4 所 示的工程窗口中可以看到 4 个树形控制的文件组:源程序文件组、MSL(M·CORE 支持库)文件 组、运行文件组和 UART 文件组。 源程序文件组中至少需要包含一个名为 main.c 的文件,也可以包含其它用户设计的源程序 文件。双击相应文件名就会自动弹出编辑窗口,显示指定文件内容。 MSL 组中包含了两个库文件: MSI_C. MCore. bare. BE. 和 MSL_UART_surport. a BE. a。 前者是 C 程序的基本输入输出支持库,后者是源程序与跟踪器之间的接口库。 运行文件组包含了两个与程序运行环境定义相关的文件 runtime.McoreEABI.BE.a.和 linker.Icf。前者初始化运行环境,使得程序可以在 EVB 板上运行;后者是连接命令文件,用 来管理连接操作。 UART 文件组中包含了两个“README”文件,是环境使用帮助信息文件。

修改工程文件及源程序
1.修改工程文件 多数样板工程文件中都包含有占位源程序文件,用户可以使用自己的文件替换它们。向工程 文件中添加文件,按下列步骤进行: ①选择工程“Project. ”菜单项中的添加文件功能项“Add Files” ; ②拖拉桌面上或其它目录下的文件到工程文件中。 若要从工程中删除文件,只需选中工程窗口中的指定文件,然后按“删除”选项。 2.源程序文件编辑和修改 源程序文件为纯文本文件,可以使用:IDE 编辑器和第三方编辑器编辑或修改。在 IDE 工 程窗口中双击文件名或选中文件,然后按回车键,将自动进入编辑窗口,然后可以使用编辑器 提供的所有功能来编辑或修改文件。 也可以在工程窗口中选择文件操作 “File” 菜单项中的 “New” 功能,然后在弹出的窗口中选文件“File”来编辑一个新的源程序文件。 3.修改对象设置 样板工程文件中的初始设置是合理的,但不一定适合特定用户的需要。用户可以修改这些 配置信息,如增加代码优化功能、更改输出文件名、取消编译器特定的告警信息等。 要修改对象配置,首先必须确认是当前对象。在工程主界面上选择编辑“Edit”菜单,选中 “…Settings”功能项(“…”代表当前工程对象名),出现当前对象设置窗口,如图 23.5 所示。 确认当前对象的另一种方法是,在工程窗口中选中“targets”功能项,然后在显示信息区域中双 击工程对象名。 对象配置选项被分成了许多组,在对话框的左侧列出。选中一个组后在对话框右侧列出该 组选项的内容。用户可以同时打开多个工程对象,某些选项组影响所有的工程对象, 有些选项组附属于程序设计语言,还有些选项组是特定工程对象特有的。特定工程对象特 有的选项组主要是与代码生成和连接器输出格式相关的设置。

生成可执行代码
生成可执行代码的过程就是编译和连接的过程,在这一过程中,需要根据连接命令为源程序 中的代码和变量分配存储空间。 1.程序和数据的分段结构 M·CORE 的执行代码分成若干个段,每个段中包含不同类型的数据。通常情况下至少包 括代码段、数据段和未初始化数据段。代码段中放置可执行代码,当前工程中所有相关文件(包 括源程序文件和 Codewarrior 支持库)的可执行代码都放入该段;数据段中放置常数数据、只读 数据和带初始值的数据,其数据同样来自于当前工程的所有相关文件;未初试化数据段中放置 所有不带初始值的数据,在目标文件中不分配存储空间,只需要在物理存储器中分配空间。表 23.1 给出了 ELF 格式目标文件中定义的各种常用段及其用途。 表 23.1 E1 月格式目标文件常用段定义
┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓ ┃ 段名 ┃ 内 容 ┃ 附 加 信 息 ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫ ┃ .bss ┃ 未初始化大数据 ┃ 由于数据未初始化,该段不占用文件空间 ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫ ┃ .C0r11nlent ┃ 版本控制和其他信息 ┃ 常用来保存程序设计人员信息 ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫ ┃ .data ┃ 已初始化大数据 ┃ 该段占用文件空间,还可能需要初始化代码 ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫ ┃ .Debug ┃ Debug 信息 ┃ ELF 规范中对该段内容未作规定 ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫

┃ .1ine ┃ Debug 使用的符号行信息 ┃ ELF 规范中对该段内容未作规定 ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫ ┃ .relname. ┃ ┃ ┃ ┃ ┃ 连接器使用的重定位信息 ┃ 符号表中元素项引用入口和对应的段 ┃ ┃ .relaname ┃ ┃ ┃ ┣━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━┫ ┃ .rOdata ┃ 常数数据 ┃ 可以放在 ROM 中的数据,占用文件空间 ┃ ┗━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━┛

(续) ┏━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ ┃ 段名 ┃ 内 容 ┃ 附 加 信 息 ┃ ┣━━━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫ ┃.sbss ┃未初始化的小数据 ┃由于数据未初始化,该段不占用文件空间 ┃ ┣━━━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫ ┃.sbss2 ┃可写的小数据 ┃数据项被初始化为 0 且占用文件空间 ┃ ┣━━━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫ ┃.sdata ┃已初始化的小数据 ┃该段占用文件空间且需要初始化代码 ┃ ┣━━━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫ ┃.sdata2 ┃小常数 ┃可以放在 ROM 中的数据,占用文件空间 ┃ ┣━━━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫ ┃.symtab ┃符号表 ┃保存与代码或变量相关符号的信息 ┃ ┣━━━━━╋━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━┫ ┃.text ┃可执行代码 ┃存放机器码 ┃ ┗━━━━━┻━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━┛ 2.连接命令文件 在源程序编译和连接时,必须知道程序代码分成多少个段,各段中包含的数据类型,在物理 存储空间中的起始地址和访问控制方式等信息。CodeWarrior 通过连接命令文件 linker.lcf 来确 定这些分段信息,在编译器开始对源程序进行编译之前用户必须编制好这个文件。 使用 CodeWarrior 编辑器打开连接器命令文件可以看到如下程序代码: # linker.Lcf- Motorola MCore 2107 系列连接器命令文件; MEMCIRY { TEXT(RWX) :ORIGIN=0x00800000,LENGTH=0x00000000 DATA(RW) :ORIGIN 1 AFTER(TEXT),LENGTH=0x00000000 BSS(RW) :ORIGIN=AFTER(DATA),LENGTH=0x00000000 } SECTIONS { .main_app: { *(.text) *(.rodata) } >TEXT .main_app_data: { .=ALIGN(Ox4); // 以 4 字节对界放置 _data_ROM_begin=. ; *(.data) _data_ROM_end=. ;

*(.vtables) // VIRTUAL 类型函数表 *(.exception) // 异常表 .=ALIGN(Ox4); // 以 4 字节对界放置 _exception_table_start_=. ; EXCEPTION _exception_table_end =. ; __sinit=. ; //静态初始化 STATICINIT }>DATA .main_app_bss: { __bss_begin=.; *(.bss) __bss_end=. ; }>BSS __stack_end =. ; // CodeWarrior 运行库用来设置堆栈空间 __stack_begin=__stack_end+Ox00000800; __stack_begin=(__stack_begin+7)&~7 __heap_addr =__stack_begin; //MSL 库用来设置堆空间 __heap_end =__heap_addr+0x00000800; __heap_size =__heap_end-__heap_addr; __data_begin =__data_ROM_begim //设置影子 RAM 地址 __data_size =__data_ROM_end-_data_ROM_begim } 1inker.lcf 文件中的第一条命令为“MEMORY”指示,描述了可执行代码和数据在存储空间 中的最终映像。每一行定义了一个存储段,其中包括段名、段存取控制标志、段起始地址和段 长度。第一个存储段标识为“TEXT” ,用来存放程序代码,其存取控制标志“RWX”表示该段 可读、 可写(赋予代码段写控制方式是为了在程序调试过程中 CodeWarrior 跟踪器能够插入断点, 当最后生成下载至 ROM 的代码时,应取消该控制权限)、可执行; “ORIGIN”参数指出存储空 间起始地址为 Ox00800000; “LENGTHT”长度参数为 0,表示该段长度可以为任意多个字节。 第二段标识为数据段,用来存放数据,其存取控制方式为可读、可写;紧接着代码段存放;长 度任意。最后一段标示为“BSS” ,用来放置未初始化数据,存储控制方式为可读、可写;紧跟 着数据段存放;长度任意。 Linker.lcf 文件中的第二条命令为“SECTIONS”指示,用来定义各段中的数据安排。第一 段标识为“.main_app” ,对应应用程序与支持库中的代码(.text 段)和可放入 ROM 中的常数数据 (.rodata 段) ;选项“TEXT”指出把这些内容放到 存储空间的 TEXT 段。第二段标识为 “.main_app_data” ,对应应用程序和支持库中已初始化数据(.data)、VIRTUAL 类型函数表 (.vtables)、异常表(.exception)及静态初始化代码。已初始化数据段(.data)前面的“.=ALIGN(0x4)” 语句是定位计数器的对界语句,指示紧接着其后的第一个数据地址必须能被 4 整除,即处于 32 位边界上(可以插入空数据来满足这一要求),从而提高存储器带宽,进而提高程序运行效率。 “.data”段还被一对引用定位计数器当前值的“dataROM”语句了起来,这表示该数据段的原 始初始化数据存放在 “__data_ROM_begin” “__data_ROM_end” 和 这两个符号表示的地址之间, 因为该段中包含的一些变量需要在 程 序 启 动 时 进 行 初 始 化 , 而 初 始 化 程 序 引 用 的 原 始 数 据 必 须 放 在 ROM 中 。 符 号 “__exception_table_start__”和“__exception_table_end__”记录了异常表的起始和结束地址。 第三段标识为“.main_app_bss” ,对应源程序和库中的所有已初始化数据。紧接着该段定义了程 序栈(自下向上生成,2KB),其栈顶地址使用符号“stack_begin”保存,CodeWarrior 启动目标 程序运行时将引用该符号。再后面是 2KB 的堆和数据段(.data)在实际 RAM 中的运行空间。

3.程序代码与数据的分离 从前一节的连接命令文件中可以看出,整个程序代码和数据都被安排到了 RAM 空间中, 并在 RAM 空间运行,但这样的安排仅仅是为了程序跟踪的需要,而不是嵌入式系统的实际运 行环境。在实际的嵌入式系统中,程序应存储并运行在非易失性的只读存储器或 FLASH 中,变 量数据存储在容量较少的 RAM 空间中。 实际程序中有多种类型的数据, 如.rodata 和.data。 .rodata 类型的数据是常数数据,也应存放在 ROM 类存储器中。.data 类型的数据是已初始化数据,所 以连接器必须保存其原始初始化值,实际上数据段中的大多数信息(如 virtual 类型函数表、异常 表和已初始化数据)都需要存放在 ROM 类存储器中,真正可以存放在 RAM 存储器中的数据只 有未初始化数据(即在 BBS 段中定义的数据)。 因此连接命令文件应做一些修正,通过下面描述的连接命令文件把程序代码和数据分离。 MEMORY { VECTORS(R):ORIGIN=0x8100C000,LENGTH=0X00000200 TEXT(R)():ORIGIN=0x8100C200,LENGTH=Ox00000000 ROMDATA(R):ORIGIN=AFTER(TEXT),LENGTH=Ox00000000 DATA(RW):ORIGIN=Ox800000,LENGTH=0x00001000 BSS(RW) :ORIGIN=AFTER(DATA),LENGTH=Ox00000000 } SECTl0NS { .vectormap: //定义向量表,放在最前面。 { .=ALIGN(Ox400); //向量表 1KB 对界。 __exception_table_begin=. ; vector_table.c(.rodata) // 向量表文件。 __exception_table_end=.; } >VECTORS //向量表空间映像,偏移地址 Ox000~Ox1FF .main_application: //定义程序代码段 { startup.c (.text) //复位起始程序 standalone.c (.text) //主程序 isr_PIT.c (.text) // PIT 中断服务程序 *(.text) }>TEXT //代码段空间映像,偏移起始地址 0x200 __data_begin=0x800000; .main_application_data; //定义数据段, { //需要复制到 RAM 的已初始化变量 *(.rodata) //保存在 ROM 中的常数 .=ALIGN(0x1); __data_ROM_begin=. //记录数据复制起始地址 ; *(.data) //所有模块中的数据 _data—ROM_end=. ; //记录数据复制终止地址 *(.vtables) *(.exception) __sinit_=. //仅用于 C++程序 ; STATICINIT }>ROMDATA .main_app_bss: //未初始化数据,被 startup.c 赋 0 值 {

__bss_begin=. ; *(.bss) __bss_end=.; }>BSS __stack_end =(.+)&~7; // 定义程序栈空间 __stack_begin = __stack_end+Ox0400; __alt_stack_end =__stack_begin; //定义交换栈空间 __alt_stack_begin =__alt_stack_end+Ox0400 __heap_addr =__alt_stack_begin; //定义堆空间 __heap_end =__heap_addr+Ox0400; __heap_size =__heap_end-__heap_addr; __data_size=__data_ROM_end-__data_ROM_begin; //定义 RAM 实际运行空间 __exception_table_size=__exception_table_end-__exception_table_begin; } 在这个连接命令文件中,新出现了一个名为“VECTORS”的段,长度为 512 字节,存储控 制方式为只读,用来存放中断向量表。向量表之后是用来放置可执行代码的“TEXT”段和用来 放置只读数据的“ROMDATA’ ’段。 “ROMDATA”段中包含了常数定义和对 RAM 空间进行初 始化的原始数据。 “DATA’ ’和“BSS”存放着所有的变量,其起始地址 0x800000 正好对应着 MCU 的片内 SRAM。在该连接命令文件中需要强调两点: .中断向量表必须放置在连接命令文件的最前面,而且必须 1024 字节对界。 .该连接命令文件中没有提及“DATA’ ’的内容安排,由 MEMORY 指示保证其存在并对 应 SRAM 空间。 连接命令程序的改动使得一个在 Debug 跟踪环境下的程序转变为一个实际可独立运 行的嵌入式程序。可独立运行的程序是指嵌入式程序实现了初始化和配置,可以独立在硬件环 境中正确运行的程序,而不再需要其它软件的支持。生成一个程序的可独立运行代码需要处理 好以下 5 个环节: (1)程序必须包含对处理器初始化的代码,如初始化堆栈指针、装载 VBR 寄存器等。 (2)程序必须包含运行环境建立代码, 完成所有数据的初始化, 如对所有未初始化数据清零, 对所有已初始化数据从 ROM 中复制原始值等。 (3)程序必须包含对硬件环境初始化代码,如激活存储器端口和外围设备的片选、初始化程 序中用到的所有外围器件等。 (4)程序最终映像必须提供中断向量表。如果程序中使用了中断,相应的中断服务程序入口 地址必须设置在向量表的正确位置。对程序中没有用到的中断,也必须提供一个缺省的配置地 址。复位向量必须指向程序入口地址。 (5)必须建立正确的空间映像。连接器根据连接命令文件组织程序代码和数据映像。 CodeWarrior 对这些必要的准备工作提供了支持程序。表 23.2 列出了实现应用程序独立运行所 必要的程序文件和每个程序中要引用的符号。 文件名 功 能 使用场合 引用的符号 startup.c 设置程序栈和交换栈 第一步 __alt_stack_begin 指针,初始化向量基 __mt_stack_end 地址寄存器 __bss_begin __bss_end __stack_begin __stack_end __vector_table main _start defined rom_copy.c 安排把已初始化数据 第二步 __data_ROM_begin

strcpy.c standalone.c isr_trap_stubs.0 vector_table.c linker.1cf

从 ROM 复制到 RAM 的 参数 完成把已初始化数据 从 ROM 复制到 RAM 主程序,初始化 MCU 外围器件和系统环境 为向量表中的空位置 提供中断服务程序 建立中断向量表 连接命令文件

__data_begin __data_size 第二步 第三步 第四步 第四步 第五步 _start __vector_table 定义 程序空间映像 main 定义

4.代码生成 在完成 CodeWarrior 环境设置、源程序编辑、连接命令文件指派等工作之后,就可以对源 程序进行编译和连接操作了。编译和连接通常是结合在一起进行的,其运行结果生成 可执行代码文件和空间映像文件。可以通过查看空间映像文件的内容来确认连接命令文件中的 各项安排是否恰当和是否符合预想的效果。 当然编译和连接也可以分开进行。可以使用 CodeWarrior 编译器编译工程中的单个文件、一组 文件或全部文件。 ‘选中工程窗口中 V 程菜单项(Project)下的编译(Compile)功能,将弹出一个代 码创建窗口,如图 23.6 所示。窗口中显示被编译文件的文件名和行计数,状态行中显示着要 编译的支件总数。工程窗口的底部还显示着正在进行编译的文件总数。选中工程窗口中的工程 菜单项(Project)下的编译(Make)功能,且指定工程类型为应用(Application)时,CodeWarrior IDE 编译当前工程中新增的和修改过的文件,并把所有代码连接成为一个可执行的应用目标程序。

目标代码调试
程序可执行代码生成后,可以使用 CodeWarrior IDE 提供的 Debug 功能进行调试。选中工程 窗口中工程菜单项(Project)下的跟踪(Debug)功能, 工程窗口中弹出一个对话框, 显示 CodeWarrior 试图与目标系统建立连接。连接完成后,该对话框被程序下载对话框取代,下载对话框显示程 序的下载进度。下载完成后出现跟踪器操作窗口,如图 23.7 所示。窗口中源程序栏的蓝色小 箭头表示 MCU 程序计数器当前指向的指令。 1.程序运行 点击工程窗口中工程菜单项(Project)下的运行(Run)功能项或跟踪器窗口顶部类似于录音机 播放键的按钮,程序立即开始运行,直到程序终止或遇到断点。 2.单步执行 单步执行是指源程序每次只执行一行源程序。选择工程窗口中跟踪菜单(Debug)下的单步 (Step Over)功能项或点击跟踪窗口中的单步图标,进行源程序的单步调试,如图 23.9 所示。如 果当前源程序行是一个函数调用,并且函数中没有断点或嵌套调用其它函数,则执行整个函数。 3.进入函数体 在程序跟踪过程中,如果需要进入函数内部进行跟踪调试,可以选择工程窗口中跟踪菜单 (Debug)下的函数进入(StepInto)功能项或点击跟踪窗口中的函数进入图标。 4.退出函数

如果要执行完一个内层函数剩余源程序返回到调用者,可以选择工程窗口中跟踪菜单(Debug)下 的函数退出(Step Out)功能项或点击跟踪窗口中的函数退出图标。 5.跃过语句 有时可能希望某些语句不执行而直接跃过,那么可以通过下列两种手段修改当前源程序行 指示箭头,使其指到下一条希望执行的语句前: ·直接拖拉当前源程序行指示箭头到目标语句。 ·使用改变程序计数器对话框。 这种操作实际上是修改了 MCU 的程序计数器值,如果使用不当,有可能会导致程序运行 异常,因此应慎重使用。 6.程序运行暂停 在程序运行过程中, 可以发出停止命令, 暂停程序运行, 而后可以使用单步执行命令或 RUN 命令从停止位置继续程序的执行。 需要注意的是,由于程序运行速度很快,停止命令的程序暂停位置是不精确的。如果需要 在特定地址暂停程序执行,可以通过设置断点的方法实现。 7.终止跟踪 在某些情况下,用户如果需要终止程序调试过程,退出 Debug 环境,可以使用 Kill 命令。 8.程序复位 程序复位(选用工程窗口中 Debug 菜单下的 Restart 功能)相当于首先做了一个 Kill 命令,然 后立即又启动了一个 Debug 命令,程序恢复初始态,重头开始进行跟踪和运行。 9.设置和取消程序断点 设置/清除单个断点有三种方法: (1)点击编辑器窗口的源程序栏或跟踪窗口的源程序栏或符号窗口的源程序栏相应源程序行 前的断点设置列,出现一个圆点标记,表示在该位置设置了一个断点。程序运行到该处将暂停 运行。点击该标记将清除该断点。 (2)在跟踪窗口的源程序栏, 点击需要设置断点的源程序行, 选择工程窗口中跟踪菜单(Debug) 下设置断点(Set Breakpoint)/清除断点(Clear Breakpoint)功能。 (3)选择工程窗口中跟踪菜单(Debug)下的设置/清除断点(Set/Clear Breakpoint)功能,在 弹出的断点设置和清除对话框中输入断点地址或符号。 与断点操作相关的功能选项还有: ·使能断点:使当前行的断点有效。 ·禁止断点:使当前行的断点无效。 ·清除所有断点:把所有断点清除。 ·显示断点:如果当前行的断点是隐藏的,显示该断点。 ·隐藏断点:如果当前行的断点是可见的,隐藏该断点。 10.显示和更改数据 能够观察和更改当前状况下的各种变量、寄存器和存储空间的数据是跟踪器应具备的基本 功能,这样用户才能清楚知道程序运行细节,试验各种可能的运行参数。 (1)查看局部变量 局部变量在跟踪窗口的变量栏显示(如图 23.7 所示)。如果变量是句柄、指针或结构类型的, 可以点击变量名前面的层次控制符显示其内容。 (2)查看全局变量 需要查看全局变量的内容时,首先通过选择工程窗口中查看(View)菜单下的全局变量窗口 (Global Variables Window)功能项或选择工程窗口中窗口(Window)菜单下的全局变量窗口(Global Variables Window)功能项打开全局变量观察窗口,然后点击文件栏中的全局变量项,在随后出 现的全局变量栏中就可以看到全局变量的具体内容了。 (3)在新窗口中显示数据.

在变量栏或全局变量窗口中观察数据不方便时,可以把一个或一组变量放到一个新窗口中 观察。打开变量或存储空间的单独观察窗口只需双击变量或数组名,或选择数据(Data)菜单项下 的 显 示 变 量 内 容 (View Variable)/ 显 示 数 组 内 容 (View Array) / 显 示 存 储 空 间 内 容 (View Memory/View Memory As)命令。 (4)修改变量的值 在任何变量显示的场合都可以修改变量的值,其方法是双击变量或选中变量后键入回车, 然后输入变量的新值。 (5)显示修改存储单元内容 显示或修改存储单元内容的方法是:首先,选择能够表示特定存储空间基地址的一个数据或 表达式;然后选择数据(Data)菜单下的显示存储器(View Memory)功能,将会弹出一个窗口,以 十六进制或 ASCII 码的方式显示一片存储单元的内容, 可以在该窗口中直接修改对应单元的值。 可以直接更改存储单元显示窗口顶部的地址栏,以选择新的显示区域。 (6)显示指针所指的存储单元内容 数据(Data)菜单下的存储单元显示(View Memory 或 View Memory As)命令允许根据指针(包括 寄存器内容作为地址)显示存储单元内容。 显示指针指向的存储区域内容按下列的步骤进行: ①在变量或寄存器出现的窗口中选中变量或寄存器的值。 ②选择数据(Data)菜单下的存储单元显示(View Memory 或 View Memory As)功能。 如果使用 View Memory 命令,将弹出一个窗口,显示指定存储单元的内容,其起始地址为指针指向的单 元, 该项操作结束; 如果使用 View Memory As 命令, 将会弹出一个要求输入数据类型的对话框。 ③在对话框类型栏中选择数据类型。如果要显示寄存器内容指向的存储单元,应在类型名 前加星号。 ④点击对话框中的“OK”按钮,将打开一个新窗口显示指针指向存储区域的内容。 (7)显示处理器寄存器的内容 选中显示(Ⅵew)菜单下的寄存器显示(Registers Windows)功能中的通用寄存器显示(General Registers)子功能可以看到处理器内所有通用寄存器的值。

1.3. Codewarrior for M·CORE 概述

1.3.1. 工程项目窗口

1.3.2. 简单工程项目的使用

1.4. 简单工程项目的使用

1.5. 配置生成目标 1.6. 复杂工程项目的使用 1.7. 工程项目模板 1.8. 编译和连接工程项目