转:https://blog.csdn.net/yueqian_scut/article/details/49968897android
笔者将从芯片IC的系统设计的角度去诠释如何掌握体系编程和SOC编程。笔者有超过10年的嵌入式研发经验,做为架构师屡次主导过基于ARM/MIPS/51核的多媒体SOC研发并成功量产案例,在高端处理器体系编程和嵌入式Linux方面有丰富的教学经验,但愿本系列文章能给嵌入式学习者和从业者有较深入的指引。编程
1、体系编程的边界和范畴缓存
嵌入式开发人员每每从最简单的51单片机编程开始,而后慢慢会接触到PIC、AVR、STM32等系列或者型号控制器,还会可能转向三星S5PV2十、Exynos4412等高端处理器编程。架构
开发人员通常的开发过程都是理解完该型号控制器或者处理器对应的指令集和datasheet,而后经过简单的例程开始编程,而最广泛的模块是GPIO、中断和定时器timer。在接触到多种类型的处理器编程以后,咱们可能会有概括式的疑问:性能
在include一个表明该型号IC的register map的头文件后,某些系列芯片的控制编程多是彻底同样的,而不一样系列芯片的控制编程也是相似,惟一的不一样可能在于寄存器命名的不一样。这是为何?学习
要回答这些问题,咱们必需要弄懂体系编程的范畴,明确体系编程的边界。要深入地理解体系编程,咱们须要从芯片的系统设计的角度去理解芯片的研发构成,能够参考笔者以前撰写过的《集成电路设计和分工》。测试
其中有一点很是重要,就是咱们要理解CPU核心和SOC的关系。这个世界上有能力研发SOC(System on chip片上系统)的公司不少不少,大到大名鼎鼎的苹果和三星公司,小到深圳那些籍籍无名但又很赚钱的芯片设计公司都是属于这个行列。而CPU核呢,放眼世界,能设计CPU知识产权核的就那么几家,如Intel的X86,ARM公司的ARM核,MIPS公司的MIPS核,51内核也算一个。这里要说明一点,中国没有,国家虽然重点扶持集成电路,但高层也知道这个砸重金也没用,实实在在的先把集成电路封装、工艺等技术发展起来再说。如今的android智能机都是基于ARM核的,想知道ARM之父是谁吗?前不久大师steve furber在广东工业大学作了讲座:操作系统
SOC都是根据市场需求和功能定位,在某个类型的CPU核基础上集成各类通用的外围模块控制器,如前面说的GPIO、INT和TIMER,和一些专用的模块控制器,如TI公司的蓝牙单芯片CC2541集成的蓝牙基带和射频控制器。SOC和CPU核的关系以下图:.net
体系编程明显是针对体系结构的编程,而体系的载体就是CPU。所以,89C5一、CC2541等都是51体系编程,而PIC3二、ATJ213X都是基于MIPS体系编程,而S5PV210和S3C2440都是ARM体系编程。对同一家CPU核设计公司,它没有理由将本身的CPU核设计成风格迥异,同一家公司不一样的CPU处理器系列应该遵循同一个体系结构。那么,体系结构的范畴是什么?是上图中红色的部分,其包括CPU核的设计和总线的时序和控制标准。而CPU核又细分CU(控制单元)和PU(运算单元),CU再分取指、译码、访问寄存器、回写存储单元等流水线操做,高级CPU通常还会集成协处理。所以体系架构编程通常包括如下内容:设计
1)指令集(寻址、运算)、汇编伪指令
2)流水线、指令预取和跳转规则。在流水线的工做模式下,指令预取当前执行指令的下面N条指令,所以PC和执行地址并不一致,所以假如发生中断、异常等状况下的返回地址要如何肯定。
3)协处理(MMU虚拟内存、cache缓存)
4)寄存器使用和参数传递规范(ABI)。其要解决寄存器级如何实现C语言的参数传递。请参考笔者以前的博文《C/汇编混合编程接口--MIPS ABI》
5)异常中断处理(硬件中断、通常异常、指令陷入中断等),上图中的INT管理全部的硬件中断,如串口、定时器、外部等中断,并将全部的中断引脚进行或以后送入CPU的中断信号。所以,对于CPU来讲,当发生中断时,它并不知道是哪一个模块发生了中断,只有INT模块才知道。
6)调试规范
7)总线规范。对于编程人员来讲,并不须要太关心总线规范。但它是SOC芯片设计的重要规范。它规定了总线的时序和仲裁的规范以及存储工做模式(冯诺依曼仍是哈佛结构)。
对于一个CPU核设计公司来讲,它会给SOC芯片设计公司提供两样东西,一是体系设计相关规范,如ARMV7指令集,描述了每一条指令执行的伪代码过程(这个伪代码针对的是硬件语言,如HDL);另外一样东西是特定系列CPU的设计规范,以及在该规范下实现的CPU IP核(知识产权核),为RTL寄存器级电路。
那么,对于同一个体系下不一样的系列,他们的差别在哪里?
例如,ARM公司如今的发展方向是Cortex A系列主要面向高端消费类电子,如手机平板,Cortex R主要面向军工、航空等实时要求高的场合,Cortex M系列则是抢占低端控制器市场,如STM32,STM8等。三者的体系都是ARM体系结构,但三者的工艺、功耗、性能并不同,并且,CPU核集成的东西是不同的,例如M系列并无集成cache,至关A系列,M系列的MMU也是一个简化版。
体系编程是嵌入式架构师和操做系统开发人员须要精通的,对于通常的开发人员比较少接触到。以上的分析都是基于理论层面的分析。而SOC编程则是面向广大的普通开发者,将会从系统设计的角度指导你们如何进行SOC编程。
2、SOC编程的范畴和定义
SOC编程是针对片上集成模块进行寄存器控制编程。在开发实践中,咱们每每把SOC编程和体系编程统称为体系编程了。不要紧,只要咱们理解清楚他们之间的关系就能够了。
那么SOC编程的范畴是什么?
1) 通用控制模块,如CLOCK、GPIO、INT、TIMER、UART等。
2) 专用控制模块,如LCD、蓝牙、编解码等。
有些模块不须要经过引脚链接外围设备就能够完成功能,如TIMER,大部分模块须要经过引脚链接外围设备来完成功能。所以芯片片上集成的是模块的控制部分,例如LCD控制器,该控制电路实现LCD驱动器(外围设备)所须要的数据传输时序、行信号、列信号和设置接口等。换一个角度说,若是没有LCD控制器,咱们也同样可以经过GPIO来模拟出LCD驱动器的时序,可是这样作,对于普通的开发者来讲太复杂,对CPU来讲也是一个沉重的负担。因此系统设计人员会针对LCD驱动器来实现专有的控制电路。
那么对于LCD控制器来讲,咱们SOC编程来作什么呢?至少,咱们须要给LCD控制器一个标识,让它启动或者关闭,如何给出这个信号呢?LCD控制器电路无非是一堆的时序电路和逻辑组合电路,启动和关闭能够用一个信号输入来表示,而该信号在CPU看来能够映射成一个寄存器的其中一个bit。所以,SOC编程便是针对寄存器编程。对于LCD控制编程,固然不仅一个寄存器这么简单,由于对于一个SOC厂商来讲,它但愿能兼容市面越多的LCD驱动器,兼容不一样的分辨率和图像深度,所以确定会有不一样的寄存器来进行设置。
从教学的角度来总结,体系编程和SOC编程分为五个层次:
1)体系指令集,如ARM指令集
2)特定系列的CPU规范,如基于ARM体系的CortexA8核
3)SOC级,在CPU核的bus总线基础上集成clock、timer、interrupt、GPIO等控制器,如三星的S5PV210和TI的OMAP3430都是基于Cortex A8核。
4)板级电路,如开发板、手机主板电路,其电路图将明确SOC的引脚和外围设备的链接关系。如GPIO A的第一个引脚接LED0,那要控制LED0就须要对GPIOA0进行控制编程。
5)外围设备规格,表示板级电路图上全部外围设备的规格,如具体LCD SPEC(尺寸、分辨率、延时参数等)。
笔者给SOC编程的过程定义是:基于1)和2)的指令集和CPU总线控制机制,根据具体外围设备5)的特性参数和4)具体的电路链接关系,对3)SOC对应控制模块的寄存器进行编程,达到控制、使用的目的。
3、SOC设计和编程
理解SOC系统设计可以极大地帮助编程,每款SOC的控制例程都是由SOC系统设计人员给出,由于他们也须要经过编程来对SOC芯片进行功能测试和验证。
另外,咱们须要明白的一个观点是,对于不一样的体系来讲,一样的模块的设计思路是基本一致的,或者能够说,从编程的角度来讲,片上集成的模块的设计控制过程无关于体系结构(二者有关更多的是在总线控制方面,而这个跟编程人员来讲关系不大)。所以基于ARM体系的LCD控制器和基于MIPS体系的LCD控制器,其设计思路都是一致的,不一样系统的GPIO控制也是一致的。尽管底层的寄存器电路可能不同,但对于上层编程人员看来,二者是一致的,不一样的可能只是寄存器名称。例如51单片机和arm处理器的GPIO都是输入寄存器、输出寄存器、方向寄存器、上下拉寄存器等等。
下面就以CLOCK和GPIO为例说明SOC编程,尽可能提取通用的设计和控制过程。
1.最小系统
最小系统除了CPU和RAM以后,还有一个重要的组件就是晶振。SOC或者CPU说到底都是一堆逻辑组合电路和时序电路,时序电路须要时钟才能正常工做,而晶振就是提供时钟的,其在上电后不断地产生时钟。
2. CLOCK
通常的低端单片机并无时钟控制模块,其直接利用晶振(如12M或者24M)工做,即CPU的工做频率就是12M或者24MHz。可是做为一个高级处理器来讲,其支持的主频达到1G或者更高。而市场上并无1G的晶振,所以SOC内部必然要实现调频,PLL锁相环倍频技术被普遍应用在处理器的CLOCK模块中,其是将晶振的频率进行倍频提高。CLOCK模块除了实现倍频的控制外,还须要考虑这样的需求:
1)SOC集成的模块不少,各类模块的工做频率并不尽相同,或者说是在不一样的层级,例如CPU和GPU、RAM的工做频率在G级,LCD的工做频率则在100M左右,视频编解码的工做频率百M级别,而像GPIO、串口这些模块的工做频率能够在10M级别。所以CLOCK还须要进行分频。因此CLOCK模块通常的处理方法是将模块进行分类,并进行一级分频。例如,S5PV210的CLOCK会将频率分为三个范围,M域供给CPU、中断异常等,D域供给LCD、JPEG、HDMI等,P域供给GPIO、UART等外围设备。每一个域都给定一个频率(能够经过控制器调节)。
2)对于在同一个域内的模块,其工做频率不尽相同,所以容许其内部进行二级分频。
所以,对于一个高级处理器集成的模块编程来讲,设置好其CLOCK源频率的相关寄存器是第一步。通常一级分频由操做系统开发人员设定,二级分频设置由各模块的开发人员负责。
3.引脚复用
芯片封装是芯片成本的重要组成部分,而封装涉及到引脚复用,并且芯片封装也涉及到最终产品的BOM成本,所以在系统设计时的引脚复用是一项很是关键的技术,能够说SOC集成电路公司的绝密技术。尽量高效地进行引脚复用很是关键。
对于编程人员说,咱们要作什么呢?那就是记得每一个引脚均可能是功能复用引脚,在使用这个引脚以前,必须设置该引脚的功能。引脚通常默认是GPIO功能,若是咱们要使用该引脚进行串口或者LCD等控制线功能,就必须对该引脚对应的功能寄存器进行设置。这是SOC编程的第二步。
CLOCK和引脚功能设置对全部模块都是适用的。
4.GPIO
这里咱们要谈通用的模块GPIO。对于GPIO编程来讲,咱们应该很是熟悉了,那就是它必定带有输入数据寄存器、输出数据寄存器、输入输出高阻态设置寄存器、上下拉设置寄存器。通常的过程是:
1)设置上下拉寄存器
2)设置引脚的方向
3)经过输入数据寄存器读入数据或者写数据到输出数据寄存器。
记得功能引脚设置也是须要的。有些高级SOC可能还会有驱动能力等级设置寄存器,控制引脚的驱动强度。
5.INT
请参考笔者的博文《软件和硬件都是对生活的高度抽象---论中断控制(ARM体系编程)》。
笔者以前的教学以基于cortex A8的S5PV210为例,有时间再整理该SOC的各个模块的编程方法。
---------------------
本文来自 吴跃前 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/yueqian_scut/article/details/49968897?utm_source=copy