day08 ARM体系结构与编程、流水线

来源:互联网 发布:交易宝行情软件 编辑:程序博客网 时间:2024/05/16 01:30
回顾:
1.I2C总线
    面试题:谈谈对I2C总线的理解
    面试题:谈谈对ARM裸板编程的理解
1.1.常见的几种硬件通信方式
1.2.I2C总线定义
    画图
1.3.看图提三个问题
    协议
1.4.I2C总线协议概念
1.5.举例子画图说明访问的过程
1.6.举例子画图说明配合
1.7.谈谈调试心得
1.8.以MMA8653三轴加速度传感器的访问为例
谈谈裸板编程的思路
1.用户需求分析
2.掌控硬件信息
    粗看
    位置
    细看
    原理图
    画图
    结论
    处理器的手册
    I2C控制器以及内部寄存器以指针的形式访问地址
    BIT位含义
    MMA8653的手册
    片内寄存器不能以指针的形式访问,必须严格按照时序图访问
    BIT位含义
3.按照裸板编程框架实现代码
谈谈裸板编程框架
顺便谈谈裸板程序的阅读
挑衅:"只要给我一套裸板程序,我就能够理顺程序的执行流程"                         
    1.首先找链接脚本,确定
    第一个运行的文件
    运行的入口函数
    运行的起始地址
    2.如果没有链接脚本,看Makeifle
    确定运行的第一个文件
    第一个文件里指定入口函数        
    确定运行的起始地址
    3.找到了入口函数,利用著名的源码阅读工具sourceinsight和ctags顺藤摸瓜,理顺代码的执行流程,
      在阅读时,要将源码和原理图和芯片手册结合起来
