基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx

上传人:b****3 文档编号:4797300 上传时间:2023-05-07 格式:DOCX 页数:13 大小:18.94KB
下载 相关 举报
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第1页
第1页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第2页
第2页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第3页
第3页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第4页
第4页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第5页
第5页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第6页
第6页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第7页
第7页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第8页
第8页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第9页
第9页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第10页
第10页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第11页
第11页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第12页
第12页 / 共13页
基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx

《基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx》由会员分享,可在线阅读,更多相关《基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx(13页珍藏版)》请在冰点文库上搜索。

基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的.docx

基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的

基于ARM7TDMI内核的芯片里多数硬件模块都是可配置的,需要由软件来设置其需要的工作状态。

因此在用户的应用程序之前,需要由专门的一段代码来完成对系统的初始化。

由于这类代码直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。

一般通用的内容包括:

中断向量表

初始化存储器系统

初始化堆栈

初始化有特殊要求的断口,设备

初始化用户程序执行环境

改变处理器模式

呼叫主应用程

一.中断向量表

  ARM要求中断向量表必须放置在从0地址开始,连续8X4字节的空间内。

每当一个中断发生以后,ARM处理器便强制把PC指针置为向量表中对应中断类型的地址值。

因为每个中断只占据向量表中1个字的存储空间,只能放置一条ARM指令,使程序跳转到存储器的其他地方,再执行中断处理。

中断向量表的程序实现通常如下表示:

AREABoot,CODE,READONLY

ENTRY

BResetHandler

BUndefHandler

BSWIHandler

BPreAbortHandler

BDataAbortHandler

B

BIRQHandler

BFIQHandler

其中关键字ENTRY是指定编译器保留这段代码,因为编译器可能会认为这是一段亢余代码而加以优化。

链接的时候要确保这段代码被链接在0地址处,并且作为整个程序的入口。

放在0地址处的中断向量表的ResetHandler一般放在FLASH内,其他中断向量的入口地址可以是FLASH内的,也可以是SDRAM内的,但是在为操作系统初始化时应该为SDRAM的地址。

例如作为uClinux的启动代码,此处应该为内存地址。

一般有两种实现方式:

1.1              1.第一种实现方式

b   reset

      add pc,pc,#0x0c000000

      add pc,pc,#0x0c000000

      add pc,pc,#0x0c000000

      add pc,pc,#0x0c000000

      add pc,pc,#0x0c000000

      add pc,pc,#0x0c000000

      add pc,pc,#0x0c000000

 

 

0x0c000000为内存起始地址,uClinux将中断向量放入地址0x0c000008,因为cpu发生中断时仍然会跳转到0地址处的中断向量表中去,所以此处要修改中断向量表的地址,使程序能正确跳转到uClinux实现的中断向量处。

此处需要注意,由于ARM系统的三级流水线技术,当程序执行到x地址处,pc指针的值其实等于x+8.

在uClinux中实现如下:

#ifdefCONFIG_ARCH_S3C44B0

#undefvectors_base()

#definevectors_base() (0x0c000008)

#endif

所以add pc,pc,#0x0c000000这条语句将会有8的偏移量。

 

 

1.2              2.第二种实现方式:

brest

ldrpc,=0x0c000004

ldrpc,=0x0c000008

ldrpc,=0x0c00000c

ldrpc,=0x0c000010

b.

ldrpc,=0x0c000018 //irq中断

ldrpc,=0x0c00001c

但相应的linux源代码应作修改,这时uClinux中实现如下:

#ifdefCONFIG_ARCH_S3C44B0

#undefvectors_base()

#definevectors_base() (0x0c000000)

#endif

即只要当发生中断时,cpu发生中断时跳转到0地址处的中断向量表中去,再这里能跳转到uClinux的vectors_base()地址处。

 

ARM7有两种IRQ中断模式

(1).向量中断时0地址代码如下:

其中从0x20开始处一定要按顺序放入

