打印

在贴 MDK FOR ARM 2440 启动 注解请教2级中断地址

[复制链接]
7549|44
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
itelectron|  楼主 | 2009-11-29 15:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 itelectron 于 2009-11-29 15:27 编辑

原 注解
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs//;向量中断模式/非向量中断模式 在PSRs设置(猜的)
  ; 系统的工作模式设定
Mode_USR        EQU     0x10  ; 定义用户模式标志代码;// 用户模式的CPSR代码
Mode_FIQ        EQU     0x11 ; 定义快速中断模式标志代码;// 快中断模式的CPSR代码
Mode_IRQ        EQU     0x12 ; 定义普通中断模式标志代码;// 中断模式的CPSR代码
Mode_SVC        EQU     0x13 ; 定义管理模式标志代码;// 管理模式的CPSR代码
Mode_ABT        EQU     0x17 ; 定义中止模式标志代码;// 中止模式的CPSR代码
Mode_UND        EQU     0x1B ; 定义未定义模式标志代码 ;// 未定义模式的CPSR代码
Mode_SYS        EQU     0x1F ; 定义系统模式(特权模式)标志代码;// 系统(特权)模式的CPSR代码
I_Bit           EQU     0x80    ;// 普通中断开关(0×80:打开;0×00:关闭)
F_Bit           EQU     0x40    ;// 快速中断开关(0×40:打开;0×00:关闭)
;//栈配置()
;系统的栈空间设定
UND_Stack_Size  EQU     0x00000000 ;未定义     
SVC_Stack_Size  EQU     0x00000008 ;管理模式端栈长度
ABT_Stack_Size  EQU     0x00000000 ;中止模式端栈长度
FIQ_Stack_Size  EQU     0x00000000 ;快速中断模式端栈长度
IRQ_Stack_Size  EQU     0x00000080 ;普通中断模式模式端栈长度
USR_Stack_Size  EQU     0x00000400 ;用户模端栈长度
;//
ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
                         FIQ_Stack_Size + IRQ_Stack_Size);所有的堆栈大小进行相加,得到总堆栈大小
/**********************************************************************************************
;//arm的汇编程序由段组成,段是相对独立的指令或数据单位,每个段由AREA伪指令定义,并定义段的属性:
;//READWRITE(读写)READONLY(只读)
**********************************************************************************************/
                AREA    STACK, NOINIT, READWRITE, ALIGN=3 ;开辟端栈段,段名(STACK)定义为可读可写,不初始化内存单元或将内存写0,字节对齐
Stack_Mem       SPACE   USR_Stack_Size  ;//申请栈内存空间
__initial_sp    SPACE   ISR_Stack_Size
Stack_Top       EQU     Stack_Mem + ISR_Stack_Size ;//定义堆栈开始地址(最大地址,堆栈向下访问)
;//堆配置
;//堆大小 (单位字节)//
Heap_Size       EQU     0x00000000        ;系统的堆空间设定//定义堆空间大小(配合最后的动态内存申请使用)
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3  ;//段名(HEAP)声明堆代码段(不初始化内存,可读写,字节对齐)
Heap_Mem        SPACE   Heap_Size ;//申请堆的内存空间
;时钟管理定义
CLK_BASE        EQU     0x4C000000      ; 时钟基地址
LOCKTIME_OFS    EQU     0x00            ; PLL锁定时间计数器对应基地址的偏移值
MPLLCON_OFS     EQU     0x04            ; MPLL控制 对应基地址的偏移值//认为MPLL分出三种模式:FCLK、HCLK、PCLK
UPLLCON_OFS     EQU     0X08            ; UPLL控制 对应基地址的偏移值//用于USB设备
CLKCON_OFS      EQU     0x0C            ; 时钟生成控制 对应基地址的偏移值
CLKSLOW_OFS     EQU     0x10            ; 慢时钟控制 对应基地址的偏移值
CLKDIVN_OFS     EQU     0X14            ; 时钟除法器控制 对应基地址的偏移值
CAMDIVN_OFS     EQU     0X18            ; 摄象时钟除法器控制 对应基地址的偏移值//UPLL提供
CLOCK_SETUP     EQU     1                 ; 时钟设置标记(开)
LOCKTIME_Val    EQU     0x0FFF0FFF        ; PLL锁定时间计数器 值
MPLLCON_Val     EQU     0x00043011        ; MPLL控制 值
UPLLCON_Val     EQU     0x00038021        ; UPLL控制 值
CLKCON_Val      EQU     0x001FFFF0        ; 时钟生成控制 值
CLKSLOW_Val     EQU     0x00000004        ; 慢时钟控制 值
CLKDIVN_Val     EQU     0x0000000F        ; 时钟除法器控制 值
CAMDIVN_Val     EQU     0x00000000        ; 摄象时钟除法器控制 值
;Interrupt  definitions      ;中断定义
INTOFFSET          EQU    0X4A000014                      ;中断请求源偏移 地址
;//中断向量表
;// 中断向量地址     <0x20-0x3fffff78>  
;// 中断向量表地址必须字对齐
;//</e>  
IntVT_SETUP      EQU     1            ;中断向量设置标记(开)
IntVTAddress    EQU     0x33ffff20    ;中断向量地址33ffff20  0x33ffff00 33FFFFF0