4.下位机测试            
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
2.ARM体系结构与编程
面试题:谈谈对ARM处理器的理解
2.1.首先交代常见的几种处理器架构
    X86架构:
    intel
    amd
    Powerpc架构:
    飞思卡尔
    DSP架构:
    TI(达芬奇系列:处理器包含DSP核和ARM核)
    FPGA架构:
    xilinx(ZYNQ系列:处理器包含FPGA核和ARM核)
    ARM架构:
    华为(海思系列),小米(澎湃),全志(A系列)
    MTK,英伟达
    高通,TI,Atmel,博通,三星,飞思卡尔等
    单片机系列:
    51单片机,MSP430,STM32(低端ARM处理器)              
    "嵌入式处理器":把X86去掉,剩余的都是嵌入式处理器              
 
    2.2.何为"ARM",谈谈ARM的定义
    ARM既可以认为是一款处理器架构,又可以认为是一家公司(ARM公司)。
    ARM公司不生产具体的处理器,而是涉及ARM
    做IP授权给各个生产处理器的厂家
    例如:S5P6818处理器的CPU核就是ARM公司设计  
    而其他控制器由三星公司添加      
    CPU核又称ARM核!
 
    2.3.谈谈ARM的版本划分
      明确:ARM的版本仅仅指ARM核的版本(ARM公司定义)
      ARM核大版本为:ARMV4/ARMV5/ARMV6/ARMV7/ARMV8
      每一个大版本下又分若干个小版本(ARM核)
      ARMV4:
            小版本                具体的处理器
              ARM720T                S3C4510(三星)
              ARM920T       S3C2410(三星)
       
      ARMV5:
              
              Xscale        PXA270(intel)
          ARM10                    S3C6410(三星)
      ARMV6:
              ARM11                    S3C6440(三星)
       
      ARMV7:
            ARM-CORTEX-A8 S5PV210(三星)
            ARM-CORTEX-A9
            ARM-CORTEX-A15
               ARM-CORTEX-M3/M0/M3 STM32(M3)主打低端
      ARMV8:正式支持64位
          ARM-CORTEX-A53 S5P6818(三星)
          ARM-CORTEX-A57  
    
   2.4.谈谈ARM7(ARMV4)三级指令流水线
   1.明确相关概念
     "指令":给CPU核下发的命令,CPU核根据命令完成一个功能
             例如:给CPU核发一个add指令,就是告诉CPU核做
             数据的加法运算
      
     "指令在哪里":指令就是存在于二进制文件中(shell.bin)
                   CPU核要想执行指令,首先将指令对应的
                   二进制文件加载到内存中,指令最终
                   存在于内存中,内存的访问以地址的执行访问
                   所以每一条指令也有对应的内存存储地址
                   所以CPU要想运行一条指令,首先从内存中
                   获取到指令
                   注意:32位系统:
                   CPU核工作在ARM状态下:一条指令的宽度为32位(4字节)
                   CPU核工作在THUMB状态:一条指令的宽度为16位(2字节)
    
    2.CPU核运行一条指令的三级流水线为(仅做了解):
      取指:CPU核中的取指器(硬件)从内存中读取
            要运行的指令
      解码:CPU核取完指令以后,这时候执行还不能
            直接去运行(CPU核还不能识别),需要
            解码器进行解码翻译
      执行: 翻译完成,CPU核最终执行指令
      总结:
        一条指令CPU核最终运行需要三步:
         取指F->解码D->执行E
      画出一个三级流水线的操作示意图!
       
    3.PC
      PC是个寄存器,位宽为32位,类似监工
      它是ARM核(CPU核)中的寄存器
      它永远只保存取指器要取的那条指令对应的内存存储地址
      例如:
      内存存储地址     指令
      0x48000000       add
      0x48000004       sub  
      0x48000008       and
      ...                             ...
      请问:当add指令被执行的时候,PC=?
      答:当add执行的时候,取指器取and指令,那么PC=0x480000008
     
    4.ARM7三级流水线特例之ldr指令
      ldr指令功能:CPU核利用此指令能够从外设中加载数据到CPU核中
      ldr指令流水线为五级:
          取指F->解码D->执行E->访存M->写回W
          说明:
          访存:CPU核找外设地址   
          写回:CPU核一旦找到了外设地址,将外设的数据
                加载到CPU核中
          注意:ARM7的ldr指令在M和W的时候,后面的两条指令
                的处理要延后两个周期                
      
     5.ARM7三级流水线特例之bl指令
       bl指令的功能:CPU核执行bl指令,能够跳转到bl指令指定的一个
                     内存地址去运行(取指->解码->执行)
       bl指令处理流水线需五级:
           取指F->解码D->执行E->保存返回地址L->正式跳转A
           说明:
           保存返回地址L:CPU核跳转到bl指令指定的地址运行之前
                         先把返回地址(bl指令的下一条指令)进行
                         保存处理
           正式跳转A:CPU核跑到bl执行指定的地址去运行
      
     6.ARM7三级流水线特例之中断
       中断定义:中断是计算机非常重要的一个机制
       问:计算机中为什么有中断呢?
       答:中断产生的根本原因就是CPU的数据处理
           速度远远快于外设的数据处理速度
           举例子说明中断:以CPU核读取UART接收缓冲区的数据为例
           当CPU核读取UART接收缓冲区数据时,当CPU核发现接收
           缓冲区没有数据,首先会考虑到采用轮训方式(死等)
           判断接收缓冲区有没有数据到来,但这种操作方式
           会让CPU核不能干其他事情,大大降低了CPU的利用率
           此时此刻,一定要想到轮训的死对头中断方式操作UART
           接收缓冲区:
           当CPU核读取UART接收缓冲区数据时,当CPU核发现接收
           缓冲区没有数据,CPU核此时去干别的事情(处理一个算法任务)
           一旦将来接收缓冲区有数据到来,UART控制器会给
           CPU发送一个中断电信号(嗨,数据到来了)
           CPU一旦接收到了UART控制器发送的中断电信号
           以后,CPU停止手头正在处理的事情(算法任务)
           转去读取UART接收缓冲区的数据,读完以后,CPU
           核继续去处理之前被打断的事情(算法任务)
           这种CPU至少干两件事,大大提高了CPU的利用率
        
       问:中断电信号的硬件处理是什么样呢?
       答:以BT通过UART给CPU核发送数据'A'为例
       1.当BT没有或者正在给CPU发送数据'A'时,
         此时CPU核去读取数据,此时数据没有准备就绪
         CPU核干其他的事情
       2.一旦UART控制器将数据接收完毕,UART控制器
         首先给中断控制器发送一个中断电信号
       3.中断控制器接收到这个中断电信号以后
         中断控制器硬件上做一番的判断
       4.经过一番判断,中断控制器最终给CPU核发送
         一个中断电信号,此中断电信号可以走FIQ
         信号线也可以走IRQ信号线
         如果是FIQ,此中断信号又称快速中断
         如果是IRQ,此中断信号又称普通中断
       5.CPU核一旦接收到FIQ或者IRQ中断信号
         CPU核停止手头的工作转去处理接收到的
         数据'A',处理完毕,CPU核继续处理原先被
         打断的事情
        
       CPU核接收到中断信号以后,开始处理中断,
       那么中断处理流水线需四级:
       切记:当CPU核正在执行某个执行时,如果CPU核
             接收到中断信号,CPU核处理中断一定是
             在当前执行执行完以后再去处理中断
       解码中断DI->执行中断EI->保存返回地址L->正式跳转A
       说明:
       保存返回地址L:中断产生之前,CPU在别的函数中做事
                     中断到来,CPU核要跑另一个函数中执行
                     将来执行完毕,还要返回到原先被打断的
                     函数中继续执行,所以要想返回先
                     保存返回地址
                              
