17年ARM笔记

1.  说多了也没什么用,简单来说,arm是单片机的一种,51也是,但arm的ROM和RAM远大于51,而且IO口功能和处理速度也是两个级别的,arm能上很多操作系统,51只能勉强上极其简单的 实时操作系统(RTOS) ,所以arm常用来开发手机等多媒体产品,51只能完成有限的 实时控制 功能,形象一点说,51和arm的等级差别就像手机和个人电脑的等级差别。

2.DMA总线:直接内存总线,IO直接 跳过 CPU和内存联系,效率高。

3.寄存器:用于在指令执行过程中存放操作数和中间数的容器。

4.ARM处理器的八种寻址方式
前言:1.什么是寻址? 数据都存在存储器中,寻址简单地说就是找到存储数据或指令的地址。存储器有很多存储单元,用于存储数据。或者说,寻址就是读取数据所在储存装置中对应地址编号中存储的内容。以存储单位寻址分为位,字,节,字,双字寻址。以功能寻址分为直接寻址,间接寻址,寄存器寻址。寻址就是为运算和执行命令。
        2.什么是寻址方式? 通常是指某一个CPU指令系统中规定的寻找操作数所在地址的方式,或者说通过什么的方式找到操作数。寻址方式的方便与快捷是衡量CPU性能的一个重要方面. 
1.立即数寻址:
        操作数在指令中, 如: ADD R0,R0,#10   ---->R0 = R0 + 10
        特点:快,单周期;但受合法立即数的限制;
2.寄存器寻址:
        利用寄存器中的值作为操作数, 如:ADD R0,R1,R2   ---->R0 = R 1 + R 2
        特点:也是单周期
3.寄存器移位寻址:
        寄存器中的值移位后得到操作数,用到 桶形移位器
            介绍一下桶形移位器:
                            LSL:(逻辑左移),相当于无符号数x2;
                            ASR: (算术右移),相当于带符号的数除2;最高位由31来补充;
                            LSR: (逻辑右移),相当于无符号数除2;
                            ROR:(循环右移),相当于位轮换;
                              RRX:(带扩展的循环右移),高位由C位来补充
              如:ADD  R0,R1,R2,LSL #2    -------->R0 = R1 + R2<<2;
4.寄存器间接寻址:
        寄存器中的值作为操作数的地址,操作数本身放在存储器中;
        如:LDR   R0,【R1】   ---->R0 = 【R1】,取出R1存的地址中的值,赋给R0;
5.基址变址寻址:
        基址寄存器的内容与指令中的偏移量相加,得到有效操作数的地址,然后访问该地址空间;
        分三种:
          1)、前索引:
                如:LDR  R0,【R1,#4】  --->R1存的地址+4,访问新地址里面的值,放到R0;
        2)、自动索引:
                如:LDR  R0, 【R1,#4】!  --->在前索引的基础上,新地址回写进R1;
                              注:!表示回写地址
          3)、后索引:
                如:LDR  R0  【R1】,#4  --->R1存的地址的内容写进R0,R1存的地址+4再写进R1;
6.多寄存器寻址:
          一条指令完成多个寄存器的传送,最多16个寄存器;
        如:STMxx  R0!,{R1-R5}
         注:xx是IDAB的任意组合:I-增;D-减;A-后;B-先;
          执行这类指令要考虑如下几个问题:
                1)、基址寄存器指向原始地址有没有放一个有效值?
                2)、寄存器列表哪个寄存器被最先传送?
                3)、存储器地址增长方向?
                4)、指令执行完成后,基址寄存器有没有指向一个有效值?
        如:STMia  R0!,{R1-R5} 的答案分别是:有;R1;低-高;没有。
        为什么要考虑这么多,因为涉及到数据还原的问题;
                如:STMib   r0!,[r1-r5]
                    LDMda   r0! , [r1-r5]             ------还原
7.相对寻址:
          pc当前值位基址,指令中值为偏移量,相加作为操作数的地址;
        如  B/BL    不过有范围限制 pc+-32Mbytes
8.堆栈寻址:
          先进先出的原则;
            如:STMxx  SP! (r0 - r12)   ---  xx是FEAD的任意组合,不过规定只用fd;
             4中堆栈方式:F-满;E-空;A-后;B-先;
            如:入栈:STMfd  SP!,(r0-r12)
                出栈:LDMfd  SP! ,(r0-r12)