;----------------------- 存储器设定 ------------------------------------
IRAM_BASE       EQU     0x40000000      ; //内存基地址
;//看门狗定义
WT_BASE         EQU     0x53000000      ; 看门狗基地址
WTCON_OFS       EQU     0x00            ; 看门狗控制 对应基地址的偏移值
WTDAT_OFS       EQU     0x04            ; 看门狗数据 对应基地址的偏移值
WTCNT_OFS       EQU     0x08            ; 看门狗记数 对应基地址的偏移值
WT_SETUP        EQU     1               ; 看门狗设置标记(开)
WTCON_Val       EQU     0x00000000      ; 看门狗控制
WTDAT_Val       EQU     0x00008000      ; 看门狗数据
; 存储控制器设定
MC_BASE         EQU     0x48000000      ;   存储控制器基地址
MC_SETUP        EQU     0               ;   存储控制器设定标记(开)
BWSCON_Val      EQU     0x22000000        ;总线宽度和等待控制
BANKCON0_Val    EQU     0x00000700        ;Boot ROM 控制
BANKCON1_Val    EQU     0x00000700        ;BANK1 控制
BANKCON2_Val    EQU     0x00000700        ;BANK2 控制
BANKCON3_Val    EQU     0x00000700        ;BANK3 控制
BANKCON4_Val    EQU     0x00000700        ;BANK4 控制
BANKCON5_Val    EQU     0x00000700        ;BANK5 控制
BANKCON6_Val    EQU     0x00018005        ;BANK6 控制
BANKCON7_Val    EQU     0x00018005        ;BANK7 控制
REFRESH_Val     EQU     0x008404F3        ;DRAM/SDRAM 刷新 控制
BANKSIZE_Val    EQU     0x00000032        ;存储器大小 控制
MRSRB6_Val      EQU     0x00000020        ;SDRAM 的模式设置寄存器 控制
MRSRB7_Val      EQU     0x00000020        ;SDRAM 的模式设置寄存器 控制
;----------------------- 存储控制器设定结束 ------------------------------------
; I/O 口设定
PIO_BASE        EQU     0x56000000      ; 端口基地址
PCONA_OFS       EQU     0x00            ; 端口A控制 对应基地址的偏移值
PCONB_OFS       EQU     0x10            ; 端口B控制 对应基地址的偏移值
PCONC_OFS       EQU     0x20            ; 端口C控制 对应基地址的偏移值
PCOND_OFS       EQU     0x30            ; 端口D控制 对应基地址的偏移值
PCONE_OFS       EQU     0x40            ; 端口E控制 对应基地址的偏移值
PCONF_OFS       EQU     0x50            ; 端口F控制 对应基地址的偏移值
PCONG_OFS       EQU     0x60            ; 端口G控制 对应基地址的偏移值
PCONH_OFS       EQU     0x70            ; 端口H控制 对应基地址的偏移值
PCONJ_OFS       EQU     0xD0            ; 端口J控制 对应基地址的偏移值
PUPB_OFS        EQU     0x18            ; 端口B上拉控制 对应基地址的偏移值
PUPC_OFS        EQU     0x28            ; 端口C上拉控制 对应基地址的偏移值
PUPD_OFS        EQU     0x38            ; 端口D上拉控制 对应基地址的偏移值
PUPE_OFS        EQU     0x48            ; 端口E上拉控制 对应基地址的偏移值
PUPF_OFS        EQU     0x58            ; 端口F上拉控制 对应基地址的偏移值
PUPG_OFS        EQU     0x68            ; 端口G上拉控制 对应基地址的偏移值
PUPH_OFS        EQU     0x78            ; 端口H上拉控制 对应基地址的偏移值
PUPJ_OFS        EQU     0xD8            ; 端口J上拉控制 对应基地址的偏移值
;--------端口 配置--------------
PIO_SETUP       EQU     0             ; IO设定标记(关)
;端口A
PIOA_SETUP      EQU     0             ; IO设定标记(关)
PCONA_Val       EQU     0x000003FF
                                                   
;端口B
PIOB_SETUP      EQU     0             ; IO设定标记(关)
PCONB_Val       EQU     0x00000000      ;
PUPB_Val        EQU     0x00000000      ;端口B上拉开启
                                                   
