IT业行者,行者无疆
分类: 嵌入式
2010-09-27 09:17:15
最近在学习TCP/IP协议,很是复杂,以前也没有正式的看过人家写过的代码,所以学习还是有一定的难度的,不过有信心,呵呵,所以最近很难,不过我要加紧把ARM相关的文章写完,然后计划在很快的时间内写一篇TCP/IP协议的移植代码及原理,如何使用等等,好的,来进行今天的移植工作吧。
IRQ.s文件
这个文件是一个很关键的头文件,里面有嵌入式中断的代码,实现了中断如何嵌套,下面会进行详细的分析
通知这个是32位的代码,因为在进入异常之后ARM内核是要进行32位模式的,所以这里的代码必须是32位的代码,否则后果将是相当的严重的,不是危言耸听哦,呵呵。
不用再解析了吧?看连载5有
;
;
;
;
IRQ_Handler
;
;
Timer0_Handler
需要操作系统管理的中断必须再这里定义,这里定义了一个宏,专为中断嵌套编写的一个宏,因为ARM内核在进入中断之后默认是禁止中断的,故我们要通过一种技术实现中断的嵌套。
;
IRQ.inc文件
NoInt
USR32Mode
SVC32Mode
SYS32Mode
IRQ32Mode
FIQ32Mode
以上是定义一些常量
;引入的外部标号在这声明
IMPORT
IMPORT
IMPORT
IMPORT
IMPORT
IMPORT
IMPORT
凡是在这个文件里使用的标号,且没有在这个文件定义的必须用 IMPORT
$IRQ_Label HANDLER $IRQ_Exception_Function
代表这里是定义一个宏
IMPORT
$IRQ_Label
只要你定义了需要系统管理的中断,那么只要这些中断发生之后都会第一时间进入这段代码,我们可以这么理解,其实zlg的中断潜入实现的方法是这样的,就是当中断发生的时候,统一进入一个入口代码,然后在这个入口代码做一些环境的保护,然后重新允许中断,执行用户需要的中断服务函数,这个函数是在系统模式开中断执行的,所以这里是可以进入中断的,这个服务函数执行完了之后,再返回到这段代码,进行一些环境的恢复,然后就是是否切换任务啦,等等的动作,要根据 UC/OS的要求来书写中断返回的代码。
计算返回地址,就是中断的返回地址啦
为什么只保存这几个参数??你可以参照ADS编译器的函数调用过程中的参数传递过程,R0-R3是用来函数调用中传递参数的,R12是进行运算用的,LR是函数调用中返回地址保存的。这里的SP值是要更新,就是SP保存好之后SP的指针自动调整
MRS
在进入IRQ中断后,原来那个模式下的CPSR会复制到IRQ中断的SPSR中,所以这里保护的是CPSR的值
STMFD
记住,这里有一个^标号,这里的SP还是IRQ模式的SP,但是大括号里面的数据是系统模式的寄存器,所以这段代码的意思是保护系统模式的CPSR值,SP 值,就是系统模式的SP,还有LR值,系统模式的LR值与这里IRQ模式的LR值是不一样的,因为我们的中断服务函数是在系统模式下开中断执行的,所以必须保护系统模式的LR值,否则会使中断返回后出错的,这里IRQ模式的SP是不回写的。
我们来解释另一个问题,IRQ_STACK_LEGTH
还记得这段代码吗??为什么一个中断嵌套就9个字,在上面的指令中总共使用了9个IRQ模式的SP空间,呵呵,看明白了吧??
LDR
LDRB
ADD
STRB
实现OSIntNesting++,这个变量是操作系统管理中断的依据,要求在中断中必须加1
上面保护了三个字的数据还没有调整SP指针呢。这里调整
CMP
这个指令很关键,实现了中断的嵌套。R1中保存的是OSIntNesting的当前值,已经进行了加1处理,当OSIntNesting这个变量是1的时候,所以这是第一层的中断,第一层中断才执行下面的指令,堆栈初始化,如果不是第一层就不需要了,因为已经在第一层初始化过了
BL
这个才是用户,也就是我们中断服务函数了,返回后执行下面的代码
防止在中断服务函数中修改了ARM的模式,代码能走到这所以已经没有中断嵌套了,这是最后一层中断
MOV
STR
OsEnterSum
STR
为了防止出现其他的错误,必须强行的置零
LDMFD
; 如果回写的是用户的SP,所以后面要调整SP
LDR
LDR
LDR
LDR
CMP
比较OSTCBHighRdy和OSTCBCur,如果不相等则代表要马上进行任务切换了
MSR
复制CPSR的值到SPSR中,因为IRQ中断返回的时候是会进行SPSR复制到CPSR的动作的
LDR
MEND
宏定义结束
;
(待续连载7)