基于gnu-arm-linux的LPC2220的简单工程模板

发布者:心怀梦想最新更新时间:2024-11-07 来源: cnblogs关键字:LPC2220  工程模板 手机看文章 扫描二维码
随时随地手机看文章

1:源头

我们学习arm嵌入式开发,一般接触到的是ADS1.2、kei的工程模板,这些模板对初学者入门来说是一种福音,但是想深入了解一下芯片启动过程、

编译和链接、映像文件结构、如何初始化、移植标准库等这些内容的话,这些商业IDE就显得隐藏了很多细节,不利于进一步学习。基于上述缘由,

我写了一个基于gnu arm-linux开发环境的LPC2220的简单工程,此工程实现了芯片开机初始化、加载映像到运行映像的转换、ZI段的清零、堆栈

的设置、引导高层C语言函数、移植标准库、在高层实现了printf用于调试。

2:例程实现的功能

初始化LPC2220芯片:

1,实现LPC2220中断向量表。

        2,设置ARM芯片各个模式运行时所需的堆栈空间。本例程中将系统模式的堆栈设置在LPC2220内部RAM的最顶端,即0x40004000。这里是因为芯片默认的运行模式就是系

统模式,也即我们的用户程序都是在系统模式下运行的。又因为ARM芯片默认是从高地址向低地址使用堆栈,因此将LPC2220内部RAM的最顶端设置为系统模式下的堆栈

指针。其他模式的堆栈设置在0x400000000开始的内部RAM中。具体怎么实现的,我们下面例程代码中会讲解。

3,初始化目标板,主要设置各种总线时钟、向量表映射、存储BANK设置、存储器加速模块、实时时钟等系统控制模块。

4:将RW段从NorFlash COPY到SDram中,清零ZI段。

5:跳转到main函数执行。

6:使用标准库并实现printf,用于调试。

7:利用printf打印全局变量,局部变量内容,地址。用来说明全局变量,局部变量以及链接器链接等相关知识。


3:过程中遇到的困难

第一个是我想使用LPC2220的外部BANK1,我使用的硬件板,BANK1上接的是RAM,一开始程序怎么也调试不过,以为是链接脚本书写错误。但后来发现是对LPC2220的引脚功能设置的问题。这不是什么知识点,但让我在这上面浪费了不少时间,特此记录一下,以安慰我那颗受伤的心。所以,记得一些硬件资源要先看datasheet初始化好后再使用。

第二个是编译代码的时候,出现一堆的undefinedreference to `__umoddi3'之类的错误,而且我还发现了只要我代码里有取整取余等操作时就会报上述错误,真是百思不得其解,后来到网上去查资料,得出这个错误确实是因为使用了除法导致的。而且,ARM7不支持除法指令,需要软件进行辅助除法运算,而一般是通过标准库的形式提供。我们使用ADS1.2,keil等集成IDE开发程序时,它们自带的库里有对除法的支持。而我现在使用的编译链是从网上下载的别人编译好的arm-linux-gcc3.4.1,可能不支持除法、软浮点支持。我不知道怎么解决这个问题,所以,干脆我使用了我自己使用源码编译的交叉编译链(4.6.0版本的)。我编译交叉连的时候选择了除法、软浮点支持。问题得以解决。具体交叉编译链的制作,参考:制作S3C6410的交叉编译链(arm-linux-gcc4.6.0)。

 

第三个问题是编译的时候提示undefinedreference to `__exidx_start'        undefined reference to`__exidx_end'等错误,而且是当我使用sprintf等相关格式化字符串的时候就提示这些错误,我没有找到合适的解决方案。所以,我参考网络资源自己实现了简单的格式化函数。这不是根本解决之道,我对使用gnu开发工具链进行嵌入式开发如何使用标准库函数也存在很多疑点。


4:部分例程代码

例程总览:该工程编译,链接出的映像下载到LPC2220的BANK0(Norflash)中,其地址为0X80000000。运行时,所有的RO段运行在BANK0,RW段和ZI段运行于LPC2220的BANK1(RAM),其地址为0X81000000。装载地址和运行地址不一致,所以在启动代码启动后,应将RW段COPY到运行时的地址处,将ZI段清零。这些工作都在startup.s中完成,最后startup.s将引导最终的main函数。

startup.s

@******************************************************************************

@ 文件名  :startup.s

@ 功    能:初始化LPC2220:初始化各种运行模式的堆栈空间,各种exception

@           入口。