;端口C
PIOC_SETUP      EQU     1             ; IO设定标记(开)
PCONC_Val       EQU     0x00001401      ;
PUPC_Val        EQU     0x00000000      ;端口C上拉开启
  
;端口D
PIOD_SETUP      EQU     0             ; IO设定标记(关)
PCOND_Val       EQU     0x00000000      ;
PUPD_Val        EQU     0x00000000      ;端口D上拉开启
  
;端口E
PIOE_SETUP      EQU     0             ; IO设定标记(关)
PCONE_Val       EQU     0x00000000      ;
PUPE_Val        EQU     0x00000000      ;端口E上拉开启
;端口F
PIOF_SETUP      EQU     0             ; IO设定标记(关)
PCONF_Val       EQU     0x00000000      ;
PUPF_Val        EQU     0x00000000      ;端口F上拉开启
                                                
;端口G
PIOG_SETUP      EQU     0             ; IO设定标记(关)
PCONG_Val       EQU     0x00000000      ;
PUPG_Val        EQU     0x00000000      ;端口G上拉开启
                                                      
;端口H
PIOH_SETUP      EQU     0             ; IO设定标记(关)
PCONH_Val       EQU     0x000007FF       ;
PUPH_Val        EQU     0x00000000      ;端口H上拉开启
                                                  
;端口J
PIOJ_SETUP      EQU     0             ; IO设定标记(关)
PCONJ_Val       EQU     0x00000000      ;
PUPJ_Val        EQU     0x00000000      ;端口J上拉开启

相关帖子

沙发
itelectron|  楼主 | 2009-11-29 15:06 | 只看该作者
(2)


   ldr    r9,[r9]                ;载入INTOFFSET
                ldr    r8,=HandleEINT0        ;加载2级中断向量表基地
                add    r8,r8,r9,lsl #2    ;计算中断处理表的入口地址 ??装载中断处理函数的指针??
                ldr    r8,[r8]                ;装载中断处理函数的地址
                str    r8,[sp,#8]                ;将中断处理函数的地址存入刚才预留的位置,r8和r9的上面
                ldmfd  sp!,{r8-r9,pc}    ;出栈后,pc指向的既是中断处理函数的地址         
                ENDIF
;开辟存储空间定义中断入口地址
Reset_Addr      DCD     Reset_Handler ;定义中断的入口地址
Undef_Addr      DCD     Undef_Handler
SWI_Addr        DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                DCD     0              ;//保留地址
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler

Undef_Handler   B       Undef_Handler ;中断处理程序的入口地址//B为跳转指令|| ??自己跳转到自己??
SWI_Handler     B       SWI_Handler
PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler
               
                IF      IntVT_SETUP <> 1        ;判断设置标记
IRQ_Handler     B       IRQ_Handler
                ENDIF
               
                IF      IntVT_SETUP <> 0 ;判断设置标记
IRQ_Handler     B       IRQ_Entry
                ENDIF
               
FIQ_Handler     B       FIQ_Handler


;//存储控制器配制
                IF      MC_SETUP <> 0 ;判断设置标记
MC_CFG
                DCD     BWSCON_Val  ;开辟存储空间并写入相关配置 存储控制器 的数据
                DCD     BANKCON0_Val
                DCD     BANKCON1_Val
                DCD     BANKCON2_Val
                DCD     BANKCON3_Val
                DCD     BANKCON4_Val
                DCD     BANKCON5_Val
                DCD     BANKCON6_Val
                DCD     BANKCON7_Val
                DCD     REFRESH_Val
                DCD     BANKSIZE_Val
                DCD     MRSRB6_Val
                DCD     MRSRB7_Val
                ENDIF


;//时钟管理配置
                IF      CLOCK_SETUP <> 0        ;判断设置标记
CLK_CFG
                DCD     LOCKTIME_Val    ;开辟存储空间并写入相关配置 时钟管理 的数据
                DCD     CLKDIVN_Val
                DCD     UPLLCON_Val
                DCD     MPLLCON_Val
                DCD     CLKSLOW_Val
                DCD     CLKCON_Val
                DCD     CAMDIVN_Val
                ENDIF

            
;//I/O 配置
               
                IF      PIO_SETUP <> 0
PIOA_CFG     
                DCD     PCONA_Val    ;开辟存储空间并写入相关配置 I/O  的数据
PIOB_CFG        DCD     PCONB_Val
                DCD     PUPB_Val
PIOC_CFG        DCD     PCONC_Val
                DCD     PUPC_Val
PIOD_CFG        DCD     PCOND_Val
                DCD     PUPD_Val
PIOE_CFG        DCD     PCONE_Val
                DCD     PUPE_Val
PIOF_CFG        DCD     PCONF_Val
                DCD     PUPF_Val
PIOG_CFG        DCD     PCONG_Val
                DCD     PUPG_Val
PIOH_CFG        DCD     PCONH_Val
                DCD     PUPH_Val
PIOJ_CFG        DCD     PCONJ_Val
                DCD     PUPJ_Val
                ENDIF

使用特权

评论回复
板凳
itelectron|  楼主 | 2009-11-29 15:06 | 只看该作者
(3)

; //复位处理模块
                                       ;//下面是重起时的中断处理函数
                EXPORT  Reset_Handler  ;//定义一个全局函数名变量
Reset_Handler   

                IF      WT_SETUP <> 0                        ;//看门狗处理;若WT_SETUP为1,则执行下面配置语句
                LDR     R0, =WT_BASE
                LDR     R1, =WTCON_Val
                LDR     R2, =WTDAT_Val
                STR     R2, [R0, #WTCNT_OFS]
                STR     R2, [R0, #WTDAT_OFS]
                STR     R1, [R0, #WTCON_OFS]
                ENDIF
               
               
                IF      CLOCK_SETUP <> 0                ;//时钟处理;若CLOCK_SETUP为1,则执行下面配置语句
                LDR     R0, =CLK_BASE            
                ADR     R8, CLK_CFG
                LDMIA   R8, {R1-R7}            
                STR     R1, [R0, #LOCKTIME_OFS]
                STR     R2, [R0, #CLKDIVN_OFS]  
                STR     R3, [R0, #UPLLCON_OFS]
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                STR     R4, [R0, #MPLLCON_OFS]  
                STR     R5, [R0, #CLKSLOW_OFS]
                STR     R6, [R0, #CLKCON_OFS]
                STR     R7, [R0, #CAMDIVN_OFS]
                ENDIF                          
                                    
                IF      MC_SETUP <> 0                        ;//存储控制器处理;若MC_SETUP为1,则执行下面配置语句
                ADR     R13, MC_CFG
                LDMIA   R13, {R0-R12}
                LDR     R13, =MC_BASE
                STMIA   R13, {R0-R12}
                ENDIF                           
                                
                IF      PIO_SETUP <> 0                        ;//IO处理;若PIO_SETUP为1,则执行下面配置语句
                LDR     R13, =PIO_BASE

                IF      PIOA_SETUP <> 0                        ;//端口A处理;若PIOA_SETUP为1,则执行下面配置语句       
                ADR     R0, PIOA_CFG
                STR     R0, [R13, #PCONA_OFS]
                ENDIF

                IF      PIOB_SETUP <> 0                        ;//端口B处理        满足条件则执行下面配置语句       
                ADR     R0, PIOB_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONB_OFS]
                STR     R1, [R13, #PUPB_OFS]
                ENDIF

                IF      PIOC_SETUP <> 0                        ;//端口C处理  满足条件则执行下面配置语句
                ADR     R0, PIOC_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONC_OFS]
                STR     R1, [R13, #PUPC_OFS]
                ENDIF

                IF      PIOD_SETUP <> 0                        ;//端口D处理  满足条件则执行下面配置语句
                ADR     R0, PIOD_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCOND_OFS]
                STR     R1, [R13, #PUPD_OFS]
                ENDIF

                IF      PIOE_SETUP <> 0                          ;//端口E处理  满足条件则执行下面配置语句
                ADR     R0, PIOE_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONE_OFS]
                STR     R1, [R13, #PUPE_OFS]
                ENDIF

                IF      PIOF_SETUP <> 0                          ;//端口F处理  满足条件则执行下面配置语句
                ADR     R0, PIOF_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONF_OFS]
                STR     R1, [R13, #PUPF_OFS]
                ENDIF

                IF      PIOG_SETUP <> 0                          ;//端口G处理  满足条件则执行下面配置语句
                ADR     R0, PIOG_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONG_OFS]
                STR     R1, [R13, #PUPG_OFS]
                ENDIF
  
                IF      PIOH_SETUP <> 0                         ;//端口H处理  满足条件则执行下面配置语句
                ADR     R0, PIOH_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONH_OFS]
                STR     R1, [R13, #PUPH_OFS]
                ENDIF
               
                IF      PIOJ_SETUP <> 0                        ;//端口J处理  满足条件则执行下面配置语句
                ADR     R0, PIOJ_CFG
                LDR     R1, [R0,#4]
                STR     R0, [R13, #PCONJ_OFS]
                STR     R1, [R13, #PUPJ_OFS]
                ENDIF

                ENDIF
               
;;以下函数为进入相应的模式,并定义相应模式的端栈大小
;//为每个模式设置栈
                LDR     R0, =Stack_Top

;//进入未定义指令模式并设定其栈指针
                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
                MOV     SP, R0
                SUB     R0, R0, #UND_Stack_Size

;//进入异常中断模式,并设定其栈指针
                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
                MOV     SP, R0
                SUB     R0, R0, #ABT_Stack_Size

;//进入 FIQ 模式,并设定其栈指针
                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
                MOV     SP, R0
                SUB     R0, R0, #FIQ_Stack_Size

;//进入 IRQ 模式,并设定其栈指针
                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
                MOV     SP, R0
                SUB     R0, R0, #IRQ_Stack_Size

;//进入 Supervisor 模式,并设定其栈指针
                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
                MOV     SP, R0
                SUB     R0, R0, #SVC_Stack_Size
;               IMPORT  MMU_EnableICache
;               bl      MMU_EnableICache


;//进入 用户 模式,并设定其栈指针  //;最后进入用户模式
                MSR     CPSR_c, #Mode_USR
                MOV     SP, R0
                SUB     SL, SP, #USR_Stack_Size


;//进入C代码
                                          
                IMPORT  __main  ;在进入真正的main()之前会调用一些函数拷贝 DATA 到RAM中
                LDR     R0, =__main
                BX      R0


;//用护初始堆与栈 ;//用户设置堆栈程序(C外部接口:用于动态申请内存使用)

                AREA    |.text|, CODE, READONLY

               ; IMPORT  __use_two_region_memory

                EXPORT  __user_initial_stackheap
__user_initial_stackheap  
/**********************************************************************
//__user_initial_stackheap 库函数用法翻译
用法:
        __user_initial_stackheap 返回这些值:
                1. 堆基址(heap base)                          ---> RO
                2. 栈基址(stack base,一般为栈的最高地址)      ---> R1
                3. 堆顶(heap limit)                           ---> R2
                4. 栈顶(stack limit)                          ---> R3
***********************************************************************/

                LDR     R0, =  Heap_Mem
                LDR     R1, =(Stack_Mem + USR_Stack_Size)
                LDR     R2, = (Heap_Mem +      Heap_Size)
                LDR     R3, = Stack_Mem
                BX      LR

                END

使用特权

评论回复
地板
itelectron|  楼主 | 2009-11-29 15:09 | 只看该作者
在看 2440 之 有傻 B
对哪个 pISR_SWI=(_ISR_STARTADDRESS+0xf0); //for pSOS
迷惑 又回过头 看了下 启动代码!!
看来想饶开 汇编 还是 难啊!

使用特权

评论回复
5
itelectron|  楼主 | 2009-11-29 15:15 | 只看该作者
IntVTAddress    EQU     0x33ffff20    ;中断向量地址33ffff20  0x33ffff00 33FFFFF0

;//中断向量表地址 定义 //这里因该是2级中断向量表 应该是可以重新定位的吧 比如定义到RAM空间           
HandleEINT0          EQU    IntVTAddress  ;中断向量基地址

---------------------------------------------
IRQ_Entry
                sub    sp,sp,#4       ;预留返回指针的存储位置
                stmfd  sp!,{r8-r9}            ;存指针
                ldr    r9,=INTOFFSET        ;
                ldr    r9,[r9]                ;载入INTOFFSET
                ldr    r8,=HandleEINT0        ;加载2级中断向量表基地
                add    r8,r8,r9,lsl #2    ;计算中断处理表的入口地址 ??装载中断处理函数的指针??
                ldr    r8,[r8]                ;装载中断处理函数的地址
                str    r8,[sp,#8]                ;将中断处理函数的地址存入刚才预留的位置,r8和r9的上面
                ldmfd  sp!,{r8-r9,pc}    ;出栈后,pc指向的既是中断处理函数的地址         
                ENDIF
-------------------------------------------------------------------------------------

使用特权

评论回复
6
itelectron|  楼主 | 2009-11-29 15:17 | 只看该作者
INTOFFSET          EQU    0X4A000014                      ;中断请求源偏移 地址

使用特权

评论回复
7
itelectron|  楼主 | 2009-11-29 15:19 | 只看该作者
#define _ISR_STARTADDRESS         0x33ffff00

使用特权

评论回复
8
itelectron|  楼主 | 2009-11-29 15:19 | 只看该作者
#define pISR_SWI                (*(unsigned _*)(_ISRSTARTADDRESS+0x8))

使用特权

评论回复
9
itelectron|  楼主 | 2009-11-29 15:20 | 只看该作者
pISR_SWI=(_ISR_STARTADDRESS+0xf0);        //for pSOS

使用特权

评论回复
10
itelectron|  楼主 | 2009-11-29 15:23 | 只看该作者
本帖最后由 itelectron 于 2009-11-29 15:26 编辑

pISR_SWI=0x33fffff0
目前还是不清楚这个pISR_SWI的内容可否 随便在RAM 空间定义
如 RAM 0X30000000-----0X34000000 64M

使用特权

评论回复
11
itelectron|  楼主 | 2009-11-29 15:25 | 只看该作者
补充下 除 下列 地址 外
#define pISR_RESET                (*(unsigned *)(_ISR_STARTADDRESS+0x0))
#define pISR_UNDEF                (*(unsigned *)(_ISR_STARTADDRESS+0x4))
#define pISR_SWI                (*(unsigned *)(_ISR_STARTADDRESS+0x8))
#define pISR_PABORT                (*(unsigned *)(_ISR_STARTADDRESS+0xc))
#define pISR_DABORT                (*(unsigned *)(_ISR_STARTADDRESS+0x10))
#define pISR_RESERVED        (*(unsigned *)(_ISR_STARTADDRESS+0x14))
#define pISR_IRQ                (*(unsigned *)(_ISR_STARTADDRESS+0x18))
#define pISR_FIQ                (*(unsigned *)(_ISR_STARTADDRESS+0x1c))
// Interrupt vector
#define pISR_EINT0                (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1                (*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2                (*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT3                (*(unsigned *)(_ISR_STARTADDRESS+0x2c))
#define pISR_EINT4_7        (*(unsigned *)(_ISR_STARTADDRESS+0x30))
#define pISR_EINT8_23        (*(unsigned *)(_ISR_STARTADDRESS+0x34))
#define pISR_CAM                (*(unsigned *)(_ISR_STARTADDRESS+0x38))                // Added for 2440.
#define pISR_BAT_FLT        (*(unsigned *)(_ISR_STARTADDRESS+0x3c))
#define pISR_TICK                (*(unsigned *)(_ISR_STARTADDRESS+0x40))
#define pISR_WDT_AC97                (*(unsigned *)(_ISR_STARTADDRESS+0x44))
#define pISR_TIMER0                 (*(unsigned *)(_ISR_STARTADDRESS+0x48))
#define pISR_TIMER1                 (*(unsigned *)(_ISR_STARTADDRESS+0x4c))
#define pISR_TIMER2                (*(unsigned *)(_ISR_STARTADDRESS+0x50))
#define pISR_TIMER3                (*(unsigned *)(_ISR_STARTADDRESS+0x54))
#define pISR_TIMER4                (*(unsigned *)(_ISR_STARTADDRESS+0x58))
#define pISR_UART2                (*(unsigned *)(_ISR_STARTADDRESS+0x5c))
#define pISR_LCD                (*(unsigned *)(_ISR_STARTADDRESS+0x60))
#define pISR_DMA0                (*(unsigned *)(_ISR_STARTADDRESS+0x64))
#define pISR_DMA1                (*(unsigned *)(_ISR_STARTADDRESS+0x68))
#define pISR_DMA2                (*(unsigned *)(_ISR_STARTADDRESS+0x6c))
#define pISR_DMA3                (*(unsigned *)(_ISR_STARTADDRESS+0x70))
#define pISR_SDI                (*(unsigned *)(_ISR_STARTADDRESS+0x74))
#define pISR_SPI0                (*(unsigned *)(_ISR_STARTADDRESS+0x78))
#define pISR_UART1                (*(unsigned *)(_ISR_STARTADDRESS+0x7c))
#define pISR_NFCON                (*(unsigned *)(_ISR_STARTADDRESS+0x80))                // Added for 2440.
#define pISR_USBD                (*(unsigned *)(_ISR_STARTADDRESS+0x84))
#define pISR_USBH                (*(unsigned *)(_ISR_STARTADDRESS+0x88))
#define pISR_IIC                (*(unsigned *)(_ISR_STARTADDRESS+0x8c))
#define pISR_UART0                (*(unsigned *)(_ISR_STARTADDRESS+0x90))
#define pISR_SPI1                (*(unsigned *)(_ISR_STARTADDRESS+0x94))
#define pISR_RTC                (*(unsigned *)(_ISR_STARTADDRESS+0x98))
#define pISR_ADC                (*(unsigned *)(_ISR_STARTADDRESS+0x9c))

使用特权

评论回复
12
itelectron|  楼主 | 2009-11-29 15:53 | 只看该作者
本帖最后由 itelectron 于 2009-12-12 10:04 编辑

下面 是 网上找的 不知道有木有  补充的 ???
细心的读者可以发现这段数据区的起始地址是_ISR_STARTADDRESS,在MAIN函数中只要让(*(unsigned *)(_ISR_STARTADDRESS+0x74)) =(int)MyIsr(MyIsr是中断服务程序的名称);但是_ISR_STARTADDRESS是一个非定值,这个值只有在连接器连接的时候才赋值,在编译阶段他是个不定值,所以编译的时候会报错。#define _ISR_STARTADDRESS 成一个在SDRAM中的地址值。在本例中是0xc7fff00

使用特权

评论回复
13
itelectron|  楼主 | 2009-11-29 15:59 | 只看该作者
那么

异常 向量表 的地址 是 固定的(关MMU) 一级中断
中断向量表是 可变的                  二级中断

使用特权

评论回复
14
itelectron|  楼主 | 2009-11-29 16:02 | 只看该作者
那么 请教 2级中断 的基地址 是 通过 1级中断中的
#define pISR_SWI                (*(unsigned *)(_ISR_STARTADDRESS+0x8))
跳转的么?

使用特权

评论回复
15
itelectron|  楼主 | 2009-12-10 18:42 | 只看该作者

(转(转 (转 (转 0

Linux混入了mmu内存管理之后,ARM的中断是怎么样的呢?和我们在裸板上的中断有没有区别?让我们从源代码入手,做一个粗略的分析:

init/main.c->start_kernel()->trap_init()
//-----------------------------------------------
1.trap_init()
//gliethttp函数位于arch/arm/kernel/traps.c
void __init trap_init(void)
{
    extern void __trap_init(unsigned long);
    unsigned long base = vectors_base(); //返回中断base基址0xffff0000
    __trap_init(base);                   //以base为vector基址,初始化中断向量表
    if (base != 0)
        printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
            base);
#ifdef CONFIG_CPU_32
    modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
#endif
}
//--------------------------------------
2.vectors_base()
//gliethttp include/arch/asm-arm/proc-armv/system.h
extern unsigned long cr_alignment;
#if __LINUX_ARM_ARCH__ >= 4                //at91rm9200是ARMV4结构
#define vectors_base()    ((cr_alignment & CR_V) ? 0xffff0000 : 0)
#else
#define vectors_base()    (0)
                  #endif

      可以看到ARMv4以下的版本,该地址固定为0;ARMv4及以上版本,ARM中断向量表的地址由CP15协处理器c1寄存器中V位(bit[13])控制,V和中断向量表的对应关系如下:

V=0    ~    0x00000000~0x0000001C
V=1    ~    0xffff0000~0xffff001C
//------------------------------------------
2.1 cr_alignment
//gliethttp arch/arm/kernel/entry-armv.S
ENTRY(stext)
        mov    r12, r0
        mov    r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
        msr    cpsr_c, r0                @ and all irqs disabled
//__lookup_processor_type 查询处理器类型,[gliethttp
以后补上<浅析head-armv.S>]返回值
//2007-07-04
//r9 = processor ID                    //读取cp15的c0寄存器
//r10 = pointer to processor structure
//下面会add pc, r10, #12,跳转到__arm920_setup
//gliethttp 在vmlinux-armv.lds.in中
//__proc_info_begin = .;
//             *(.proc.info)
// __proc_info_end = .;
//见2.2
        bl    __lookup_processor_type
        teq    r10, #0                   @ invalid processor?
        moveq    r0, #'p'                @ yes, error 'p'
        beq    __error
        bl    __lookup_architecture_type
        teq    r7, #0                    @ invalid architecture?
        moveq    r0, #'a'                @ yes, error 'a'
        beq    __error
//__create_page_tables 创建arm启动临时使用的前4M页表
        bl    __create_page_tables
        adr    lr, __ret                 @ return address
        add    pc, r10, #12              @ initialise processor
        .type    __switch_data, %object
__switch_data:    .long    __mmap_switched
        .long    SYMBOL_NAME(__bss_start)
        .long    SYMBOL_NAME(_end)
        .long    SYMBOL_NAME(processor_id)
        .long    SYMBOL_NAME(__machine_arch_type)
        .long    SYMBOL_NAME(cr_alignment)
        .long    SYMBOL_NAME(init_task_union)+8192
/*
* Enable the MMU. This completely changes the structure of the visible
* memory space. You will not be able to trace execution through this.
* If you have an enquiry about this, *please* check the linux-arm-kernel
* mailing list archives BEFORE sending another post to the list.
*/
        .type    __ret, %function
__ret:        ldr    lr, __switch_data
        mcr    p15, 0, r0, c1, c0
//将__arm920_setup中设置的r0值,置入cp15协处理器c1寄存器中
        mrc    p15, 0, r0, c1, c0, 0     @ read it back.
        mov    r0, r0
//填充armv4中的三级流水线:mov r0,
r0 对应一个nop,所以对应2个nop和一个mov pc,lr刚好三个"无用"操作
        mov    r0, r0
        mov    pc, lr
//跳转到__mmap_switched函数 gliethtttp
/*
* The following fragment of code is executed with the MMU on, and uses
* absolute addresses; this is not position independent.
*
* r0 = processor control register
* r1 = machine ID
* r9 = processor ID
*/
        .align    5
__mmap_switched:
        adr    r3, __switch_data + 4
        ldmia    r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat
//2007-07-04 gliethttp
//r4    ~    __bss_start
//r5    ~    _end
//r6    ~    processor_id
//r7    ~    __machine_arch_type
//r8    ~    cr_alignment
//sp    ~    (init_task_union)+8192
//以下几步操作对processor_id,__machine_arch_type,cr_alignment赋值gliethttp
        mov    fp, #0                                @ Clear BSS (and zero fp)
1:      cmp    r4, r5                                //bss区清0
        strcc    fp, [r4],#4
        bcc    1b
        str    r9, [r6]                              @ Save processor ID
        str    r1, [r7]                              @ Save machine type
#ifdef CONFIG_ALIGNMENT_TRAP
        orr    r0, r0, #2                            @ ...........A.
#endif
        bic    r2, r0, #2                            @ Clear 'A' bit
//r2存放 禁用TRAP队列故障 后的r0值
//r8->cr_alignment,cr_no_alignment
//所以stmia    r8, {r0, r2}后,cr_alignment = r0,cr_no_alignment = r2
        stmia    r8, {r0, r2}           @ Save control register values
        b    SYMBOL_NAME(start_kernel)        //进入内核C程序
//--------------------------------------
2.2 __arm920_proc_info
//gliethttp arch/arm/mm/proc-arm920.S
.section ".proc.info", #alloc, #execinstr
    .type    __arm920_proc_info,#object
__arm920_proc_info:
//该地址存储到r10中
    .long    0x41009200
    .long    0xff00fff0
    .long    0x00000c1e                               @ mmuflags
    b    __arm920_setup
//add pc, r10, #12 gliethttp将使cpu执行b __arm920_setup跳转指令
    .long    cpu_arch_name
    .long    cpu_elf_name
    .long    HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
    .long    cpu_arm920_info
    .long    arm920_processor_functions
    .size    __arm920_proc_info, . - __arm920_proc_info
//----------------------------------------
2.3 __arm920_setup
    .section ".text.init", #alloc, #execinstr
__arm920_setup:
    mov    r0, #0
    mcr    p15, 0, r0, c7, c7        @ invalidate I,D caches on v4
    mcr    p15, 0, r0, c7, c10, 4    @ drain write buffer on v4
    mcr    p15, 0, r0, c8, c7        @ invalidate I,D TLBs on v4
    mcr    p15, 0, r4, c2, c0        @ load page table pointer
    mov    r0, #0x1f                 @ Domains 0, 1 = client
    mcr    p15, 0, r0, c3, c0        @ load domain access register
    mrc    p15, 0, r0, c1, c0        @ get control register v4
/*
* Clear out 'unwanted' bits (then put them in if we need them)
*/
//gliethttp r0单元存放了cp15协处理器c1寄存器的值,如下代码对该值进行加工
                                          @ VI ZFRS BLDP WCAM
    bic    r0, r0, #0x0e00                           //清0 bit[9..11]
    bic    r0, r0, #0x0002                           //清0 bit[1]
    bic    r0, r0, #0x000c
    bic    r0, r0, #0x1000                @ ...0 000. .... 000.
/*
* Turn on what we want
*/
    orr    r0, r0, #0x0031                           //bit0=1 使能mmu
    orr    r0, r0, #0x2100                @ ..1. ...1 ..11 ...1
//bit13=1 中断向量表基址为0xFFFF0000
#ifndef CONFIG_CPU_DCACHE_DISABLE
    orr    r0, r0, #0x0004                @ .... .... .... .1..
#endif
#ifndef CONFIG_CPU_ICACHE_DISABLE
    orr    r0, r0, #0x1000                @ ...1 .... .... ....
#endif
                      mov    pc, lr

使用特权

评论回复
16
itelectron|  楼主 | 2009-12-10 18:42 | 只看该作者
17
xinzha| | 2009-12-11 10:52 | 只看该作者
个人感觉,_ISR_STARTADDRESS这个表只是一种软件手段,看了一些网上的例子,讲到0x1c之前的那些只是为了格式,并没有真正的意义,而后面的表格就是你自己可以配置的一些中断入口。
建议去看一下lpc22xx的资料,里面对ARM的vic中断控制ip讲得比较详细,ZLG应该有很多关于这个的例程。

使用特权

评论回复
18
xinzha| | 2009-12-11 10:54 | 只看该作者
可否传一份2440的代码看看?没接触过,很好奇,呵呵

使用特权

评论回复
19
huangqi412| | 2009-12-11 12:18 | 只看该作者
晕,LS随便网上搜啊

使用特权

评论回复
20
xinzha| | 2009-12-11 13:22 | 只看该作者
人可以做到很懒的...

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:MARK: zhi kan ji shu

274

主题

2762

帖子

8

粉丝