2.5.ARM9(ARMV4)以后ARM核的五级流水线
   1.ARM9以后的所有ARM核指令流水线一律采用五级
     也就是将访存M和写回W给每一条指令都添加上
     例如:
         三级流水线:add:F->D->E
                                 ldr:F->D->E->M->W
         五级流水线:add:F->D->E->(M)->W
                     ldr:F->D->E->M->W
                     注意:add/sub/orr/eor/and等指令仅仅是在CPU核内部玩,
                           无需访问外设,所以无需访存M
                           但是访问M这个时间(位置)需要保留
     画出一个五级流水线的处理示意图!
 
2.6.ARM编程模型(必考)
    1.ARM核的7种工作模式
    SVC管理模式
    当系统复位或者软件执行swi指令,CPU核切换到此模式下
    FIQ快速中断模式
    外设给CPU核发送一个FIQ快速中断信号,CPU核切换到此模式下
    IRQ中断模式
    外设给CPU核发送一个IRQ普通中断信号,CPU核切换到此模式
    Abort中止模式
    当CPU核取指失败或者访存失败,CPU核进入此模式
    Undef未定义指令模式
    当CPU核执行一个不认识的指令(lisi),CPU核进入此模式
    System系统模式              
    User用户模式
    System和User一样,CPU核正常运行的情况下,CPU核
    要不在System模式要不在User模式,linux系统
    下,当CPU核处理一个进程时,对应的CPU核为User模式
 
    2.ARM核的两种工作状态
    ARM状态
    ARM指令
    位宽为32位
    Thumb状态      
    Thumb指令    
    位宽为16位
 
    3.ARM核的37个寄存器
    寄存器:暂存数据的硬件,类似内存
    寄存器分类:特殊功能寄存器和ARM寄存器
    特殊功能寄存器:各种硬件控制器内部的寄存器,也就是之前课程常说的"一大堆寄存器",CPU核访问这类寄             存器都是通过地址指针的形式访问
    ARM寄存器:仅仅存在于ARM核内部
 
    CPU核访问内部的ARM寄存器通过名字(不区分大小写)
    共37个ARM寄存器
     
    ARM核37个寄存器:
    31个通用寄存器:
    r0,r1,r2,...r15
    每一种工作模式下又有自己单独的寄存器
    r15又称pc:永远只保存取指器要取的那条指令的内存存储地址
    r14又称lr:永远只保存返回地址
    r13又称sp:永远只保存栈指针
 
    6个状态寄存器:
    1个cpsr和5个spsr
    cpsr又称当前程序状态寄存器,也就是保存
    当前程序运行的状态
    spsr又称备份程序状态寄存器,本质目的就是
    为了保存cpsr的值                            
    此时此刻务必画出37个寄存器的分布图!
 
    详解CPSR程序状态寄存器:
    BIT[4:0]:模式位Mode
    =10000,表示当前CPU核处于用户模式
    =10011,表示当前CPU核处于SVC管理模式
    ...
    BIT[5]:状态位T                                      
    =0:ARM核处于ARM状态
    =1:ARM核处于Thumb状态
 
    BIT[6]:FIQ配置位F
    =0:使能FIQ中断功能
    =1:禁止FIQ中断功能
 
    BIT[7]:IRQ配置位I
    =0:使能IRQ中断功能
    =1:禁止IRQ中断功能  
 
    BIT[28]:溢出标志位V
    =0:表示程序运行结果没有发生溢出
    =1:表示程序运算结果发生溢出                               
 
    BIT[29]:进位或者借位标志C
    =0:表示程序运算时没有发生进位或者借位
    =1:表示程序运算时发生过进位或者借位
 
    BIT[30]:零位Z
    =0:表示程序运算结果为非0
    =1:表示程序运算结果为0
 
    BIT[31]:负或者小于位N
    =0:表示程序运算结果不为负数或者不小于
    =1:表示程序运算结果为负数或者小于
        
       BIT[31:28]简称NZCV
       只要程序一运行,cpsr的值就会随时随刻改变!
        
       问:cpsr用于指示当前程序运算的状态,那么
           spsr字面上说是备份cpsr的值,什么时候用呢?
       答:举例子说明:
                现在有一个进程获取到CPU资源,此进程就可以
                投入运行,此时对应的CPU核的工作模式为User
                用户模式,此时由于CPU核执行进程对应的代码
                cpsr时刻进行改变,突然UART控制器给CPU核
                发送一个IRQ中断电信号,此时CPU核就会由
                User用户模式切换到IRQ普通中断模式,
                紧接着CPU核开始去处理IRQ中断,本质就是
                CPU核去执行这个IRQ中断对应的一个函数而已
                此函数也是一个程序,如果此程序运行,将来
                势必也会影响cpsr,但是将来中断处理完毕CPU核
                还要返回到原先被打断的进程继续运行,为了
                让原先的进程能够继续正确运行,所以CPU核
                在处理中断之前,先把当前进程的cpsr的值
                备份到IRQ模式下的spsr,将来中断返回
                只需从IRQ模式下的spsr恢复原先进程的cpsr
           
       4.ARM支持的数据类型
         Byte:1字节
         HalfWord:2字节
         Word:4字节
         DoubleWord:8字节
         笔试题:考察内存对齐问题
                 struct A {
                     char a;
                     int b;
                     short c;
                 };
                 求:sizeof(struct A) =答案参见背面.
        
       5.ARM支持大端和小端模式,默认为小端
         X86是小端
         Powerpc是大端
         笔试题:编写程序,确定当前系统使用的是大端还是小端?
                   
       6.ARM汇编语法格式:
         1.ARM汇编源文件以.s(.S)结尾
           参考代码:
           .text @代码段的起始
           .code 32 @使用ARM指令
           .global start @声明一个全局标签start
           start: @全局标签的内容如下
                   mov r0, #10 @r0=10
                   ldr r1, =3  @r1=3
                   add r0, r0, r1@r0=r0+r1
                   b .  @while(1);
           .end @代码段的结束
        问:何为"标签"?
        答:标签类似C语言的函数名和变量名
            到底是函数还是变量,关键看标签
            里对应的内容:
            如果标签里的内容是一堆代码,此标签就是函数名
        如果标签里的内容是数值,此标签就是变量
 
        7.切记:影响CPSR的NZCV位的两种情形:
        1.指令后面加s,运算结果影响CPSR的NZCV
        add r0, r0, r1 @r0=1,r1=-1
        @r0保存运算结果,不影响CPSR的NZCV
        adds r0, r0, r1 @r0=1,r1=-1    @CPSR的Z=1
        
        2.cmp比较指令后面不加s,运算结果同样影响cpsr
        cmp比较指令本质做减法运算
        cmp r0, r1 @本质:运算结果=r0-r1                        
        例子:
        cmp      r0, #4
        cmpne    r0, #10
        moveq    r1, #0
        
        假设r0=4,CPU核执行三条指令的细节:
        1.比较r0和4,本质做:运算结果=r0-4=4-4=0
        运算结果为0,影响CPSR的Z,Z=1
        2.当CPU核执行cmpne时,首先判断CPSR的Z位
        是否为0,现在Z=1,条件不成立,所以cmp不执行
        3.执行CPU核执行moveq时,首先判断CPSR的Z位
        是否位1,现在Z=1,条件成立,所以执行mov
        将0赋值给r1
 
        假设r0=10,CPU核执行三条指令的细节:
        1.比较r0和10,本质做:运算结果=r0-4=10-4=0
        运算结果为6,影响CPSR的Z,Z=0
        2.当CPU核执行cmpne时,首先判断CPSR的Z位
        是否为0,现在Z=0,条件成立,所以cmp执行
        3.比较r0和10,本质做:运算结果=r0-10=10-10=0
        运算结果为0,影响CPSR的Z位,Z=1
        3.执行CPU核执行moveq时,首先判断CPSR的Z位
        是否位1,现在Z=1,条件成立,所以执行mov
        将0赋值给r1
 
        假设r0=250,CPU核执行三条指令的细节:
        1.比较r0和4,本质做:运算结果=r0-4=250-4=246
        运算结果为246,影响CPSR的Z,Z=0
        2.当CPU核执行cmpne时,首先判断CPSR的Z位
        是否为0,现在Z=0,条件成立,所以cmp执行
        3.比较r0和10,本质做:运算结果=r0-10=250-10=240
        运算结果为240,影响CPSR的Z位,Z=0
        3.执行CPU核执行moveq时,首先判断CPSR的Z位
        是否位1,现在Z=0,条件不成立,所以不执行mov
 
        注意:记住常用的四个条件助记符:EQ/NE/CS/CC