1. 在异常发生后, ARM 内核会自动做以下工作:

    保存执行状态:将CPSR复制到发生的异常模式下SPSR中;

    模式切换:将CPSR模式位强制设置为与异常类型相对应的值,同时处理器进入到ARM执行模式,禁止所有IRQ中断,当进入FIQ快速中断模式时禁止FIQ中断;

    保存返回地址:将下一条指令的地址(被打断程序)保存在LR(异常模式下LR_excep)中。

    跳入异常向量表:强制设置PC的值为相应异常向量地址,跳转到异常处理程序中。

 

1)保存执行状态

        当前程序的执行状态是保存在CPSR里面的,异常发生时,要保存当前的CPSR里的执行状态到异常模式里的SPSR里,将来异常返回时,恢复回CPSR,恢复执行状态。

2)模式切换

        硬件自动根据当前的异常类型,将异常码写入CPSR里的M[4:0]模式位,这样CPU就进入了对应异常模式下。不管是在ARM状态下还是在THUMB状态下发生异常,都会自动切换到ARM状态下进行异常的处理,这是由硬件自动完成的,将CPSR[5] 设置为 0。同时,CPU会关闭中断IRQ(设置CPSR 寄存器I位),防止中断进入,如果当前是快速中断FIQ异常,关闭快速中断(设置CPSR寄存器F位)。

3)保存返回地址

        当前程序被异常打断,切换到异常处理程序里,异常处理完之后,返回当前被打断模式继续执行,因此必须要保存当前执行指令的下一条指令的地址到LR_excep(异常模式下LR,并不存在LR_excep寄存器,为方便读者理解加上_excep,以下道理相同),由于异常模式不同以及ARM内核采用流水线技术,异常处理程序里要根据异常模式计算返回地址。

4)跳入异常向量表

     该操作是CPU硬件自动完成的,当异常发生时,CPU强制将PC的值修改为一个固定内存地址,这个固定地址叫做异常向量


2.看门狗定时器

    相信大家都看过中国移动前些时间做的一个广告,从城市到山村,到青藏高原,在哪儿都有中国移动的网络,到哪儿都能打电话,由此可以联想到中国移动在全国有无数个信号基站,很多基站建设在环境比较恶劣的地方,我们来思考一个问题?假如,有一天某个基站出了问题不能正常工作了,毫无疑问,移动的工作人员会带各种检测设备去进行修理,如果是出现非硬件故障(如用户电话服务突然巨增,造成繁忙死机或电磁干扰造成CPU运行出错等),导致基站服务器出现异常死机,工作人员只需要进行一个操作,重启一下即可。如果该基站安装在青藏高原上,这样一次上去,成本是很大的。退一步讲,这种情况虽然成本很高,但是还是可以修复的,如果这种情况出现在月球探测器身上,问题就更严重了。因此针对这种特殊情况的设备,我们期待有一种设备能够在机器出现非正常情况下进行自动重启来恢复工作状态,使用看门狗定时器就可以完美解决这个问题了。

看门狗WatchDog的名字形象的描述了它的工作原理,看门狗每隔一段时间(比如:3个小时)它就会饥饿,每次饥饿时都叫,如果不想让它叫,只要我们保证在3个小时内喂狗一次就行。因此我们要及时的对看门狗控制器执行喂狗操作。

    看门狗定时器内部有一个递减计数器,当该计数器递减为0的时候,就会自动重启控制器(如下图所示),如果我们写有这样的程序,该程序在定时器计数器递减为0之前,将其递减计数器重新设置一下(喂狗),那么就不会产生重启操作。假如机器设备出现异常情况下如死机,CPU执行出错,程序跑飞等情况,CPU就会陷入非正常的执行流程,就不会去执行重置计数器的程序,当计数器递减为0时,会产生复位控制器信号,机器就会重新启动,恢复正常执行流程。这样的设计原理就解决了很多环境恶劣的情况下,对服务器进行重启的任务。上面的重置倒计数的操作通常叫做“喂狗”。


3. 集成开发环境:
         集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器编译器调试器和图形用户界面工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。如微软的Visual Studio系列等。

