Main函数之IsrInit分析.docx

上传人:b****3 文档编号:2124821 上传时间:2022-10-27 格式:DOCX 页数:13 大小:22.14KB
下载 相关 举报
Main函数之IsrInit分析.docx_第1页
第1页 / 共13页
Main函数之IsrInit分析.docx_第2页
第2页 / 共13页
Main函数之IsrInit分析.docx_第3页
第3页 / 共13页
Main函数之IsrInit分析.docx_第4页
第4页 / 共13页
Main函数之IsrInit分析.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

Main函数之IsrInit分析.docx

《Main函数之IsrInit分析.docx》由会员分享,可在线阅读,更多相关《Main函数之IsrInit分析.docx(13页珍藏版)》请在冰豆网上搜索。

Main函数之IsrInit分析.docx

Main函数之IsrInit分析

飞凌2440Bootloader学习中的若干问题

1.2440init.s分析

1)关于HANDLER宏定义

MACRO

$HandlerLabelHANDLER$HandleLabel;宏定义

$HandlerLabel

;由于ADS仅支持FD(满递减)型堆栈

subsp,sp,#4;将堆栈退一个字用于保存下面用到的R0

stmfdsp!

{r0};将R0压入堆栈

ldrr0,=$HandleLabel;将HandleLabel的地址赋给R0

ldrr0,[r0];将HandleLabel的地址指向的内容

;(实际的中断函数的执行地址)赋给R0

strr0,[sp,#4];将对应的中断函数首地址入栈保护

ldmfdsp!

{r0,pc};将中断函数的首地址出栈,放入PC中,系统将跳转到

;对应中断处理函数

MEND

HANDLER是宏名。

$HandlerLabel是宏展开后要被别的字符替换掉的标号,不过不叫参数。

例如:

HandlerFIQHANDLERHandleFIQ

展开后为:

HandlerFIQ

subsp,sp,#4

stmfdsp!

{r0}

ldrr0,=HandleFIQ

ldrr0,[r0]

strr0,[sp,#4]

ldmfdsp!

{r0,pc}

启动代码中有很多的类似下面的语句:

HandlerFIQHANDLERHandleFIQ

HandlerIRQHANDLERHandleIRQ

HandlerUndefHANDLERHandleUndef

HandlerSWIHANDLERHandleSWI

HandlerDabortHANDLERHandleDabort

HandlerPabortHANDLERHandlePabort

等等

该宏定义的代码用于将对应中断服务程序ISR的入口地址装载到PC中,可称之为“加载程序”。

本初始化程序定义了一个34个字空间的数据区(文件最后),用于存放相应中断服务程序的首地址。

每个字空间都有一个标号,以HandleXXX命名。

在向量中断模式下使用“加载程序”来执行中断服务程序。

在_ISR_STARTADDRESS=0x33FF_FF00里定义的第一级中断向量表是采用型如Handle***的方式的.而在程序的ENTRY处(程序开始处)采用的是bHandler***的方式.

在这里Handler***就是通过HANDLER这个宏和Handle***进立联系的.这种方式的优点就是正真定义的向量数据在内存空间里,而不是在ENTRY处的ROM(FLASH)空间里,这样,我们就可以在程序里灵活的改动向量的数据了.其中HANDLER是一个宏,用于查找中断处理程序的入口地址。

这些地址存放在由HandleXXX指向的表项中,该表定位在RAM高端,基地址为_ISR_STARTADDRESS。

假如_ISR_STARTADDRESS为0x800000000,当IRQ中断时,根据bHandlerFIQ,先跳转再根据^_ISR_STARTADDRESS基地址+HandleIRQ的偏移地址(4*6)得到的中断地址

0x80000000+0x00000024=0x80000024

2)

ALIGN

AREARamData,DATA,READWRITE

^_ISR_STARTADDRESS;_ISR_STARTADDRESS=0x33FF_FF00

HandleReset#4

HandleUndef#4

HandleSWI#4

HandlePabort#4

HandleDabort#4

Ø这个^起什么作用的呢?

^,是ARM汇编中的一个伪操作,和MAP是同义词,用来定义一个结构化的内存表的首地址。

#,也是一个伪操作,和FIELD是同义词,用来定义结构化的内存表中的一个数据域。

Øbootloader设定的中断向量表在启动Wince系统之后是不是就没用了?

没有用了,进入CE后会重新初始化中断向量的。

Ø那么是Wince在启动之后,自己又重新设定了中断向量表?

在哪个文件中设定的呢?

又把向量表保存在哪了?

OAL的startup.s中会调用KernelStart,里面会设置向量表。

可以参考%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARM\armtrap.s。

 

2.

初始化中断服务程序。

当中断产生时,处理相应的程序

voidIsr_Init(void)

{

pISR_UNDEF=(unsigned)HaltUndef;

pISR_SWI=(unsigned)HaltSwi;

pISR_PABORT=(unsigned)HaltPabort;

pISR_DABORT=(unsigned)HaltDabort;

rINTMOD=0x0;   //All=IRQmode

rINTMSK=BIT_ALLMSK;   //Allinterruptismasked.

}

pISR_UNDEF=(unsigned)HaltUndef;  就是将函数HaltUndef的地址强制转换为unsigned类型,赋给指针pISR_UNDEF。

由pISR_UNDEF定义知,

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

pISR_UNDEF为相应的异常中断地址。

函数名称代表函数的地址,即将HaltUndef函数的地址赋值到_ISR_STARTADDRESS+0x4中。

当发生中断时,系统会去pISR_UNDEF定义的地址里取出中断函数的地址也就是HaltUndef的地址,然后执行.就相当于当发生中断时,执行HaltUndef函数.

voidHaltUndef(void)

{

Uart_Printf("Undefinedinstructionexception!

!

!

\n");

while

(1);

}

注意:

unsignedlong*p

p=((unsignedlong*)0x80001000);

上面2句可以写成

unsignedlong*p=((unsignedlong*)0x80001000);

*p=0x55555555,就是给地址0x80001000写0x55555555

#defineAT91C_SDRAM((unsignedint*)0x20000000)//根据sdram的地址进行修改

unsingedint*pTemp=AT91C_SDRAM,指针pTemp的地址为0x20000000

/*PinConnectBlock*/

#definePINSEL0(*((volatileunsignedlong*)0xE002C000))

#definePINSEL1(*((volatileunsignedlong*)0xE002C004))

#definePINSEL2(*((volatileunsignedlong*)0xE002C014))

PINSEL0=0x00050000;地址0xE002C000的值为0x00050000

首先(volatileunsignedlong*)0x48000000的意思是把0x48000000强制转换成volatileunsignedlong类型的指针,即对指针的操作的范围是从0x48000000开始的4个字节(long型).暂记为p,那么就是

#defineA*p,即A为P指针指向位置的内容了。

这里就是通过内存寻址访问到寄存器A,可以读/写操作!

表示处理相应中断。

1./********************************************************************

2.*名称:

Timer1_ISR()

3.*功能:

定时器1中断服务程序

4.*入口参数:

5.********************************************************************/

6.void__irqTimer1_ISR(void)

7.{

8.

9.    staticintcount;

10.    count++;

11.    rSRCPND=rSRCPND|(0x1<<11);

12.    rINTPND=rINTPND|(0x1<<11);

13.

14.    //每隔为1秒蜂鸣器响一次,持续时间为0.5秒

15.    if(count%1000==0)

16.          rGPADAT|=(1<<16);                //蜂鸣器响

17.    elseif(count%1000==500)

18.          rGPADAT&=~(1<<16);          //蜂鸣器不响

19.}

复制代码

1./********************************************************************

2.*名称:

Timer1_init()

3.*功能:

定时器1初始化

4.*入口参数:

5.********************************************************************/

6.void  Timer1_init(void)

7.{

8.      U32      time_val;

9.

10.      rTCFG0=3;                          //配置定时器0,1的预分频值

11.      rTCFG1=0<<4;                      //配置定时器1分频值

12.

13.      time_val=PCLK/(3+1)/2/1000-1;      //1ms=PCLK/prescaler/divider/1000

14.      

15.      rSRCPND=rSRCPND|(0x1<<11);                //清除中断源未决寄存器相应位

16.      rINTPND=rINTPND|(0x1<<11);                //

17.      rINTMSK=~(0x1<<11);          //打开定时器1中断

18.      

19.      rTCNTB1=time_val;                //计数缓存寄存器

20.      rTCMPB1=time_val>>1;          //50%

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

当前位置:首页 > 教学研究 > 教学反思汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1