ENTRY

bResetHandler;0x00

bHandlerUndef;0x04

bHandlerSWI;0x08

bHandlerPabort;0x0c

bHandlerDabort;0x10

b.;0x14

bHandlerIRQ;0x18

bHandlerFIQ;0x1c

ldrpc,=HandlerEINT0;0x20

ldrpc,=HandlerEINT1

ldrpc,=HandlerEINT2

ldrpc,=HandlerEINT3

ldrpc,=HandlerEINT4567

ldrpc,=HandlerTICK;0x34

b.

b.

ldrpc,=HandlerZDMA0;0x40

ldrpc,=HandlerZDMA1

ldrpc,=HandlerBDMA0

ldrpc,=HandlerBDMA1

ldrpc,=HandlerWDT

ldrpc,=HandlerUERR01;0x54

b.

b.

ldrpc,=HandlerTIMER0;0x60

ldrpc,=HandlerTIMER1

ldrpc,=HandlerTIMER2

ldrpc,=HandlerTIMER3

ldrpc,=HandlerTIMER4

ldrpc,=HandlerTIMER5;0x74

b.

b.

ldrpc,=HandlerURXD0;0x80

ldrpc,=HandlerURXD1

ldrpc,=HandlerIIC

ldrpc,=HandlerSIO

ldrpc,=HandlerUTXD0

ldrpc,=HandlerUTXD1;0x94

b.

b.

ldrpc,=HandlerRTC;0xa0

b.

b.

b.

b.

b.

b.

ldrpc,=HandlerADC;0xb4

 

 

 

 

2.非向量IRQ中断模式

ENTRY

bResetHandler;fordebug

bHandlerUndef;handlerUndef

bHandlerSWI;SWIinterrupthandler

bHandlerPabort;handlerPAbort

bHandlerDabort;handlerDAbort

b.;handlerReserved

bIsrIRQ

bHandlerFIQ

......

IsrIRQ

subsp,sp,#4;reservedforPC

stmfdsp!

{r8-r9}

ldrr9,=I_ISPR

ldrr9,[r9]

movr8,#0x0

0movsr9,r9,lsr#1

bcs%F1

addr8,r8,#4

b%B0

1ldrr9,=HandleADC

addr9,r9,r8

ldrr9,[r9]

strr9,[sp,#8]

ldmfdsp!

{r8-r9,pc}

......

HandleADC#4

HandleRTC#4

HandleUTXD1#4

HandleUTXD0#4

......

HandleEINT3#4

HandleEINT2#4

HandleEINT1#4

HandleEINT0#4;

 

此处通过判断I_ISPR的值可以跳到相应的中断处理函数处。

此处的Bootloader采用非向量IRQ中断方式,通过以下头文件的定义可以方便的把中断向量处理函数的地址传入:

/*ISR*/

#definepISR_RESET   (*(unsigned*)(_ISR_STARTADDRESS+0x0))

#definepISR_UNDEF   (*(unsigned*)(_ISR_STARTADDRESS+0x4))

#definepISR_SWI (*(unsigned*)(_ISR_STARTADDRESS+0x8))

#definepISR_PABORT (*(unsigned*)(_ISR_STARTADDRESS+0xc))

#definepISR_DABORT (*(unsigned*)(_ISR_STARTADDRESS+0x10))

#definepISR_RESERVED   (*(unsigned*)(_ISR_STARTADDRESS+0x14))

#definepISR_IRQ  (*(unsigned*)(_ISR_STARTADDRESS+0x18))

#definepISR_FIQ  (*(unsigned*)(_ISR_STARTADDRESS+0x1c))

 

#definepISR_ADC(*(unsigned*)(_ISR_STARTADDRESS+0x20))

#definepISR_RTC (*(unsigned*)(_ISR_STARTADDRESS+0x24))

#definepISR_UTXD1    (*(unsigned*)(_ISR_STARTADDRESS+0x28))

#definepISR_UTXD0    (*(unsigned*)(_ISR_STARTADDRESS+0x2c))

#definepISR_SIO  (*(unsigned*)(_ISR_STARTADDRESS+0x30))

#definepISR_IIC   (*(unsigned*)(_ISR_STARTADDRESS+0x34))

#definepISR_URXD1    (*(unsigned*)(_ISR_STARTADDRESS+0x38))

#definepISR_URXD0    (*(unsigned*)(_ISR_STARTADDRESS+0x3c))

#definepISR_TIMER5   (*(unsigned*)(_ISR_STARTADDRESS+0x40))

#definepISR_TIMER4   (*(unsigned*)(_ISR_STARTADDRESS+0x44))

#definepISR_TIMER3   (*(unsigned*)(_ISR_STARTADDRESS+0x48))

#definepISR_TIMER2   (*(unsigned*)(_ISR_STARTADDRESS+0x4c))

#definepISR_TIMER1   (*(unsigned*)(_ISR_STARTADDRESS+0x50))

#definepISR_TIMER0   (*(unsigned*)(_ISR_STARTADDRESS+0x54))

#definepISR_UERR01  (*(unsigned*)(_ISR_STARTADDRESS+0x58))

#definepISR_WDT(*(unsigned*)(_ISR_STARTADDRESS+0x5c))

#definepISR_BDMA1   (*(unsigned*)(_ISR_STARTADDRESS+0x60))

#definepISR_BDMA0   (*(unsigned*)(_ISR_STARTADDRESS+0x64))

#definepISR_ZDMA1   (*(unsigned*)(_ISR_STARTADDRESS+0x68))

#definepISR_ZDMA0   (*(unsigned*)(_ISR_STARTADDRESS+0x6c))

#definepISR_TICK(*(unsigned*)(_ISR_STARTADDRESS+0x70))

#definepISR_EINT4567(*(unsigned*)(_ISR_STARTADDRESS+0x74))

#definepISR_EINT3     (*(unsigned*)(_ISR_STARTADDRESS+0x78))

#definepISR_EINT2     (*(unsigned*)(_ISR_STARTADDRESS+0x7c))

#definepISR_EINT1     (*(unsigned*)(_ISR_STARTADDRESS+0x80))

#definepISR_EINT0     (*(unsigned*)(_ISR_STARTADDRESS+0x84))

 

通过如下代码就可以实现UART0口的中断处理了:

rINTCON=0x5;   //Non-vectored,IRQenable,FIQdisable

   rINTMOD=0x0;   //All=IRQmode

   pISR_URXD0=(unsigned)Uart0_RxInt;

 

当在地址0处将中断向量跳到内存后,相应的中断向量就应该拷贝到内存地址处。

把以下代码从FLASH拷贝到SDRAM中:

real_vectors:

      b    reset

      b    undefined_instruction

      b    software_interrupt

      b    prefetch_abort

      b    data_abort

      b    not_used

      b    irq

      b    fiq

undefined_instruction:

      movr6,#3

      b    endless_blink

software_interrupt:

      movr6,#4

      b    endless_blink

prefetch_abort:

      movr6,#5

      b    endless_blink

data_abort:

      movr6,#6

      b    endless_blink

not_used:

      /*we*should*neverreachthis*/

      movr6,#7

      b    endless_blink

irq:

subsp,sp,#4;reservedforPC

stmfdsp!

{r8-r9}

ldrr9,=I_ISPR

ldrr9,[r9]

movr8,#0x0

0movsr9,r9,lsr#1

bcs%F1

addr8,r8,#4

b%B0

1ldrr9,=HandleADC

addr9,r9,r8

ldrr9,[r9]

strr9,[sp,#8]

ldmfdsp!

{r8-r9,pc}

......

fiq:

      movr6,#9

      b    endless_blink

有了如上步骤就可以在bootloader中实现中断处理了。

 

 

 

 

1.3              二.Reset中断处理如下内容

1初始化存储器系统

存储器地址分布

一种典型的情况是启动ROM的地址重映射。

初始化堆栈

因为ARM有7种执行状态,每一种状态的堆栈指针寄存器(SP)都是独立的。

因此,对程序中需要用到的每一种模式都要给SP定义一个堆栈地址。

方法是改变状态寄存器内的状态位,使处理器切换到不同的状态,让后给SP赋值。

注意:

不要切换到User模式进行User模式的堆栈设置,因为进入User模式后就不能再操作CPSR回到别的模式了,可能会对接下去的程序执行造成影响。

这是一段堆栈初始化的代码示例,其中只定义了三种模式的SP指针:

MRSR0,CPSR

BICR0,R0,#MODEMASK;安全起见,屏蔽模式位以外的其他位

ORRR1,R0,#IRQMODE

MSRCPSR_cxfs,R1

LDRSP,=UndefStack

ORRR1,R0,#FIQMODE

MSRCPSR_cxsf,R1

LDRSP,=FIQStack

ORRR1,R0,#SVCMODE

MSRCPSR_cxsf,R1

LDRSP,=SVCStack

2初始化有特殊要求的端口,设备

  这里视不同的硬件设计而不同。

 

3 初始化应用程序执行环境

映像一开始总是存储在ROM/Flash里面的,其RO部分即可以在ROM/Flash里面执行,也可以转移到速度更快的RAM中执行;而RW和ZI这两部分是必须转移到可写的RAM里去。

所谓应用程序执行环境的初始化,就是完成必要的从ROM到RAM的数据传输和内容清零。

下面是在ADS下,一种常用存储器模型的直接实现:

LDRr0,=|Image$$RO$$Limit|;得到RW数据源的起始地址

LDRr1,=|Image$$RW$$Base|;RW区在RAM里的执行区起始地址

LDRr2,=|Image$$ZI$$Base|;ZI区在RAM里面的起始地址

CMPr0,r1;比较它们是否相等

BEQ%F1

0CMPr1,r3

LDRCCr2,[r0],#4

STRCCr2,[r1],#4

BCC%B0

1LDRr1,=|Image$$ZI$$Limit|

MOVr2,#0

2CMPr3,r1

STRCCr2,[r3],#4

BCC%B2

程序实现了RW数据的拷贝和ZI区域的清零功能。

其中引用到的4个符号是由链接器第一输出的。

|Image$$RO$$Limit|:

表示RO区末地址后面的地址,即RW数据源的起始地址

|Image$$RW$$Base|:

RW区在RAM里的执行区起始地址,也就是编译器选项RW_Base指定的地址

|Image$$ZI$$Base|:

ZI区在RAM里面的起始地址

|Image$$ZI$$Limit|:

ZI区在RAM里面的结束地址后面的一个地址

程序先把ROM里|Image$$RO$$Limt|开始的RW初始数据拷贝到RAM里面|Image$$RW$$Base|开始的地址,当RAM这边的目标地址到达|Image$$ZI$$Base|后就表示RW区的结束和ZI区的开始,接下去就对这片ZI区进行清零操作,直到遇到结束地址|Image$$ZI$$Limit|

4改变处理器模式

因为在初始化过程中,许多操作需要在特权模式下才能进行(比如对CPSR的修改),所以要特别注意不能过早的进入用户模式。

内核级的中断使能也可以考虑在这一步进行。

如果系统中另外存在一个专门的中断控制器,这么做总是安全的。

5 呼叫主应用程序

当所有的系统初始化工作完成之后,就需要把程序流程转入主应用程序。

最简单的一种情况是:

IMPORTmain

Bmain

直接从启动代码跳转到应用程序的主函数入口,当然主函数名字可以由用户随便定义。

在ARMADS环境中,还另外提供了一套系统级的呼叫机制。

IMPORT__main

B__main

__main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()函数。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2