1.ARM汇编循环亮灭LED2:
1
.text
2
.global _start
3
_start:
4
5
ldr r0,=0x11000C40             @GPX2CON
6
ldr r1,[r0]
7
bic r1,#0xF0000000
8
orr r1,#0x10000000
9
str r1,[r0]
10
11
loop:
12
13
ldr r0,=0x11000C44            @GPX2DAT
14
ldr r1,[r0]
15
orr r1,#0x80
16
str r1,[r0]
17
18
bl delay
19
20
ldr r0,=0x11000C44
21
ldr r1,[r0]
22
bic r1,#0x80
23
str r1,[r0]
24
25
bl delay
26
27
b loop                        @跳回去循环量灭
28
29
delay:                        @这下面都是延时函数
30
ldr r0,=0x10000000
31
mov r1,#0
32
start:
33
add r1,#1
34
cmp r1,r0
35
bne start
36
mov pc,lr                @如果相等跳到函数调用处(bl下一条指令处)
37
38
.end

2.      #define  GPX2CON (*(volatile unsigned int *)0x11000C40)
为什么不写成#define  GPX2CON (*(volatile unsigned int )0x11000C40)
因为我们先要将0x11000C40强转成 (volatile unsigned int *)的指针,这样编译器就会把0x11000C40当成地址了,不然按照下面的写法编译器不知道把0x11000C40当成一个int型还是一个地址不好说。

3.C语言实现LED2的循环量灭:
1
#define GPX2CON *((volatile unsigned int *)0x11000C40)
2
#define GPX2DATA *((volatile unsigned int *)0x11000C44)
3
4
#define GPX1CON *((volatile unsigned int *)0x11000C20)
5
#define GPX1DATA *((volatile unsigned int *)0x11000C24)
6
7
#define GPF3CON *((volatile unsigned int *)0x114001E0)
8
9
void delay()
10
{
11
int i,j;
12
for(i=0;i<1000;i++)
13
{
14
for(j=0;j<1000;j++)
15
{}
16
}
17
18
}
19
int main()
20
{
21
GPX2CON=((GPX2CON)&0x0FFFFFFF)|0x10000000;
22
GPX1CON=((GPX1CON)&0xFFFFFFF0)|0x1;
23
while(1)
24
{
25
GPX2DATA=(GPX2DATA)|0X80;
26
delay();
27
GPX2DATA =(GPX2DATA)&0XFFFFF7F;
28
delay();
29
30
GPX1DATA=GPX1DATA|0x01;
31
delay();
32
GPX1DATA=GPX1DATA&0xFFFFFFFE;
33
delay();
34
}
35
return 0;
36
}

I2C:同步(同步就需要一根线是时钟线),半双工,2根线。
SPI:同步,全双工,4根线。

4.IRQ和FIQ有什么区别
         简单的对比的话就是 FIQ IRQ 快,为什么快呢?
         1) ARM FIQ 模式提供了更多的 banked 寄存器, r8 r14 还有 SPSR ,而 IRQ 模式就没有那么多, R8,R9,R10,R11,R12 对应的 banked 的寄存器就没有,这就意味着ARM IRQ 模式下,中断处理程序自己要保存 R8 R12 这几个寄存器,然后退出中断处理时程序要恢复这几个寄存器,而 FIQ 模式由于这几个寄存器都有 banked 寄存器,模式切换时 CPU 自动保存这些值到 banked 寄存器,退出 FIQ 模式时自动恢复,所以这个过程 FIQ IRQ 快。
         2) FIQ IRQ 有更高优先级,如果 FIQ IRQ 同时产生,那么 FIQ 先处理。
         3) FIQ 的中断向量地址在 0x0000001C ,而 IRQ 的在 0x00000018 ( 也有的在 FFFF001C 以及 FFFF0018) ,写过完整汇编系统的都比较明白这点的差别, 18 只能放一条指令,为了不与 1C 处的 FIQ 冲突,这个地方只能跳转,而 FIQ 不一样, 1C 以后没有任何中断向量表了,这样可以直接在 1C 处放 FIQ 的中断处理程序,由于跳转的范围限制,至少少了一条跳转指令。






















































































 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值