s3c44b0的初始化程序就是初始化各个关键的寄存器,建立中断向量,然后转移到主函数去执行程序。不过s3c44b0不支持地址映射,所以程序不copy到ram种执行。s3c44b0初始化对我们广大初学者来说,比较难理解的是中断的处理和一些少见的操作符号,s3c44b0的中断子程序地址存放在初始化程序最后就是
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 does't 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 isn't 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 %f1
add r8,r8,#4
b %b0
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 %f1 判断是否把置位是否转移到c位,
add r8,r8,#4 如果没有的r8加4
如果r9内容为0x04 需要右移3次 ,之后r8的内容为8 然后handleadc的地址 加上r8的值 就是串口1发送中断的地址,这个地址的内容是中断子程序的地址
再说明几个伪操作:^=map. #=field
别的方面我觉得比较容易理解了,就不多讲了。
千兆网线和百兆网线的传输速率是多少
OPPO Reno5系列外观细节曝光:晶钻更大更闪亮
一座变电站建成的流程是什么
来看一下170A电源模块的MCU主控板
全新第三代荣威RX5开启预售,搭载3颗地平线征程3芯片
S3C44B0的初始化程序的理解
三星Galaxy S20曝光采用了方正的设计在背部加入了一枚ToF镜头
借助NVIDIA CloudXR重新构想增强现实和虚拟现实
MWC2019:OPPO携重磅成果亮相MWC Nubia展出骁龙855小屏旗舰机
STM32硬件IIC操作解析
使用免清洗助焊剂有必要清洗吗?
PSB-1000系列可编程多量程直流电源的产品特点及应用
电路多路复用汽车传感器知识简介
微信支付跟美团外卖合作互利共赢在哪里?
IBM Think 2019探讨企业数字化转型旅程
封装设计解惑:如何使用数据表中的稳态热特性参数
Java版智慧工地云平台源码(微服务+Java+Springboot+Vue+MySQL),支持私有化部署,SAAS模式
光电耦合器鉴别电路图
苹果发布新一代MacBookAir轻薄本 确认搭载双核心8代酷睿i5处理器
数字万用表测量误差分析