@ 说明   :此工程为gcc for arm的工程,书写此工程启动代码目的是学习嵌入式开发过程中

@          的一些要点知识。gcc for arm 是开源的编译,链接器,可以学习程序开发的更多

@          细节。其他商业开发工具隐藏太多细节,不利于其初学者学习。

@ 备注    :大家可以根据工程需要修改其内容。   

@ 作者    :张连聘

@ 创建时间:2014-07-27

@******************************************************************************


@define the stack size for each mode

@定义各种运行模式堆栈大小

.equ  FIQ_STACK_LEGTH ,256 

.equ  IRQ_STACK_LEGTH ,9*8 

.equ  ABT_STACK_LEGTH ,256 

.equ  UND_STACK_LEGTH ,256


.equ  NoInt     ,0x80

.equ  NoFIQ     ,0x40

.equ  USR32Mode ,0x10

.equ  SVC32Mode ,0x13

.equ  SYS32Mode ,0x1f

.equ  IRQ32Mode ,0x12

.equ  FIQ32Mode ,0x11


.equ PINSEL2    ,0xE002C014

.equ BCFG0      ,0xFFE00000

.equ BCFG1      ,0xFFE00004

.equ BCFG2      ,0xFFE00008

.equ BCFG3      ,0xFFE0000C

@The imported labels        

@引入的外部标号在这声明

    .extern  FIQ_Exception                    @Fast interrupt exceptions handler 快速中断异常处理程序

    .extern  main                             @The entry point to the main function C语言主程序入口 

    .extern  TargetResetInit                  @initialize the target board 目标板基本初始化

    .extern  SoftwareInterrupt

.extern  Copydata

.extern  ClearBssData

.global Reset

.text

@interrupt vectors

@中断向量表

