zoukankan      html  css  js  c++  java
  • ARM体系结构(1)

    嵌入式系统的构成 

      软件:
        应用程序
        第三方库(Qt,libc,myclient)
        操作系统:
        引导程序
        内核+驱动
        文件系统
      硬件:
        底板:
          外置芯片
            网卡(DM9000)
            声卡
            ADC
            电源
            USB
          接口:
            串口
            SD
            LCD+触摸屏
            摄像头
            按键
          核心板:
            Soc(CPU+uart+timer)
            DDR
            Nand

    ARM的体系结构

    一、ARM的工作模式

      用户模式
      系统模式
      快速中断模式
      外部中断模式
      特权模式
      快速模式
      未定义模式
      除用户模式外,其它被称为特权模式
      用户模式和系统模式外,其它被称为异常模式

    二、ARM的寄存器

    一共37个寄存器,用户模式和系统模式可以使用17个,其它模式可以使用18个(17+状态寄存器的备份)。

    r0~r7:所有模式共用
    r8~r12:快速中断模式有它私有的,其它模式共用。
    r13~r14:用户模式和系统模式共用,其它模式有私有的。
    r15、cpsr:所有模式共用
    r15也叫pc:程序计数器,它记录着下一条要执行的程序,可以被赋值,这样就实现了跳转。
    cpsr:用户来记录上一条指令的执行状态,进位、溢出、零、负数、当前模式,只有12位有效,其它位目前保留。
    spsr:用户模式和系统模式下没有,其它模式有私有的。
    与cpsr的格式一样,它是用来备份用户模式和系统模式的cpsr。

    三、流水线

    一条指令的执行需要六个步骤:
      1、取指
      2、译码
      3、取数
      4、计算
      5、存储
      6、回写
    如果只是按顺序执行,那么执行其中一项操作时其它硬件都处于空闲状态,因此ARM引入了流水线的概念,每个控制单元只负责干一件事情,这样理论上,三级流水线就提高了三倍的性能,而5级流水线就提高了五倍的性能。
    但实际情况其实达不到,因为流水线会被打断、暂停。
    比如:

      1. b1 func //跳转指令
      2. ldr r0,[r0,#0]
        add r0,r0,r1//这一步要等上一行的r0回写完成才能开始执行这一步,因为也会打断流水线,在上一个步骤完成之前,只能执行前两个步骤,即取指和译码,取数要等回写之后才可以取出r0 里面的值

    四、ARM处理器寻址方式

    1.立即寻址
      ADD R0,R0,#1中的 #1
    2.寄存器寻址
      ADD R0,R1,R0 中的R0和R1,直接把寄存器当成一个变量使用
    3.寄存器间接寻址
      ldr r1,[r0,#4] ADD把寄存器当指针变量使用,这条语句就是把(r0+4)(加四个地址,不是加4)的放到r1中去,但是r0的值不变
    4.寄存器偏移寻址
      r0 << n,对寄存器进行左移或者右移操作
    5.基址变址寻址:
      [r0,#1],相当于对指针变量进行加减操作,*(r0+1)
    6.多寄存器寻址
      LDMIA r0,{r1,r2,r3,r4} 寄存器的批量操作,把r0里面的值复制到r1,r2,r3和r4中去
    7.堆栈寻址:
      可以使用堆内存和栈内存,但前提是要设置好堆内存和栈内存的基地址。

    五、ARM指令集

    1、ARM指令的格式
      <opcode> {<cond>}{S} <Rd>,<Rn> <operand2>...
      opcode 指令码
      cond 条件码
      S 是否影响状态寄存器
      Rd 目标寄存器
      Rn 源寄存器

      shifter_operand 表示第二个操作数
      {} 可以省略,而<>必须要有的
    2、RM指令条件执行及标志位
      CMP会自动把比较结果存储到状态寄存器
      而数据处理指令需要在指令反加S才会把计算结果存储到状态寄存器。

        数据处理指令:https://www.cnblogs.com/electronic/p/11011777.html
      EQ 相等
      NE 不等
    3、跳转指令

      B 相对地址跳转,在当前地址的基础上加一个偏移值进行跳转(速度快,但是跳转的范围有限+/-32MB以内)
      BL 绝对地址跳转,需要一个完整的地址,在跳转前会把下一条指令的地址存储到R14中,然后跳到目标位置进行执行,执行完后,可以从R14恢复到p中,这样就实现了返回(指令可以继续执行下去,B跳转了就不能返回,BL可以返回)
      BLX 功能与BL类似,但是BLX可以从ARM状态切换到Thumb状态(ARM是32位的,Thumb是16位的),当指令较短,涉及的数据少的时候用thumb状态生成的可执行文件较小,基本能小一半。
      BX 功能与B类似,BX可以从ARM状态切换到Thumb状态。

    4、数据处理指令
      MOV r0,#100 <=> r0 = 100
      MOV R1,R3,LSL,#3 <=> r1 = r3 <<3

      MVN r0,#100 <=> r0 = ~100
      ADD r0,r1,#110 <=> r0=r1+110
      SUB R0,R0,#1 <=> r0-=1 反减
      RSB R3,R1,#0xFF00 <=> r3=0xff00-r1

      ADDS R1,R1,R2
      ADC R0,R0,R2 带进位的加

      SUBS R0,R0,R2
      SBC R1,R1,R3 带借位的减

      RSBS R2,R0,#0
      RSC R3,R1,#0 带借位的反减

      AND R0,R0,#3 <=> r0 = r0&3
      ORR R0,R0,#3 <=> r0 = r0|3
      EOR R1,R1,#3 <=> r1 = r1^3
      BIC R0,R0,#3 <=> r0 = r0&(~3)
      CMP R1,R0 把两个数的比较结果影响状态寄存器
      CMN R1,R0 把两个数求反后比较,并把比较结果结果影响状态寄存器
      TST R0,#0x01 把两个数进行按位与操作,并把计算结果影响状态寄存器
      TEQ R1,R2 把两个数进行按位异或操作,并把计算结果影响状态寄存器
    5、程序状态寄存器传输指令
      MRS R7,CPSR 把当前模式的状态寄存器备份到r7
      MSR CPSR_cxsf,R3 把数据写入到状态寄存器
      [31:24] 为条件标志位域,用f表示
      [23:16] 为状态位域,用s表示
      [15:8] 为扩展位域,用x表示
      [7:0] 为控制位域,用c表示
    6、Load、Store指令
      Load 从内存加载数据到寄存器
      LDR R0,#8
      LDR R0,[R1,#8] <=> r0 = *(r1+8);
      DMFD R13,{R0,R4‐R12,LR}

      Store 把寄存器中的数据写到内存
      STR #8,R0
      STR R0,[R1,#8] *(r1+8) = r0
      STMFD R13,{R0,R4‐R12,LR}
      SWP r0,r1,r2 <=> r0 = r2; r2 = r1;
    7、中断指令
      SWI 0-16777215 一旦这条指令就会进入中断模式。

    六、电源锁定:

    1、找到厂家提供的代码,保存为start.S文件。
      start:
      ldr r0, =0xe010e81c
      ldr r1, [r0]
      orr r1, r1, #0x300
      orr r1, r1, #0x1
      str r1, [r0]
    2、生成目标代码
      arm-none-linux-gnueabi-gcc -c start.S ->start.o
    3、生成可执行文件(设置代码段、不加入启动代码、不加入标准库)
      arm-none-linux-gnueabi-gcc -Ttext 0xd0020010 -nostartfiles -nostdlib start.o -o lock
    4、从可执行文件中拷贝出纯二进制指令
      arm-none-linux-gnueabi-objcopy -O binary lock lock.bin
    5、编译出添加校验和的工具(研究一下,明天我们自己写一份)
      gcc mkv210_image.c -o mkv210
    6、为lock.bin添加校验和
      ./mkv210 lock.bin lock_image.bin
    7、把添加校验和后的文件烧写到SD卡中执行,效果:开发板能够持续供电。

  • 相关阅读:
    和2018年年初做管理系统的不同(vuex)
    项目中使用package-lock.json锁版本问题
    沟通协作:避免犯低级错误,开发前沟通清楚所有细节
    学会学习:高效学习方式(使用vscode-snippet有感)
    关于学习,避免没必要的熬夜的思考
    pc端布局的一点思考
    学习掌握一个新东西
    要想有价值,首先要乐于去解决每一个问题
    problem: 记一次聊天框的表情包弹框不显示的找问题过程
    abp-159,js最理想的继承——寄生组合式继承
  • 原文地址:https://www.cnblogs.com/jiangyu0331/p/11791241.html
Copyright © 2011-2022 走看看