微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM处理器学习之GPIO操作篇(gnu link script)

ARM处理器学习之GPIO操作篇(gnu link script)

时间:11-09 来源:互联网 点击:

1:主要内容

本文主要介绍了VMA、LMA的相关概念,gnu link script的作用和使用方法。

2:引言

我们程序员刚开始学习编写程序时,都会接触到一个 " *.C " 文件要经过编译、链接等过程才能变成可以执行的程序。至于这里的链接到底怎么回事,我们今天就来谈谈这方面的内容。现在,我们有这样一套ARM7的硬件开发环境,0X80000000地址开始BANK0 我们用的是NorFlash,0X40000000地址是芯片内部的RAM。我编译、链接的程序下载到0x80000000地址处。而真正运行时,一部分初始化代码在0X80000000运行,初始化完毕后,将主要工作的代码copy到内部RAM 0X40000000开始的地方运行。因为内部RAM运行程序比较快,所以我想NorFlash充当电脑的硬盘的作用,让其主要程序在RAM里运行。这是今天主要的内容,当然,程序的功能还是和上一节ARM处理器学习之--GPIO操作篇一样:让板子上的一个LED灯闪烁。

3:主要思路

我把程序分成两个主要部分,第一部分负责对芯片基本的操作和copy代码(从Norflashcopy到Sdram中),然后跳转到Sdram中去执行程序。第二部分为程序的主要部分。那这样的话,我对这两部分程序通过链接器链接时则需要设置不同的运行地址。即,第一部分代码链接的运行地址是0X80000000,而第二部分代码链接的运行地址是0X40000000。但这两部分组成的映像文件的下载地址都是0X80000000.我想这个应该能通过链接器进行设置,通过查询资料得知,这个可以通过链接器的链接脚本来实现,在gnu arm 的链接器上是通过书写一个*。lds的链接脚本来实现的。

4:相关知识点

经过编译,链接后生成的可执行文件,其实有一定的结构。主要分为code段,data段,zi段(在gnu linux 下为.text .data .bss段)。这个code段,就是我们使用汇编,c语言,c++写的程序指令,而data是程序中使用的变量,zi是程序中定义的未初始化的变量(由于这些内容本来就没有被初始化,所以这些zi段没有必要存储在生成的映像文件中,只是在程序真正运行时在相应的地址处预留出相应的空间即可)。文件的链接简图:

VMA(Virtual Memory Address)和LMA:(Load Memory Address)。这个LMA地址是程序装载到存储器时的地址,WMA可以理解成程序真正运行时所在的地址。

而链接器指定的链接地址要和程序真正运行时所在的地址一致。这个也好理解,链接器就是根据你指定的链接地址进行整个映像的链接操作,一些绝对跳转指令就是根据链接指定的地址进行更改PC值的,这些在上一讲有所解释。当然一般情况下,LMA和VMA的地址是一样的,不过,在有些嵌入式开发的过程中,程序的装载地址和运行地址不一样,那在访问链接地址和装载地址不一样的code、data、zi段的时候应该在真正访问前将其copy到链接指定的地址上去。

gnu 链接脚本的格式。gnu 链接脚本是一个描述文本,用来描述怎么链接最终的映像文件。关于这个链接脚本文件,我们在具体案例中了解其用法。

5:实验源码

initsystem.s

@****************************************************************************** @ 文件名 :initsystem.s @ 功 能:初始化系统并copy代码 @ @ 作者 :张连聘 @ 创建时间:2014-06-22 @****************************************************************************** .text .global _start @声明常量 .equ DATA_DST,0x40000000 @目的地址 .equ DATA_SRC,0x80000000 @源地址 @引入外部标号 .extern MainLoop .extern start_copy_addr _start: LDR PC, ResetAddr ResetAddr: .word ResetInit ResetInit: LDR R0,=DATA_DST @RO 指向目的地址 LDR R1,=start_copy_addr @R1 指向源地址 MOV R10,#128 @复制的个数为128*8*4=4K CopyLoop: LDMIA R1!,{R2-R9} @从R1指定的内存地址处装载数据到R2--R9中 STMIA R0!,{R2-R9} @把R2--R9的数据复制到R0指定的内存中 SUBS R10,R10,#1 BNE CopyLoop LDR PC,=MainLoop .end

control_led.s

@****************************************************************************** @ 文件名 :control_led.s @ 功 能:利用P2.28控制led灯闪烁 @ @ 作者 :张连聘 @ 创建时间:2014-06-08 @****************************************************************************** .text .global MainLoop StartMain: @定义程序中使用到的常量 .equ IO2DIR ,0xE0028028 @ 控制IO0的输入、输出属性寄存器 .equ IO2SET ,0xE0028024 @IO2输出1控制寄存器 .equ IO2CLR ,0xE002802C @IO2输出0控制寄存器 .equ LEDCON ,(1<28) @0x10000000 MainLoop: LDR R0,=IO2DIR @IO2DIR LDR R1,=LEDCON STR R1,[R0] @设置P2.28为输出 LDR R0,=IO2CLR LDR R1,=LEDCON STR R1,[R0] @P2.28为输出0,熄灭led BL DELAYS @调用延时程序 LDR R0,=IO2SET LDR R1,=LEDCON STR R1,[R0] @P2.28为输出1,点亮led BL DELAYS @调用延时程序 B MainLoop @****************************************************************************** @ 名 CopyData @ 功 能:复制代码,从0x8000***---->0x40000000 size:4K @ 入口参数:无 @ 出口参数:无 @ 占用资源: @****************************************************************************** /* CopyData: LDR R0,=DATA_DST @RO 指向目的地址 MOV R10,#128 @复制的个数为128*8*4=4K CopyLoop: LDMIA R1!,{R2-R9} @从R1指定的内存地址处装载数据到R2--R9中 STMIA R0!,{R2-R9} @把R2--R9的数据复制到R0指定的内存中 SUBS R10,R10,#1 BNE CopyLoop MOV PC,LR */ @****************************************************************************** @ 名 称:DELAYS @ 功 能:软件延时 @ 入口参数:无 @ 出口参数:无 @ 占用资源:R7 @****************************************************************************** DELAYS: LDR R7,=0x00080000 @ 延时参数 DELAYS_L1: SUBS R7,R7,#1 @ R7 = R7-1 BNE DELAYS_L1 @ 判断R7-1结果是否为0,若不为0则跳转 MOV PC,LR @ 返回 .end

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top