前言
从单片机转到ARM,主要需要学习ARM的架构,ARM相比单片机多了一些外设和总线。在仅仅是裸奔的情况下,如果熟悉了ARM架构,那么我认为使用任何ARM架构的芯片和用单片机将没有区别。ARM架构之所以更复杂,当然是为了跑更快以及更好地支持片上系统,所以在某种程度上来说对片上系统不是很了解的话那对于ARM架构的理解也不会那么深。
ARM的历史版本
ARM7TDMI是基于ARMv4T架构的。ARMv5TE架构则是伴随着ARM9E处理器家族亮相的。ARM11是基于ARMv6架构基于ARMv6架构的处理器包括ARM1136J(F)-S,ARM1156T2(F)-S,以及ARM1176JZ(F)-S。最近的几年,基于从ARMv6开始的新设计理念,ARM进一步扩展了它的CPU设计,成果就是ARMv7架构的闪亮登场。在这个版本中,内核架构首次从单一款式变成3种款式。就拿ARM7TDMI来说,T代表Thumb指令集,D是说支持JTAG调试(Debugging),M意指快速乘法器,I则对应一个嵌入式ICE模块。后来,这4项基本功能成了任何新产品的标配,于是就不再使用这4个后缀——相当于默许了。
通用寄存器
R13通常被用作栈指针,进入异常模式时,可以将需要使用的寄存器保存在R13所指的栈中;当退出异常吹程序时,将保存在R13所指的栈中的寄存器值弹出。R14又被称为连接寄存器(LinkRegister,LR),即PC的返回值。R15又被记作PC。ARM指令是字对齐的,PC的值的第0位和第1位总为0。也就是说是32位对齐。
就Cortex-M3来说,拥有R0-R15的寄存器组。其中R13作为堆栈指针SP。SP有两个,分别为R13(MSP)和R13(PSP)即主堆栈指针(MSP)和进程堆栈指针(PSP),但在同一时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。这些寄存器都是32位的。
ARM的各个模式ARM有以下7种模式:
用户模式(User,usr)正常程序执行的模式快速中断模式(FIQ,fiq)用于高速数据传输和通道处理外部中断模式(IRQ,irq)用于通常的中断处理特权模式(Supervisor,svc)供操作系统使用的一种保护模式数据访问中止模式(Abort,abt)用于虚拟存储及存储保护未定义指令中止模式(Undefined,und)用于支持通过软件方针硬件的协处理器系统模式(System,sys)用于运行特权级的操作系统任务其中除用户模式之外都称之为特权模式(privilegedmodes),而在privilegedmodes中除了系统模式其它都称为异常模式,即exceptionmode。起初关于异常这个词我的理解有些偏差,我认为异常模式就是这个系统出错了,而实际上是。exceptionmode的意思是例外,意思是“这模式什么时候会发生不说……”,比如说来了个外部中断也会进入异常模式,但是此时系统是运行完好的。其中SVC用于在系统刚启动的启动文件BOOT程序中,跳转到kernel之前必须为SVC,SVC具有最高权限,可以对任何寄存器进行操作。在裸机程序中我们有时候会一直处于SVC模式下。关于什么时候会进入用户模式或者系统模式,以下是我的猜测,比如进入linuxkernel之后会设置成sys模式,比如任务调度等等都会在sys模式中,而执行用户编写的应用程序时,系统是处于usr模式中。以上猜测需要在linux中找出证据验证。其中FIQ,IRQ为中断模式,有中断发生时会进入FIQ模式或者IRQ模式,至于到底是进入哪个模式是由开发者设定的。理论上FIQ模式的响应速度比IRQ模式要快。其中abt模式通常发生于在访问地址没有对齐时的情况,此时会跳转到abt所属的中断向量地址中去。und模式应该是取到指令之后发现指令不能用,,此时会跳转到abt所属的中断向量地址中去。以上两种模式应该是开发过程中出现BUG才会进入的,也是一种调试手段,在版本发行之前应该消除这些错误(我猜==)。
启动文件
这一部分只要了解一下协处理器CP15的相关作用以及ARM或者THUMB汇编再看一下网上的例程以及解释应该不难理解。在启动文件中我们可以做任何事情,但是通常我们可以做这些:改变程序大小端排序,关闭看门狗,屏蔽中断,设置各个时钟,设置从SLEEP或者IDLE启动时的程序,初始化SDRAM,设置各模式指向的堆栈,设置好中断向量表,判断是从NOR还是NANDFLASH启动,将文件拷到SDRAM中,运行Main。以上也说明了为什么需要一个汇编写的启动文件,设置各个模式下的SP指针以及初始化中断向量的跳转(ARM的中断较多设置也较灵活)也只有汇编干比较合适了。甚至在SOC(片上系统)中每个任务都有自己的堆栈,所以改变堆栈指针的那一部分程序也是放在汇编里做的。总之了解启动文件是一个非常好的切入点。
MMU相关地址
基本概念关于MMU,因为多种存储设备的物理地址不同以及不连贯性,将其地址安放在合理的连续虚拟地址上是很必要的,所以MMU出现了。MMU即将不同的地址放在合适的虚拟地址中,以便调度。比如要跑LINUX必须要有MMU的支持才行。ARM920T中有三种类型的地址:虚拟地址(VA),变换后的虚拟地址(MVA),物理地址(PA)。以下是一个当一个指令被请求时地址所做操作的例子:1、指令VA(IVA)被ARM920T发出2、它被ProcID(当前进程所在的进程空间块的编号)转换成指令MVA(IMVA),指令CACHE(ICACHE)和MMU看到的就是IMVA。3、如果在IMMU上的保护模块确认IMVA不会被中断,并且IMVA标签也在ICACHE中,指令数据会读出并返回到ARM920T内核中。4、如果IMVAtag并不在ICACHE中,那么IMMU会产生出一个指令PA(IPA)。地址会给AMBA总线接口以获取外部数据。那么VA是如何被PID转换为MVA的呢?这有关于CP15中的13,FCSEPIDregisterR13是fastcontextswitchextension(FCSE快速上下文切换扩展)processidentifier(PID进程标识符)寄存器,此寄存器复位时为0。读R13会得到FCSEPID的值,写R13会更新FCSEPID的值到[31:25]中,位[24:0]应该是零。如何使用FCSEPID:920T内核发出的地址都是0-32MB的范围,4GB的逆序空间被分成了1238个进程空间块,每个进程空间块大小为32MB。每个进程空间块中可以包含一个进程。系统128个进程空间块的编号0-127,编号为I的进程空间块中的进程实际使用的虚拟地址空间为(I*0x02000000)到(I*0x02000000 0x01FFFFFF)。所以VA通常高7位都为0时MVA=VA|(PID25)当VA高7位不为0时MVA=VA,这种VA是本进程用于访问别的进程中的数据和指令的虚拟地址,注意这时被访问的进程标识符不能为0。注意:当FCSE_PID为0时,即当前复位,则当前920T和CACHES及MMU之间是平面映射的关系(很巧妙:))。TLB是什么?TLB即translatelook-asidebuffer,快表就是存储几个常用的页表,以提高系统运行的速度。在更新页表之前要使其无效,其操作的寄存器为R8,R8为只写寄存器,如果读它则会造成不可估计的后果。AP赋值表:而DOMAIN的赋值则是在C3中的,32bit共有16个域,每个域分两个bit,这两个bit控制当前域的权限。而以上四个bit是为了选择0-15个域的其中一个。关于C、B赋值:
以上有关于两种写缓存,写通以及写回。写回法是指CPU在执行写操作时,被写的数据只写入cache,不写入主存,仅当需要替换时,才把已经修改的cache块写回到主存中。写通法是指CPU在执行写操作时,必须把数据同时写入cache和主存。时钟以及总线概念 FCLK,HCLK,andPCLKFCLKisusedbyARM920T.HCLKisusedforAHBbus,whichisusedbytheARM920T,thememorycontroller,theinterruptcontroller,theLCDcontroller,theDMAandUSBhostblock.PCLKisusedforAPBbus,whichisusedbytheperipheralssuchasWDT,IIS,I2C,PWMtimer,MMCinterface,ADC,UART,GPIO,RTCandSPI.WhatisAHB/APB?InternalAdvancedMicrocontrollerBusArchitecture(AMBA)是一种总线标准,以下两项都符合此标准。AHB(AdvancedHighperformanceBus),主要用于系统高性能、高时速速率模块间通信。APB(AdvancedPeripheralBus),主要用于慢速片上外设与ARM核的通讯。AHB私有外设总线,只用于CM3内部的AHB外设,它们是:NVIC,FPB,DWT和ITM。APB私有外设总线,既用于CM3内部的APB设备,也用于外部设备(这里的“外部”是对内核而言)。CM3允许器件制造商再添加一些片上APB外设到APB私有总线上,它们通过APB接口来访问。四种耗电模式:NORMAL,SLOW,IDLE,SLEEP先配置主PLLMPLL给CPU用。在上电复位的时候PLL是不稳定的,所以在PLLCON在被软件配置之前Fin直接是跳过MPll给FCLK,所以不配置PLLCON也是可以正常工作。即使工作在正常状态下,也可以对MPLLCON进行配置,配置之后等待PLLLock-time过后内部各模块的CLK才可以被正常供应。DMA阅读芯片手册即可。