Reset:

        LDR     PC, ResetAddr

        LDR     PC, UndefinedAddr

        LDR     PC, SWI_Addr

        LDR     PC, PrefetchAddr

        LDR     PC, DataAbortAddr

        .word   0xb9205f80

        LDR     PC, [PC, #-0xff0]

        LDR     PC, FIQ_Addr


ResetAddr:

.word     ResetInit

UndefinedAddr:      

.word     Undefined

SWI_Addr:

.word     SoftwareInterrupt

PrefetchAddr:

.word     PrefetchAbort

DataAbortAddr:  

.word     DataAbort

Nouse:          .word     0

IRQ_Addr:

.word     0

FIQ_Addr:        

.word     FIQ_Handler

@未定义指令

Undefined:

        B       Undefined

      

@取指令中止

PrefetchAbort:

        B       PrefetchAbort


@取数据中止

DataAbort:

        B       DataAbort


@快速中断

FIQ_Handler:

        STMFD   SP!, {R0-R3, LR}

        LDR     PC, =FIQ_Exception

        LDMFD   SP!, {R0-R3, LR}

        SUBS    PC,  LR,  #4


/*********************************************************************************************************

**函数名称: InitStack

**功能描述: Initialize the stacks  初始化堆栈

**输 入:    None 

**输 出 :  None 

**全局变量: None 

**调用模块: None 

********************************************************************************************************/


InitStack:    

        MOV     R0, LR

@Build the SVC stack

@设置中断模式堆栈

        MSR     CPSR_c, #0xd2

        LDR     SP, StackIrq

@Build the FIQ stack

@设置快速中断模式堆栈

        MSR     CPSR_c, #0xd1

        LDR     SP, StackFiq

@Build the DATAABORT stack

@设置中止模式堆栈

        MSR     CPSR_c, #0xd7

        LDR     SP, StackAbt

@Build the UDF stack

@设置未定义模式堆栈

        MSR     CPSR_c, #0xdb

        LDR     SP, StackUnd

@Build the SYS stack

@设置系统模式堆栈

        MSR     CPSR_c, #0xdf

        LDR     SP, =StackUsr


        BX     R0

/*********************************************************************************************************

**函数名称: ResetInit

**功能描述: RESET  复位入口

**输 入:    None 

**输 出 :  None 

**全局变量: None 

**调用模块: None 

**-------------------------------------------------------------------------------------------------------

********************************************************************************************************/

ResetInit:

@Initial the extenal bus controller

@初始化外部总线控制器,根据目标板决定配置


LDR     R0, =PINSEL2

        LDR     R1, =0x0f814914

STR     R1, [R0]

        LDR     R1, =0x0f814914

        LDR     R0, =BCFG0

        LDR     R1, =0x1000ffef

        STR     R1, [R0]


        LDR     R0, =BCFG1

        LDR     R1, =0x1000ffef

        STR     R1, [R0]


        LDR     R0, =BCFG2

        LDR     R1, =0x0000fbef

        STR     R1, [R0]


        LDR     R0, =BCFG3

        LDR     R1, =0x10001460

        STR     R1, [R0]

        

        BL        InitStack               @ Initialize the stack 初始化堆栈

        BL        TargetResetInit         @ Initialize the target board 目标板基本初始化

BL        Copydata

BL        ClearBssData

        B          main                    @ Jump to the entry point of C program 跳转到c语言入口

     

StackIrq:

           .word     IrqStackSpace  +(IRQ_STACK_LEGTH - 1)*4

StackFiq:

           .word     FiqStackSpace  +(FIQ_STACK_LEGTH - 1)*4

StackAbt:  .word     AbtStackSpace  +(ABT_STACK_LEGTH - 1)*4

StackUnd:  .word     UndtStackSpace +(UND_STACK_LEGTH - 1)*4

 

/* 分配堆栈空间 */


.bss 

.align 4 

IrqStackSpace:      

  .space   IRQ_STACK_LEGTH * 4  @Stack spaces for Interrupt ReQuest Mode 中断模式堆栈空间

FiqStackSpace:      

  .space   FIQ_STACK_LEGTH * 4  @Stack spaces for Fast Interrupt reQuest Mode 快速中断模式堆栈空间

AbtStackSpace:      

  .space   ABT_STACK_LEGTH * 4  @Stack spaces for Suspend Mode 中止义模式堆栈空间

UndtStackSpace:

  .space   UND_STACK_LEGTH * 4  @Stack spaces for Undefined Mode 未定义模式堆栈






.end



main.c

/******************************************************************************

* 文件名  :main.c

* 功    能:初始化系统后,利用P2.28控制led灯闪烁

* 作者    :张连聘

* 创建时间:2014-07-27

*******************************************************************************/


#include    'LPC2220.h'

#include    'uart0.h'

#include    'print.h'

#define LEDCON   (1<<28)                                  

[1] [2]
关键字:LPC2220  工程模板 引用地址:基于gnu-arm-linux的LPC2220的简单工程模板

上一篇:android休眠唤醒驱动流程分析
下一篇:Windows CE6.0中断实验过程

推荐阅读最新更新时间:2026-03-25 10:51

基于LPC2220低压无功补偿控制器设计
  摘要:本文设计了一种基于ARM7TDMI-S处理器 LPC2220 为主控制MCU,以复合开关为电容投切开关的压无功补偿 控制器 。该 控制器 能够实现自动采样计算、无功自动调节、故障报警保护、数据存储等功能。并具有LCD液晶菜单显示,直观地显示测量基本电网参数。软件设计采用基于嵌入式实时操作系统μC/OS-Ⅱ。并且可通过上位机进行实时电网参数、电容投切情况、及历史数据的远程查询。   关键词:无功补偿;复合开关; LPC2220 ;μC/OS-Ⅱ;远程查询   如何跟踪并快速有效地补偿无功功率,对电力系统的运行稳定、改善电能质量、降低线损、实现电力节能等方面起着重要的作用。   本文设计的无功补偿 控制器 在硬件
[嵌入式]
【STM32 HAL库】HAL库的移植及工程模板的建立
文章内容偏向HAL库的移植和使用,以个人观点及了解为主,若与事实不符,则以www.st.com、www.stmcu.org.cn等平台为准。 使用的软件:VSCode(1.36版,带C/C++ IntelliSense插件) Keil MDK(5.26版) 芯片:STM32H743ZIT6(Nucleo-H743平台) 所使用的库:STM32Cube_FW_H7_V1.3.0,下载地址:https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software
[单片机]
【STM32 HAL库】HAL库的移植及<font color='red'>工程模板</font>的建立
创建STM32工程模板
1、创建一个工程文件夹,并且在文件夹里创建三个文件夹并分别以CORE、STM32F10X_LIB、USER命名。 2、将STM32F10x_StdPeriph_Lib_V3.5.0里跟内核相关的几个文件(core_cm3.c/core_cm3.h、startup_stm32f10x_hd.s、stm32f10x.h、system_stm32f10x.c/system_stm32f10x.h)拷贝到CORE文件目录里,几个文件路径如下图所示。 3、将STM32F10x_StdPeriph_Lib_V3.5.0里的库函数文件拷贝到STM32F10X_LIB文件夹里,文件夹路径如图所示。 4、
[单片机]
创建STM32<font color='red'>工程模板</font>
STM32标准库编程之工程模板介绍
【1】工程模板如下 本来不打算写这一篇的,为了系列的完整性吧,也为了有一个好的过度,但我只能说个大概,具体还要看我给的资料哦! 【2】什么是标准固件库? 其实标准固件库没有什么神秘的,里面无非是包含了一些源文件和头文件,由于文件作用不同分了好几个文件夹而已,命名这一点值得学习,一定要做到见名知意,那么你就是成功的。 【3】标准库的关键文件 那些我们只使用不用修改的文件我们就不用在意了,我这里说的是与内部外设相关的部分。也就是下面这些: 因为我们以后每次编程都要和它们打交道,所以这些便是我们研究的关键!这里不得不提一个文档,里面包含库里的所有函数,关键是说明了每个函数的作用,可传的值用枚举的方式列举了出来,并且每个
[单片机]
2.1、STM32怎么创建工程:如何创建第一个工程模板(基于固件库)
一、 首先在电脑的某个目录下创建一个空文件夹用来存放工程文件。创建好后在该文件目录下分别创建CORE 、FWLIB、OBJ、SYSTEM、USER等五个子文件夹。至于这些文件夹名字,实际上是可以任取的,我们这样取名只是为了行业规范。 二、打开keil软件,点击 Keil 的菜单: Project – New Uvision Project,保存时将目录定位到自己创建的文件下的USER子目录下: 三、接下来会出现一个选择 Device 的界面,就是选择我们的芯片型号,我们选择STM232F407ZE(如果使用的是其他系列的芯片,选择相应的型号就可以了)特别注意: 一定要安装对应的器件支持包才会显示这些内容)。 这里是
[单片机]
2.1、STM32怎么创建工程:如何创建第一个<font color='red'>工程模板</font>(基于固件库)
STM32编译环境、建立工程模板以及程序下载
1、之前写51的程序我们一般都是用的keil5软件,现在写32程序,要用到keil MDK软件,但是keil5和keil MDK不兼容,也就是说在keil5里面我们没办法写STM32F1之类的程序,而在keil MDK里面也没办法写51的程序,所以说为了让他们俩相互兼容,即我们要实现在keilMDK里面要既能够写51的程序,也能够写32的程序,我当初在网上找了好多方法都不行,最后发现一种特别简单好用的方法,就是在把keil5和keil MDK两个软件安装在同一个文件夹下面。具体步骤就是 (1)安装keil5软件(尽量不要安装在C盘),然后激活它。这里激活的时候要在注册机里选择C51。 (2)安装keil MDK软件,在安装
[单片机]
STM32编译环境、建立<font color='red'>工程模板</font>以及程序下载
IAR for stm8 新建工程模板
第一步:安装IAR for stm8 (略) 我使用的1.31版本,使用一个多月还没发现问题。 第二步:新建工程 1.新建文件夹test,再在test文件夹下建立user文件夹 2.打开IAR for stm8 1.31 3.点击 Project -- Creat New Project 4.弹出如下对话框,选择STM8 Series -- Empty project -- OK 。 5.保存.ewp文件到刚才新建的文件夹1-LED -- user下,取名test 。 6. 鼠标放蓝色处,右击 Add -- Add Group 。 7. 取名user ,点击OK 。 8. 点击 File --
[单片机]
IAR for stm8 新建<font color='red'>工程模板</font>
【STM32H7教程】第6章 STM32H7工程模板建立(IAR8)
6.1 初学者重要提示 IAR的工程创建过程还是比较重要的,务必实际上手操作一遍。 6.2 第1步,创建工程文件夹 创建一个文件夹,里面包含如下文件(直接将跑马灯例子的Project文件里面内容全部删除,然后整个工程复制进来即可)。 Doc文件夹 用于记录例程的修改记录和例子简介。 Libraries文件夹 在第一章详细介绍从官网的下载方法。 Project文件夹 这个是本章的重点,在这个文件夹里面再建立两个文件夹,EWARMv8文件夹用于存放IAR工程,MDK-ARM(uV5)文件夹里面用于存放MDK工程,方便以后创建MDK的工程。 User文件夹 这个是要用户提供的,开发板已经都提供
[单片机]
【STM32H7教程】第6章 STM32H7<font color='red'>工程模板</font>建立(IAR8)
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved