zoukankan      html  css  js  c++  java
  • undefine异常

      1 .text
      2 .global _start
      3 
      4 _start:
      5     b reset  /* vector 0 : reset */
      6     ldr pc, und_addr /* vector 4 : und 此时又跳回到4k flash中 */
      7 
      8 /* 这个操作是为了防止start.S超过4K内存 */
      9 und_addr:
     10     .word do_und
     11 
     12 do_und:
     13     /* 执行到这里之前:
     14      * 1. lr_und保存有被中断模式中的下一条即将执行的指令的地址
     15      * 2. SPSR_und保存有被中断模式的CPSR
     16      * 3. CPSR中的M4-M0被设置为11011, 进入到und模式
     17      * 4. 跳到0x4的地方执行程序 
     18      */
     19 
     20     /* sp_und未设置, 先设置它  这个sp是und特有的sp*/
     21     ldr sp, =0x34000000
     22 
     23     /* 在und异常处理函数中有可能会修改r0-r12, 所以先保存 */
     24     /* lr是异常处理完后的返回地址, 也要保存 */
     25     stmdb sp!, {r0-r12, lr}  
     26     
     27     /* 保存现场 */
     28     /* 处理und异常 */
     29     mrs r0, cpsr
     30     ldr r1, =und_string
     31     bl printException
     32     
     33     /* 恢复现场 */
     34     ldmia sp!, {r0-r12, pc}^  /* ^会把spsr的值恢复到cpsr里 */
     35     
     36 und_string:
     37     .string "undefined instruction exception"
     38 
     39 .align 4
     40 
     41 reset:
     42     /* 关闭看门狗 */
     43     ldr r0, =0x53000000
     44     ldr r1, =0
     45     str r1, [r0]
     46 
     47     /* 设置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */
     48     /* LOCKTIME(0x4C000000) = 0xFFFFFFFF */
     49     ldr r0, =0x4C000000
     50     ldr r1, =0xFFFFFFFF
     51     str r1, [r0]
     52 
     53     /* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8  */
     54     ldr r0, =0x4C000014
     55     ldr r1, =0x5
     56     str r1, [r0]
     57 
     58     /* 设置CPU工作于异步模式 */
     59     mrc p15,0,r0,c1,c0,0
     60     orr r0,r0,#0xc0000000   //R1_nF:OR:R1_iA
     61     mcr p15,0,r0,c1,c0,0
     62 
     63     /* 设置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 
     64      *  m = MDIV+8 = 92+8=100
     65      *  p = PDIV+2 = 1+2 = 3
     66      *  s = SDIV = 1
     67      *  FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
     68      */
     69     ldr r0, =0x4C000004
     70     ldr r1, =(92<<12)|(1<<4)|(1<<0)
     71     str r1, [r0]
     72 
     73     /* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
     74      * 然后CPU工作于新的频率FCLK
     75      */
     76     
     77     
     78 
     79     /* 设置内存: sp 栈 */
     80     /* 分辨是nor/nand启动
     81      * 写0到0地址, 再读出来
     82      * 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动
     83      * 否则就是nor启动
     84      */
     85     mov r1, #0
     86     ldr r0, [r1] /* 读出原来的值备份 */
     87     str r1, [r1] /* 0->[0] */ 
     88     ldr r2, [r1] /* r2=[0] */
     89     cmp r1, r2   /* r1==r2? 如果相等表示是NAND启动 */
     90     ldr sp, =0x40000000+4096 /* 先假设是nor启动 */
     91     moveq sp, #4096  /* nand启动 */
     92     streq r0, [r1]   /* 恢复原来的值 */
     93 
     94     bl sdram_init
     95     //bl sdram_init2     /* 用到有初始值的数组, 不是位置无关码 */
     96 
     97     /* 重定位text, rodata, data段整个程序 */
     98     bl copy2sdram
     99 
    100     /* 清除BSS段 */
    101     bl clean_bss
    102 
    103 
    104     ldr pc, =sdram
    105 sdram:
    106     bl uart0_init
    107 
    108     bl print1
    109     /* 故意加入一条未定义指令 */
    110 und_code:
    111     .word 0xdeadc0de  /* 未定义指令 */
    112     bl print2
    113 
    114     //bl main  /* 使用BL命令相对跳转, 程序仍然在NOR/sram执行 */
    115     ldr pc, =main  /* 绝对跳转, 跳到SDRAM */
    116 
    117 halt:
    118     b halt
    View Code

    代码整体跳转框图:

    跳转过程:

    1、一上电,CPU从0地址执行,执行 b reset(进行初始化操作)

    2、重定位程序

    3、跳转到sdram去继续执行

    4、执行到 0xdeadc0de,发生未定义指令异常

    5、跳转到异常向量表的 0x4 地址去执行

    6、跳转到sdram上执行异常处理函数(do_und)

    7、异常返回,继续执行 

  • 相关阅读:
    使用AWS、Docker与Rancher提供弹性的生产级服务
    如何用微服务重构应用程序
    Prometheus入门
    Docker监控:最佳实践以及cAdvisor和Prometheus监控工具的对比
    前后端分离session不一致问题
    Eclipse整合SSM框架+AOP+全局异常处理
    SSM配置基于注解AOP
    有关Linux
    Tomcat下配置javaWeb访问路径-Linux
    Linux下如何安装Nginx
  • 原文地址:https://www.cnblogs.com/lihanrui/p/13827459.html
Copyright © 2011-2022 走看看