44B0的初始化程序便是初始化各个要害的寄存器,树立中止向量,然后转移到主函数去履行程序。不过44B0不支持地址映射,所以程序不COPY到RAM种履行。44B0初始化对咱们广阔初学者来说,比较难了解的是中止的处理和一些罕见的操作符号,44b0的中止子程序地址存放在初始化程序最终便是
HandleADC # 4
HandleRTC # 4
HandleUTXD1 # 4
HandleUTXD0 # 4
HandleSIO # 4
HandleIIC # 4
HandleURXD1 # 4
HandleURXD0 # 4
这一段,它的其实地址是ISR_STARTADDRESS,个人写中止程序的时分,子程序地址被编译器连放在相应的方位。初始化完成后,程序转经过BL Main 转到用户界说的主程序上履行。以下是我个人的一些了解,有过错的当地期望我们指出来。
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE}
CODE32
|
THUMBCODE SETL {FALSE}
]
[ THUMBCODE
CODE32 ;for start-up code for Thumb mode
]
×××××××××××××××××××××××
其间[=IF ,|=ELSE ,]= ENDIF, CODE32 标明一下操作都在ARM状况。这些都是伪操作
这段我了解为设定THUMCODE的值,然后确认,用户的程序是在ARM状况仍是THUM状况。不过不论THUMCODE是何值,下面代码都是ARM状况
这段没有什么很杂乱的,便是这三个[,|,]操作符让我利诱了半响,翻了半响书才找到解说
MACRO 宏伪操作
$HandlerLabel HANDLER(宏的称号) $HandleLabel(宏的参数)
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr doest push because it return to original address)
ldr r0,=$HandleLabel;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
*******************************
这段最初我觉得比较难了解,不过经过看各种程序,对这段有了一个根本的了解。这个宏的作用是把各个中止程序的地址装入当时的PC,44B0有两种装断形式一种是没有中止向量表,一种是运用中止向量表的运用中止向量表只能是IRQ方法,当运用中止向量表的时分,中止产生时由44B0的中止控制器主动跳转到相应的方位。比如在中止向量表的形式下,一个外部中止0产生程序主动跳转到地址0X20处,0X20地址单元的指令时ldr pc,=HandlerEINT0因此程序PC跳到HandlerEINT0处,履行这个宏操作,把外部中止的函数的地址赋给PC。 44B0里边界说了一个
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x84)) ,_ISR_STARTADDRES是中止程序地址的开始地址,_ISR_STARTADDRESS+0X84是HandleEINT0的地址例如一个外部中止函数名void EXINT(),程序里履行 pISR_EINT0=(unsigned)EXIT,就把自己的函数地址赋给了标号为HandleEINT0处的内存单元
IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$ZI$$Base| ; Base and limit of area
IMPORT |Image$$ZI$$Limit| ; to zero initialise
××××××××××××××××××××××××××××××××××
这段我个人的了解为这些是连接器生成的于输出段相关的符号,是在没有运用SCATTER文件的状况能够调用。这段指出了在ROM和RAM种的数据的地址,这些地址应该是连接器生成的,不过为什么能调用连接器出产的符号,我不大了解其间的原因,还期望各位说说自己的了解
IsrIRQ ;using I_ISPR register.
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
;IMPORTANT CAUTION
;if I_ISPC isnt used properly, I_ISPR can be 0 in this routine.
ldr r9,=I_ISPR
ldr r9,[r9]
mov r8,#0x0
0
movs r9,r9,lsr #1
bcs �
add r8,r8,#4
b �
1
ldr r9,=HandleADC
add r9,r9,r8
ldr r9,[r9]
str r9,[sp,#8]
ldmfd sp!,{r8-r9,pc}
×××××××××××××××××××××××
这段是没有运用装断向量形式下怎么装载中止子程序,由于44B0有30个中止源,所以需求程序处理以确认调用那个中止程序
0,1是部分标号,%B是向后查找部分标号, %F是向前查找部分标号 。都是伪操作
I_ISPR寄存器各位标明产生了应该调用那个中止子程序。只能1方位位,其它位为0,比如说串口1发送中止产生,这时I_ISPR的值为0X04,
ldr r9,=I_ISPR
ldr r9,[r9] 两条指令后,r9的内容为0X4 ,
movs r9,r9,lsr #1 r9内容右移一位
bcs � 判别是否把置位是否转移到C位,
add r8,r8,#4 假如没有的R8加4
假如r9内容为0x04 需求右移3次 ,之后r8的内容为8 然后HandleADC的地址 加上r8的值便是串口1发送中止的地址,这个地址的内容是中止子程序的地址
再阐明几个伪操作:^=MAP. #=field
其他方面我觉得比较简单了解了,就不多讲了。
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/262923.html