CM3-读书笔记《Cortex-M3权威指南Cn》-2

目的:找到一种适合的多平台的开发环境

在本文后将详细描述ECLIPSE+GCC的免费开源环境搭建 和一系列demo工程

 (时间紧凑,先摘录原文,回头会来写体会)

开发工具
  在开始使用Cortex ‐ M3之前,需要准备好一些开发工具,典型的如: 
z   编译器/ 汇编器:把C 和汇编源程序转换成目标文件。几乎所有的C 编译器套件都
包含了对应的汇编器。 
z   指令系统模拟器:模拟指令的执行,用于在软件开发早期的调试。 
z   在线仿真器(ICE )或者调试探测器(probe):连接到电脑和目标板上的调试硬件,
与目标板的接口通常是JTAG 或SW。 
z   一块开发板。 
z   跟踪捕捉仪:可选的硬件设备和周边软件,可以用它来捕捉来自 DWT 以及ITM 的
输出,并且以可读的形式显示出来。 
z   嵌入式操作系统:在单片机上运行的操作系统。这也是一个可选件,许多简单的应
用程序不需要操作系统。但是在开发复杂度较高或者有高性能指标的系统时,常常
需要使用。 
C 编译器
  截止到目前,已经有若干个C 编译器套件可以使用了,如表17.2 所列。 
表17.2   支持Cortex ‐ M3的开发工具

 

 

使用GNU工具链开始Cortex-M3开发

 

 

背景
  GNU 工具链在ARM 产品开发中使用得很广泛,并且有些为ARM 打造的开发工具也是
基于GNU 工具链的。在目前,支持CM3 的GNU 工具链可以由CodeSour c er y 处免费下载到
(ww w.c odesourcer y.com)。而GNU 的主打C 编译器则在以后支持CM3 (在2008年3 月31
日以后,主流的GNU 工具链已经支持Cortex‐ M3,对应的开发工具为WinARM——译者注)。 
  本章只介绍使用GNU 工具链的基础知识,更详细的信息还需要参阅联机帮助文档。值
得一提的是,GNU 的汇编语法(GNU 工具链中的AS程序)与ARM 的汇编语法是有些不同
的。这些不同点包括变量定义、编译指示字、以及the   lik e。因此,使用ARM   Rea lView 工具
的汇编代码在使用GNU 工具前,还需要一些(很枯燥的)修改工作。 
获取GNU工具链
  编译好的GNU 工具链可以从w w w.codesourcer y.com/gnu_toolchains/a rm/ 处下载。有一系
列的二进制构建版本。对于最简单的使用,可以使用EABI(EABI表示嵌入式应用程序二进制
接口。可执行目标文件必须符合该规格,从而可以跨开发工具集使用),并且没有嵌入式OS
的版本。这个工具链既有在Windows 上使用的版本,也有在Linux上使用的版本。本章给出的
示例程序可以用于任何一个版本上。 
开发流程
  和ARM 开发工具的相似,GNU 工具链也包含了编译器、汇编器和连接器,从而使得源
代码既可以使用C,也可以使用汇编写成,如图19.1 所示。

 

  不同的应用程序环境中也有不同版本的工具链(Symbian,   Linux,  EABI 等)。取决于工具
链的目标平台,相应的可执行文件通常有一个前缀。例如,如果使用了EABI 环境,则GCC
命令为arm ‐ xxxx ‐ eabi ‐ gcc。本章的目标代码使用 CodeSourcery 的GNU   ARM 工具链,如表19.1
所示。 
表19.1   winARM20080331  GNU 工具链的命令名称

在开发流程图中,连接脚本是可选的。但是当存储器映射比较复杂时,常常是必需的。

例 5:纯 C 程序
  想必大家已经受够了在汇编下过的日子吧!在GNU 工具链中的一个主要组件就是C 编
译器。在本例中,整个可执行程序——甚至是复位向量和MSP 初值都由C 写成。此外,还
添加了一个连接器脚本,用来把各段放到正确的位置。那么,先让我们看一看C 程序文件。 
========== example5.c ==========
#define STACK_TOP   0x20000800
#define NVIC_CCR   ((volatile unsigned long *)(0xE000ED14))
//  声明函数原型
void myputs(char *string1);
void myputc(char mychar);
int main(void);
void nmi_handler(void);
void hardfault_handler(void);
//  定义向量表
__attribute__ (( section(“vectors”) ))  void (* const VectorArray[])(void) = 
{
 STACK_TOP,
 main,
 nmi_handler,
 hardfault_handler
};
 
//  主程序入口点
242  
 
Cortex ‐ M3权威指南  初稿  第19章 
int main(void)
{
  const char *helloworld[]="Hello world\n";
  *NVIC_CCR = *NVIC_CCR | 0x200; /*  设置NVIC 的STKALIGN */
 myputs(*helloworld);
 while(1);
 return(0);
}
 
//  函数
void myputs(char *string1)
{
 char mychar;
 int j;
 j=0;
 do 
 {
  mychar = string1[j];
  if (mychar!=0) 
  {
   myputc(mychar);
   j++;
  }
  } while (mychar != 0);
 return;
}
void myputc(char mychar)
{
  #define UART0_DATA ((volatile unsigned long *)(0x4000C000))
  #define UART0_FLAG ((volatile unsigned long *)(0x4000C018))
  // Wait until busy fl ag is clear
  while ((*UART0_FLAG & 0x20) != 0);
  // Output character to UART
  *UART0_DATA = mychar;
 return;
}
 
//空的服务例程
void nmi_handler(void)
{
 return;
}
 
void hardfault_handler(void)
243  
 
Cortex ‐ M3权威指南  初稿  第19章 
{
 return;
}
========== end of file ==========
注意粗体字显示的部分,它使用  __attribute((  )) (注意,是双小括号)来指定特殊的属
性。在这里则指出那个函数指针数组是放到vectors 段中的。然而,这个C 程序并没有指定
vectors 段在何处。那么在哪里指定 vectors 段的位置呢?现在该请出我们的连接器脚本文件
了,工作就在这里完成。本例的连接器脚本文件为simple.ld ,内容如下: 
========== simple.ld ==========
/* MEMORY 命令:定义允许的存储器区域 */
/*  本部分定义了连接器允许放入数据的各存储器区域,这是 */
/*  一个可选的功能,但是对于开发很有益,它使连接器在在 */
/*  程序太大时能给你警告 */
MEMORY
{
  /* ROM 是可读的(r) 和可执行的(x) */
  rom (rx) : ORIGIN = 0, LENGTH = 2M
  /* RAM 是可读的(r) ,可写的(w) ,可执行的(x) */
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4M
}
/* SECTIONS 命令 :  定义各输入段到输出段的映射 */
 
SECTIONS
{
 . = 0x0;     /*  从0x00000000开始 */
  .text : {
  *(vectors)    /*  向量表 */
  *(.text)    /*  程序代码 */
  *(.rodata)    /*  只读数据 */
  }
  . = 0x20000000;     /*  从0x20000000开始 */ 
  .data : {
  *(.data)    /*  数据存储器 */
 }
  .bss : {
  *(.bss)    /*  预留的数据存储器,必须初始化为零 */
 }
}
========== end of file ==========
为使用连接脚本,需要在编译阶段把simple.ld 传给编译器。 
$> arm-none-eabi-gcc -mcpu_cortex-m3 -mthumb example5.c -nostartfiles
-T simple.ld -o example5.o

 

  在CodeSourcery 安装后,已经包含了一系列的连接脚本,可以从 codesourcery/sourcery 
g++/arm‐ none‐ eabi/lib目录下找到。在下例中,我们就使用了 lm3s8xx ‐ rom.ld 文件。这个连
接器脚本顾名思义,是用于LM3S8XX 系列芯片的。

 

GNU C编译器的内联汇编
  GNU 的ARM   C编译器是支持内联汇编的,但此时的汇编语法看起来有点怪: 
__asm (" inst1 op1, op2... \n"
" inst2 op1, op2... \n"
...
" inst op1, op2... \n"
: 输出操作数s /*  可选 */
: 输入操作数s /*  可选 */

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值