已阅读5页,还剩48页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
从51到ARM的华丽转身在开始构思这篇文章的时候,我在考虑,是华丽的转身还是艰难的转身更合适一些,我觉得内涵是一样的,每次的华丽丽都伴随着一段苦逼的艰难岁月,为了庆祝三观的重新归位,还是用“华丽”这个词更喜庆一点。一、闲言ARM与511二、 翻天覆地大事变5三、 真理只有一个,没有本质的区别8四、 做一个合格的嵌入式工程师15五、 最重要的小事17六、 开发前的东风27七、 从0到运行30八、 ARM的心声-寄存器、工作模式、异常处理、汇编31九、 责任细分:ARM?2410?编译器?我?41十、 一些知识点44一、闲言ARM与51之前已经学过,ARM7内核的S3C44B0X,但由于那时51单片机都没玩熟练,参照物不明显,所以即使是成绩很好,但却不得其要领。个人认为在单片机炉火纯青的情况下,对嵌入式开发有了比较深入的理解,再去学习ARM才事半功倍。在期盼了好久之后,由于项目需要和课程需要的双重契机下,终于与ARM有了亲密的接触。我们平时说的51单片机泛指的是以英特尔8031为内核的微处理器。现在intel、ATMEL等厂家都在生产,就像三星、ST都能拿ARM的内核做微处理器道理一样,授权生产。大陆最火的一家51单片机厂家莫过于STC了,它是深圳的一家设计公司,感兴趣的去他的主页上看看,或者打开它做的DATASheet,简直是太坑爹了,山寨中的极品。ARM其实有很多种含义,可以看做是英国ARM公司的名称,也可以是他们公司设计的CPU的名称,也可以是以这种CPU为内核做出来的处理器的统称。大家都知道ARM公司不做硬件,它们卖的是IP核,卖的是设计,靠产权赚钱。所谓的卖设计,差不多类似于咱们做课程设计时用VHDL写了一个电子钟,然后被人买去做成了实物。ARM从底层搭起,做出一个通用CPU架构,工程的复杂度简直无法想象。做ARM处理器做的比较好的公司有三星、ATMEL、ST(意法半导体)、TI等等,他们用ARM核加上自己设计的外设控制器,生产出一款嵌入式处理器。韩国三星涉猎的最为广泛,而且市场覆盖面很大,ARM7有S3C44B0、ARM9有S3C2440、2410、2416、2450等,ARM11有S3C6410这一款,contexA8有S5PV210(这款内核也是iphone的处理器)ST专注于做contexM3内核的处理器,也就是STM32系列的,相当火的一款ARM处理器,ST为了推广它,真实煞费苦心,提供了覆盖所有功能的驱动函数库,使开发变得相当简单。之前我纠结过一些概念问题,很多人可能没有仔细思考过。就是CPU、微处理器、计算机、单片机、微机系统。你如果去查的话,概念是明确的:CPU是由ALU、译码逻辑、控制逻辑组成的中央处理单元,微机系统就是由CPU、存储器、输入输出接口组成的。这也是计算机的基本结构。单片机也属于这个范畴。那ARM就为难了,我们一般称2410这样的芯片叫做嵌入式微处理器,甚至明目张胆的叫做CPU,这让ARM内核情何以堪?再说了它明明是拿了ARM公司的CPU加上自己的外设控制器构成的。那管它叫单片机?也不完全合适,因为像2410这样的处理器,是没有存储器的,FLASH和SRAM都要在外边接,它不是一个完整的计算机系统。STM32就是完整的,但依然被人称为微处理器。其实也没必要纠结于这个问题,你把它看成一个大单片机、小PC来学习,至于叫什么,心中有数就行了。51与ARM之间不光是主频、内存等的不同,而是架构就不一样,8位的51和32位的ARM比起来,就像一个亚洲人、一个是欧洲人,一个是小瘦子,一个是大力士。但毕竟都是人,没有本质的区别。(字长即一次可处理的位数,跟地址长度、寻址空间的概念无关,这个一定要明确)。目前嵌入式系统的主流是以32位嵌入式微处理器为核心的硬件设计和基于实时操作系统(RTOS)的软件设计,ARM已经成为中国嵌入式设计应用的首选。嵌入式系统设计的核心是软件设计(占70%左右的工作量),单片机系统软硬件设计所占比例基本相同。随着配置的提高,嵌入式系统越来越PC化、软件化。而且整个嵌入式系统,包括CPU在内的芯片设计相当成熟了,重点在于模电接口设计。在学习ARM的时候幸得好导师一枚,无论是从课上还是项目上都给了我很大的影响,我非常能理解他的思想,讲课的思路,他做学问的态度。他讲课就是“授道”、完全朴素的唯物主义,大白话、声情并茂。虽然在面试的时候被他羞辱,在实验室没少被他骂,但是我还是相当敬佩他,也能跟他谈到一块去,良师益友,总之遇见他我很幸运,当然,能得到我这样评价的老师,就他一个。做51开发的时候,虽然对CPU于接口的互动、对寄存器编程等等都有比较深刻的认识,但也忽略了很多重要的知识,的底层汇编,比如它的初始化文件startup.s,顶多算是会用,不能算是懂,或者精。导师面试的时候说看我做了很多单片机的项目,要问几个问题,我心里很得意,随你怎么问。但是一开口我就傻眼了,他问:8051的寻址空间?Idata、xdata、sdata?.好囧的。做了几年的单片机开发,真的没关注过这些,真的不能算是懂51,顶多算是知道开发流程、多了点项目经验,会用C语言写写程序而已,甚至指针、链表什么的还稀里糊涂的。其实想想真是,只顾用C语言写程序,那区区的256字节的RAM不够用了怎么办?如何优化程序?你真的懂整个开发、运行的流程吗?从上电开始,内部发生了些什么事情?你的程序是怎么被执行到的?于是我吸取了教训,端正了自己的学习的态度,进了实验室之后,努力做项目,努力学习ARM,当然,也努力让自己学会在压力和指挥下伴着骂声学习。从51到ARM很多地方难以接受,系统复杂度提高了很多倍,电源、时钟、定时器、中断等结构都变得很复杂,而且还多了很多控制器,学习起来难度也比较大。但仔细研究的话,发现二者有那么多相似之处。殊途同归的道理,毕竟不跑操作系统的话,二者没有本质的区别。为了讨论与51对比以及ARM处理器的开发,不便屏蔽硬件的细节,所以仅限于裸机开发,涉及操作系统的地方,可忽略。关于嵌入式操作系统,后续会有讨论。在开始学习之前我整理了一下自己关于51都会些什么,以清清爽爽的姿态跨入ARM的大门。1、编程环境KEIL、下载工具ISP、常用的工具如串口助手、单片机精灵2、最小系统及常用外围接口(数码管等)的焊制3、熟练使用IO口、中断、定时、PWM、AD、串口。4、基本模块:红外模块(避障、循迹、光电管)、超声波模块、L298N电机驱动、DS1302、1602LCD、舵机、编码器(码盘)、热电阻、水位计、GSM、红外遥控、继电器(固态)、测速电机。5、项目:freescale智能车、生产实习遥控车、毕设淋浴器、定时器等6、其他技术:上位机控制、双机通信等。其实做这些东西,收获最大的不是学到了多少技术,而是对心态的历练,还有在设计的过程中得到的感悟。技术都是先知道和后知道的区别,但是经验的积累才最重要。2、 翻天覆地大事变1、 寄存器翻天了,32位。DATAsheet阅读的难度很大。传统的寄存器编程已经不再适用,就算是裸机开发也没办法把它当做单片机使用。开发重点由寄存器编程到外设功能理解、外设寄存器了解。裸机编程的风貌也已经大大改变,更多的时候是利用层层封装好的规范的驱动函数库编程,屏蔽了底层的细节。2、 外设爆棚了。IO/AD/UART/PWM/定时器等通用标准外设之外增加了IIC/IIS/SPI/USB/CAN/LCD/触摸屏/以太网等专用外设控制器,专为嵌入式系统设计。外设的接口一般只需要集成和改变一下形态,有时需要接上物理层电平转换芯片(串口、CAN)。这样程序猿对外设的编程操作,就变成了对片内外设控制器的寄存器编程。再也没有了要用单片机模拟时序的尴尬。3、 结构复杂度爆棚了:原来的电源系统、时钟系统、中断控制、定时器等等结构优化且复杂面向更宽广的应用。51单片机的最小系统中,直接用个5V的稳压芯片接上就行了,但ARM的电源系统中也有3.3V、1.8V等,各个部分需要的电压不同,特别是时钟系统变成了clock tree,不同总线的外设时钟也是不同的,还有锁相环倍频,定时器不光有定时、计数的功能,看STM32F2的技术文档,三种定时器加上systemtick、窗口看门狗、独立看门狗,定时器数量达到了10几个,而且有一堆乱七八糟的功能。总之结构相当复杂,你原先懂,现在未必懂,原先认为理所当然的,就坐等被狂虐吧。4、 这就导致我们对待嵌入式开发的态度应该发生改变,更应该以应用为目的去学习,就是边做项目边学习。毕竟ARM处理器提供的功能肯定是为了解决工控领域出现的问题,面向整个工控领域,初出茅庐的我们不可能完全搞明白,有时候也不必完全搞明白再动手,等你的项目经验多了,遇到的情况多了,许多难解的结自己也就化开了,就像STM32的定时器系统,我相信没几个人能真正搞明白,但是你如果只用定时、计数功能的话,还是相当简单的。5、 开发面貌改变了。硬:因为管脚的爆棚,最小系统基本上不能自己焊了。软1:因为硬件很灵活,很多都属于定制的系统,存储器什么的都自己接,所以如果不是买核心板的话,bootloader(或是startup.s)需要自己烧写,甚至是编写或是修改。软2:资源的爆棚和应用的复杂性也导致了前后台系统的崩溃,因为它牵一发而动全身,功能一多,把所有的任务都放进一个while(1)里,我是不放心,对程序的修改、维护什么的都是很大的问题。多任务、实时性、硬件资源管理、产品开发效率瓶颈的要求导致了操作系统的引入,消耗了CPU资源,却换来了开发效率,而且操作系统提供了大量的API函数,方便了编程开发。操作系统向上提供更强大的开发平台、更便捷和更美观的人机交互界面、方式;向下制定更合理的硬件管理办法、机制,让硬件更高效地被使用。软3:设备驱动程序在51的前后台系统中基本上跟应用程序是不分的,在ARM裸机开发中,由于寄存器编程和外设时序的复杂性,驱动函数逐渐与用户代码分离,有了操作系统之后,设备驱动程序甚至单独称为了一个软件层次。下面是设备驱动老师的一段话:操作系统引入之前,顺序执行的程式决定了驱动编程和应用程序同等地位的表现,两者混合在一起,驱动编程占了总代码量的二分之一甚至更多。微内核操作系统的引入和应用,使得设备驱动得以第一次封装,并和应用程序任务处于同等优先级的地位进行执行。任务式的驱动封装,使得驱动的移植性增强,任务调度程序的作用减小了MCU中驱动和应用程序代码之间的复杂调用逻辑带来的工作量,并将硬件的复杂驱动编程独立出来。软4:用户程序不再需要自己一步一步搭建,庞大的工程,一般移植成熟的程序。手敲大批的代码变得不可能也不必要,借鉴并修改程序是一种很重要的能力。6、 操作系统的引入,也导致了裸机开发的面貌的第二次改变,因为是在操作系统的平台上编写程序,在嵌入式操作系统中运行程序,所以学习操作系统是必然的,就像操作windows。学习它的API,学习它的运行原理、学习它的使用方法。7、 整个嵌入式系统软硬件体系和开发流程发生改变:硬件层次 核心板+外围板+外设(核心板:微控制器(CPU和外设控制器)、电源、时钟、复位、ROM、RAM、flash。外围板一般是引脚的集合、电平转换。外围设备。)硬件特点:通常由嵌入式处理器和嵌入式外围设备组成,高度集成,常采用SOC设计方法,对功耗、体积等有严格要求,定制性决定了它的可裁剪性,没有像计算机领域的垄断,解决方案不唯一。软件层次:用户程序-操作系统-驱动程序-再底层是bootloader.(底层为上层提供服务)。软件特点:采用交叉开发方式,系统软件层次分明,操作系统为用户程序提供标准API,提供图形接口和文件系统。用户调用系统服务,系统调用设备驱动从而操纵硬件。硬件从最小系统开始软件从bootloader开始开发软件:即集成开发环境:asemmbler&compiler&linker&debugger&loader(需系统引导代码)(下面说的是有操作系统的情况下,可忽略)开发过程:搭建开发环境-烧写bootloader-烧写内核-烧写根文件系统-烧写应用程序。访问外设过程:用户程序-访问(字符、块、网络)设备文件-调用设备驱动-设备。应用程序生成下载所需的软硬件开发环境:linux/vi/gcc/gbd/makefile+make/-ip tftp nfs(网口、串口、JTAG)。3、 真理只有一个,没有本质的区别上边说了从51到ARM之后发生巨大变化的地方,说到头也只是鸟枪换炮,还有开发流程的变化,没有本质性的区别,都是嵌入式微处理器,CPU与外设控制器的,时序、寄存器编程、交叉开发方式是都适用的概念,就算功能结构再复杂,裸机跑前后台系统道理也是一样的,先CPU初始化代码,再跳转到后台while(1),前台用中断处理异步事件。CPU与外设控制器即无论是51还是ARM都是通过CPU与外设控制器的互动实现功能的。CPU通过寄存器编程对外设控制器的工作模式进行设定,通过外设控制器产生时序与外设交互,CPU通过简单读写寄存器的方式与外设控制器互动,以获取外设信息或者像外设传递信息。外设(控制器)则通过查询或者中断的方式申请的服务。这一过程也可以描述为:CPU是“大脑”,那么外设控制器(IO接口)就是它的“手足”。大脑是控制中枢,手足是执行机构。CPU通过给外设控制寄存器赋值可以控制外设寄存器的工作方式,通过对数据寄存器的读写掌控全局信息,体现自己“老大”的地位。外设控制器负责向上申请CPU的处理数据的服务,这一过程一般是通过中断或者查询完成的,向外与外围设备(外设)进行交互,控制外设的运行达到实现控制的目的,同时也实现了CPU的价值。CPU什么都不会,就只会寻址、传送、计算,所以它要实现什么功能,一定是有若干级的控制器部件帮他做。在CPU可以通过寄存器编程控制、直接负责沟通(约定数据往返方式,如读写某个寄存器即可)的干将中可以分为两类,即两类外设控制器:一类是通信控制器接口即用来产生时序,面向陌生外设(ARM的串口、USB SPI IIC LCD CAN等,通用PC的PCI接口等),当然可以通信的基础上由外设实现更复杂的功能,即在物理层链路层通信的基础上实现应用层的功能。比如一个拥有IIC接口的芯片,可以将压力、温度、时间等数据通过IIC发给CPU,这一类一般需要与外设芯片通过特定指令控制,就是说CPU要对它说点特别的话,就是需要驱动程序了(驱动程序是个大的概念,即实现操作对象的功能规约)。第二类是内部功能接口(定时器、中断、AD、PWM、普通IO口),他们直接面向对外功能应用,也属于CPU可以直接控制的一部分。举例说明,PCI可以看做CPU面向PCI设备的一个总线,内部PCI控制器与CPU交互,CPU可以通过控制它产生时序与PCI设备进行通信。有了这个通信基础,我们就可以做一些事情了,比如把一个具有温度采集功能的AD模块做成一个PCI接口的AD接口卡,这样就可以实现CPU对温度的了然,然后去做一些运算、控制之类的事情。这个AD卡可以有自己的指令系统和通信规约,即收到什么做什么,发过去的数据那一部分是什么意思,CPU要想正确的通过PCI找到数据,就得了解AD接口卡,就是需要设备驱动程序做解析。比如现在有一个直接可以控制显示器的显卡,可以通过PCI接到CPU总线上,CPU想画个圆,就发一定的指令,给显卡,显卡里有GPU专门做这件事情,根据指令在屏幕上画个圆。将图画、视频编码传递给GPU,它就能正确的显示,不用CPU操心。所以这个显示功能的实现就通过了PCI控制器、GPU、显示器三级实现的。 时序的概念当然外设控制器与外设的交互就是“对话”,就像两个人一样,要想沟通就得说一样的“语言”,在通信中管它叫“通信协议”,而在我们嵌入式系统中叫做遵守一定的“时序”。相当于双方约定好了一定的沟通流程,做出双方的都能理解的动作,相当于一种机器之间的语言、机器通信协议。都是人规定的机器之间的沟通方式,没有什么神秘的,既然人家已经推广成了一种标准,我们就毫无保留的去遵守,就像汉语已经形成了,我们在生活中不说汉语就没办法工作生活,没办法传递信息,也就没办法体现个人价值。比如我们知道SPI、 IIC都是串行通信总线,也可以看做是一种通信协议,一种串行通信语言,通信双方都遵守这种协议规定的时序(什么时候开始?(帧起始)什么时候结束?(帧结束)何时应答?(ACK等)哪里是数据信息?(数据域)怎么知道数据错了?(校验域),时序的概念体现了计算机中一种博大精深的思想,那就是“编码”。就像摩斯码的产生,就是双方为了交流,而约定的一种都能识别的方式。在有外设控制器的情况下,相当于CPU有了一个得力干将。直接给干将下达命令,干将怎么做是他自己的事情。拿IIC控制器举例,这个干将的专业就是说“IIC语言”,服从CPU的领导,CPU告诉它你去跟另外一个IIC控制器说“XXXXX”,那么剩下就没有CPU什么事了,两个控制器直接用IIC语言交流。我们就不用关心时序的实现,功能的开发直接就是对控制寄存器进行编程,决定控制器的工作方式(),在工作的过程中想发送一个字节数据,可能直接就是一个写数据寄存器的指令就可以实现。想接收一个自己的数据,也就是读数据寄存器就可以了。在没有外设控制器的情况下,相当于CPU就是一个光杆司令。以前得力干将干的活就得它自己干。接着上一个例子,那么CPU像跟一个IIC控制器说话就得自己说这样的语言,这个学说话的过程就是模拟时序的过程,也就是编写驱动程序的过程。在51单片机中没有IIC这个接口,也没有SPI接口,那么想跟相应的设备进行通信,就必须得遵守通信协议上的规定,用IO口进行时序的模拟。中国人学英语就是这个道理,大脑产生逻辑思维,但是我们只有“汉语模块”没有“英语模块”,大脑产生授意后,就只能用说汉语的嘴去模仿英语的发音,这样就能和外国人交流了。寄存器编程上文提及,微机系统的实现就是靠CPU与控制器的配合、控制器和外设的配合来实现的。其中CPU对控制器进行控制的方法最主要的方法就是寄存器编程,通过查询DATASHEET可以看到片内的寄存器每一位的作用。可以想象这些位肯定对应着某些功能电路的“片选端”或者“功能选择端”,SOC的芯片架构决定了面向片上寄存器赋值方式的编程方法,通过片上外设接口,进一步可以实现时序描述方式的片外设备驱动编程。寄存器编程体现在51单片机和ARM内核单片机上是两种不同的形式,在51单片机中,因为是8位的,所以寄存器也都是8位的,外设的功能也相对简单,所以直接对寄存器编程。而ARM内核的微控制器一般为32位的,寄存器也是32位,这样直接对寄存器编程时十分复杂的,所以就产生了最底层的驱动函数,把要实现的功能对应的寄存器配置封装成函数,在主程序中直接调用,进行寄存器的间接编程。下面举例说明:下面是51单片机的串口初始化程序,查询DATASHEET之后,直接对相应的寄存器进行编程。void InitUART(void)/波特率2400 ,6T模式,在编程器设置TMOD |= 0x20; /定时器工作在定时模式 模式1 SCON |= 0x50; TH1 = 0xF3; TL1 = TH1; /初始化计数器初值 PCON = 0x80; EA = 1; /打开所有中断 ES = 1; /打开串口中断 TR1 = 1; /打开定时器TMOD SCON PCON等寄存器都是8位特殊功能寄存器,在该函数中直接对其进行赋值,修改功能只需要对照DATASHEET,工作不繁琐。下面是STM32微控制器(ARM CONTEX M3)的串口配置函数:void USART_Config(void) USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; STM_EVAL_COMInit(COM1, &USART_InitStructure); STM_EVAL_COMInit(COM2, &USART_InitStructure); Delay(); 这个配置函数中我们已经看不得到寄存器的影子了,已经进行了层层的封装,但是本质还是寄存器编程,这些底层驱动函数是芯片厂家出厂时就给提供的,因为如果对照着32位的寄存器去编程,那就太繁琐了。我们编程的时候也不用像开发51单片机那样把寄存器功能弄得一清二楚,只需要了解一下,然后会用驱动函数编程就行了。下面是设备驱动程序老师的一段话,感觉说的比较在理:MCU的编程为嵌入式开发提供了原型,早期的嵌入式开发就是MCU的编程。从广义上讲,“设备”是指计算机中除CPU外的所有器件,因此基于MCU的开发中,SOC的芯片架构决定了面向片上寄存器赋值方式的编程方法,通过片上外设接口,进一步可以实现时序描述方式的片外设备驱动编程。交叉开发方式同时嵌入式应用,都采用交叉开发的方法,即在一台通用计算机(宿主机)上进行软件的编辑编译,然后下载到嵌入式设备(目标机)中运行调试的开发方式。建立交叉开发环境是进行系统设计前必须要做的方法,在51开发的时候用的KEIL,下载采用的是ISP下载(通过串口)。在进行STM32开发的时候用的是KEIL MDK,用ST提供的FLASH loader下载,无论是STC的51单片机还是ST的M32都固化了下载引导代码,所以不需要专门的下载器。一般只有在仿真或者下载bootloader时采用JTAG。交叉开发环境一般由运行于宿主机上的交叉开发软件:(assembler&compiler&linker&debugger&loader)、宿主机到目标机的调试通道组成。需要交叉开发环境是因为目标机一般对体积、功耗等有严格限制,资源也面向应用,较为紧张,要求仅仅能流畅运行代码即可,而将用户开发软件(包括各种库、工具)放置在主机上,而且现在的集成开发环境提供了各种修改好的功能库,用起来也方便。这是由其组成决定的。Assembler将.c源代码汇编,compiler形成目标文件,linker根据链接描述文件将各个目标代码链接定位生成可执行代码。Debugger有些交叉开发工具提供了仿真调试通道。Loader可以将目标文件烧录进设备中(有时需要内部引导代码的配合)。我们在集成开发环境中,敲代码、编译、汇编、连接(在连接描述文件的作用下加上了startup.o)、下载到目标机,上电从地址0开始运行,先初始化,在跳转到main执行。在无限循环中中断处理异常。这样的过程,无论是51还是ARM都是适用的。4、 做一个合格的嵌入式工程师1、专业素养对嵌入式软硬件层次相当了解;对开发环境及其原理开发流程有一定的认识;职业病思维:用嵌入式系统的思维去分析生活中遇到的设备,如果能分析明白或者做出推测,将是一件很开心的事情。“编码”思想:其实整个计算机世界,都体现着一种“编码”思想,人如何与机器交互、器件之间如何交互、通信双方如何定义通信协议,这都体现着编码的思想。管理的思维:因为在复杂的计算机系统也是人设计得,各模块的工作协调无处不散发着管理的思想,把系统调用抽象为人事安排,将变得很有爱。要相信你要你想到的解决问题的方法(算法),肯定能编出来。要相信,真理肯定是存在的,你还没有到遇到未解之谜的程度,即只要是问题就能解决,遇到需要反复测试的时候,不能气馁,也许只是哪个知识点理解的有偏颇,离真理只有一步之遥。从历史看起、从总体看起:用历史的眼光和谦虚但不自卑的态度看待复杂的系统和知识,这样一切就都简单又好理解。认识指导实践,实践反作用认识。2、个人品质:不悲不喜:在嵌入式开发过程中,会有一个又一个问题出现,不要因为一个问题的解决和搁置而悲喜,更大的喜剧在前方,也许更大的悲剧也在酝酿。勇于钻研:对解决问题有强烈的向往,有征服的渴望。所以一些很恬淡的人往往不会成为IT行业的精英。并从中找到成就感、存在感乐在其中:俗话说兴趣是最好的老师,拿欣赏的眼光看待内核的管理思想、看待精妙的算法、看待精密的电路设计,你会发现一切都美好起来。要会学习:有强大的学习能力,要会查资料、会聊天、会推测。用“学道”的思维去学习一切知识,抓住本质,老子说,为学日益,为道日损,损之又损,以至于无为,无为而无不为。,最复杂的科学,也能用最朴素的话解释。用历史、发展的眼光、用总体、联系的眼光去学习。不做任何无用功。不但要用发展、联系的眼光去解决问题,还要用孤立的眼光解决问题。存在即合理,要回问为何,才逐步打通,得到一眼看到底的本领。耐得住寂寞还得有兴趣爱好。有时会比较枯燥和辛苦,除了对专业的兴趣之外,最好能有些调节生活的兴趣爱好,比如唱歌、画画、旅行、摄影、健身等等。3、如何提高?因为嵌入式系统设计所涉及的知识面相当广,微机原理知识、电路知识、接口知识、操作系统、甚至是控制理论、数学计算等等,所以单单学习知识点的话,会很枯燥而且提高很慢,一切以应用为中心,在做项目中成长,加深理解,边学变做,把解决问题当做学习的目标。找若干良师益友,他们能带给你好的影响,包括做项目和做人,在与他们的交流共事中你可以迅速提高。大量的阅读,开阔眼界,了解当前行业的发展状况,大量阅览一些典型系统的设计,所谓书到用时方很少是很有道理的。学一些跟专业相关的知识,如数据库、网站设计等,不但能在设计系统时打开思维,还可以给IT男换个口味,陶冶一下情操。5、 最重要的小事你有没有想过为什么我用C语言写的代码机器能识别?为什么我用JTAG可以直接下载程序,我用串口下载程序的话,为什么从串口接收到的数据就能放到FLASH里面呢?是谁在作用?发生中断的时候为什么就能跳转到我写的中断函数?CPU怎么知道我分配的堆栈在哪里?我的程序不是烧写到FLASH里了吗,什么时候,又是谁把它拿到SDRAM中去的?又是什么我一个工程文件按照什么方式排序生成一个可执行文件?一上电,处理器内部发生了什么事情?这些问题的解决就要弄清楚四个被大部分人所忽略的代码文件:bootloader/startup.s/连接描述文件scf/下载引导代码。下载引导代码我们下载程序分成两种情况,一种情况是用专用的下载器,可以直接将代码烧写到合适的区域,比如用JTAG,JTAG接口是现在CPU一般都能配置的接口,通过边界扫描灯方式,可以访问到处理器内部的每一个寄存器或模块,可以用于仿真,也可以用于下载。另一种情况是使用下载引导代码,简单说它也是内部运行的一段程序,可以将串口或网口接受的数据放到FLASH中去,要有专门的下载软件将编译好的代码通过串口发过去。很简单的道理,凭什么你向串口发东西就给你放在FLASH中去呢?比如STC51一个很重要的优势就是下载程序非常方便,它已经将引导代码固化在内部,上位机ISP下载软件,可直接将程序下载进去。STM32可以BOOT的电平,选择从FLASH启动还是从系统固化代码启动,从后者启动就是要下载程序了,上位机运行FLASH loader,可以将串口收到的代码送到FLASH中去(先放到RAM)。又是一个裸片下载bootloader,没有内部的引导代码,需要JTAG进行下载。有了bootloader以后就不用JTAG了,为什么呢?因为bootloader有下载引导功能,下载内核、根文件系统、用户程序什么的,它都可以搞定。连接描述文件这是细心的人才能发现的问题,它是集成在编译开发环境中的,即一般对用户是不可见的,如果你追根溯源的话,肯定能发现它的存在。一个工程中有那么多的源文件,有的是启动代码,有的是中断代码文件(51的直接用标号表示,放在主程序下面,STM32是一个专门的文件)、有的是MAIN.C,编译环境怎么知道它们是什么?分别编译成目标文件后怎么连接成一个可执行文件?可以说这些规则是编译环境规定的,或者也可以是你规定,编译器遵循编程规格,在连接时将startup.s放在第一位,然后是main函数.等等(比如在做51开发的时候,处理器硬件的机制是发生xx中断时跳转到0x08,那么startup向量表中规定0x08地址上一条指令B interrupt3,那么我主程序中编写中断程序时,程序名称就得是interrupt3)。大胆按照规则写代码就行,编译器懂你在干什么。Startup.s发生中断的时候为什么就能跳转到我写的中断函数?CPU怎么知道我分配的堆栈在哪里?我的程序不是烧写到FLASH里了吗,什么时候,又是谁把它拿到SDRAM中去的?这几个问题的解决就得需要startup.s了。细心的都会发现在做51开发的的时候建立工程选定CPU型号之后,会有一个提示:要不要把startup.s添加到工程中。我们一般点YES。这就是开发环境祝我们一臂之力,而且编译环境还提供了寄存器的地址封装,我们可以直接用,而且还有连接描述文件来帮助我们开发。总之我们写代码就行了,根本不用关心这些东西。那么这个startup.s是用来做什么的呢,它是在用户程序运行前给CPU一个必要的工作环境,什么叫必要呢?我们知道CPU在发生中断的时候会自动跳转到存储器空间开头的相应的地址,那么这个地址上有什么代码得用户自己写吧,这些地址上放的就是startup.s。Startup开头就是一个中断向量表(所谓的向量表也是一段代码,只是由于CPU的跳转,每次只会从其中的一行开始执行,所以像一张表一样),上电首先执行的就是startup.s。0地址上方的就是.s文件。我们知道堆栈在程序运行中相当重要,对保存断点(程序跳转、中断),存放变量的的地方,指针就是SP,程序运行的时候CPU的压栈出栈指令就是对SP进行操作,所以要想用户程序正确运行,肯定要对SP进行初始化。而且他们它的具体功能和程序分析如下:启动代码start.s(相当于bootloader的前端代码),开机就执行的代码,即0x0000处放置的代码。给CPU一个合适的工作环境。面向CPU内核和外围硬件,所以一般用汇编编写。1、在起始地址分配中断向量表即中断处理函数(CPU要求的),以为向量空间只有4字节,所以一般只是一个跳转指令,去别处执行。2、之后初始化存储器系统3、初始多个模式下的堆栈(模式切换时,硬件给SP置位)4、初始化有特殊要求的外围设备,如LED灯、看门狗5、初始化用户的执行环境(在FLASH中运行太慢了,把代码整体搬迁到RAM中)6、切换处理器的工作模式7、调用主程序(没见到有存储控制器的配置代码,也没见到有时钟初始化代码)下面分析,所给的2410的启动代码实现了以上的那些功能,实现得显然不全,或者不需要,或者在工程代码的其它部分实现。读程序时注意,所有程序都是逐行顺序执行的,要看清跳转指令。GET 2410addr.s /用到了2410addr.s中的寄存器地址宏定义; Some ARM920CPSR bit discriptions;Pre-defined constants/预定义的变量,一下后续代码中使用方便,与CPSR相关USERMODE EQU0x10FIQMODE EQU0x11IRQMODE EQU0x12SVCMODE EQU0x13ABORTMODE EQU0x17UNDEFMODE EQU0x1bMODEMASK EQU0x1fNOINT EQU0xc0I_Bit*0x80F_Bit*0x40; MMURegister discription;p15CP15;c0CN0;c1CN1;c2CN2;c3CN3CtrlMMU*1CtrlAlign*2CtrlCache*4CtrlWBuff*8CtrlBigEnd*128CtrlSystem*256CtrlROM*512;initializationL0 is MMU FULL_ACCESS, DOMAIN, SECTIONTLB_L0_INIT*0x0C02; Start here /执行代码从这里开始;/IMPORT ,定义表示这是一个外部变量的标号,不是在本程序定义的 /EXPORT ,表示本程序里面用到的变量提供给其他模块调用的。 /以上两个在汇编和C语言混合编程的时候用到AREAInit,CODE,READONLYIMPORT _use_no_semihosting_swiIMPORTEnter_UNDEF /有点extern的感觉IMPORTEnter_SWIIMPORTEnter_PABORTIMPORTEnter_DABORTIMPORTEnter_FIQENTRY/这是程序的入口/中断/异常向量表(跳转),上电第一条就执行b ColdReset,跳转到ColdReset。bColdReset bEnter_UNDEF;UndefinedInstructionbEnter_SWI;syscall_handler or SWIbEnter_PABORT;PrefetchAbortbEnter_DABORT;DataAbortb.;ReservedHandlerbIRQ_Handler;IRQHandlerbEnter_FIQ;FIQHandler;deal with IRQ interruptEXPORTIRQ_Handler/IRQ中断处理子程序IRQ_HandlerIMPORTISR_IrqHandler /服务程序在外部定义STMFDsp!, r0-r12, lrBLISR_IrqHandler/跳转至服务程序LDMFDsp!, r0-r12, lrSUBSpc, lr,#4;=; ENTRY ;=EXPORT ColdResetColdReset /上电执行复位异常函数,就跳转到这里来ldrr0,=WTCON;watch dog disable /关闭看门狗,还没初始化完系统,防止没“喂狗”再次复位,写看门狗寄存器WTCON即可ldrr1,=0x0strr1,r0ldrr0,=INTMSK/关闭所有中断ldrr1,=0xffffffff;all interrupt disablestrr1,r0ldrr0,=INTSUBMSK/关闭所有次级中断ldrr1,=0x7ff;all sub interrupt disable, 2002/04/10strr1,r0;*;*Initialize stacks * /进行堆栈初始化;*blInitStacks; StackSetup for each MODE/跳转到initstack,对各个模式下的堆栈进行初始化。; copy excption table to sram at 0x0/对堆栈初始化之后,进行域初始化;IMPORT|Load$EXCEPTION_EXEC$Base|IMPORT|Image$EXCEPTION_EXEC$Base|IMPORT|Image$EXCEPTION_EXEC$Length|ldrr0,=|Load$EXCEPTION_EXEC$Base|;sourcedataldrr1,=|Image$EXCEPTION_EXEC$Base|;place exception talbe at 0x0ldrr2,=|Image$EXCEPTION_EXEC$Length|exception_cploop/这段没读明白,但是猜测是将flash中的程序代码拷贝到SDRAM中运行subr2,r2,#4ldmiar0!,r3stmiar1!,r3cmpr2, #0bge exception_cploop; start main function in C language/跳转到用户代码main();IMPORT _mainBL_main ;Dont use main() because .B.;*;*The function for initializing stack *;*IMPORT UserStack/堆栈指针的值是在外部就定义好的。IMPORT SVCStackIMPORT UndefStackIMPORT IRQStackIMPORT AbortStackIMPORT FIQStackInitStacks;Dont use DRAM,such asstmfd,ldmfd.;SVCstack is initialized before;Under toolkit ver 2.50, msr cpsr,r1 can be used instead of msr cpsr_cxsf,r1/每个模式下都有自己的堆栈指针SP,我们对其进行设置的前提就是进入该模式,即对CPSR进行置位,才能访问这个模式下的SP,模式切换的时候,硬件会自动给SP置我们赋给的值。对CPSR的操作时按照“读出修改写入”的步骤进行的。即先用mrs读出,再用msr写入。mrsr0,cpsrbicr0,r0,#MODEMASKorrr1,r0,#UNDEFMODE|NOINTmsrcpsr_cxsf,r1;UndefMode/未定义模式堆栈初始化ldrsp,=UndefStack/cpsr_cxsf下划线后表示域,即操作哪些位。orrr1,r0,#ABORTMODE|NOINTmsrcpsr_cxsf,r1;AbortMode/中止模式堆栈初始化ldrsp,=AbortStackorrr1,r0,#IRQMODE|NOINTmsrcpsr_cxsf,r1;IRQMode/IRQ模式ldrsp,=IRQStackorrr1,r0,#FIQMODE|NOINTmsrcpsr_cxsf,r1;FIQMode/FIQ模式ldrsp,=FIQStack;bicr0,r0,#MODEMASK|NOINT/管理模式orrr1,r0,#SVCMODE|NOINTmsrcpsr_cxsf,r1;SVCModeldrsp,=SVCStack;USER m
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 临床路径模拟教学在儿科疫苗接种教学中的实践研究
- 临床路径模拟教学对医团队协作效率的影响研究
- 临床试验远程监查与中心实验室数据协同
- 评语大全之毕业论文开题评语
- 水库渗漏的原因及处理方法分析
- 一体化成本管控模式
- 专业技术人员科技论文写作100分答案
- 化学专业论文写作规范及排版格式
- 医学硕士学位申请书范文
- 中国语言文学论文
- 碎纸机管理制度
- 2022桶装饮用水 PC 罐清洗消毒卫生规范
- 湖南省长沙市雅礼教育集团2024-2025学年九年级3月月考道德与法治试题(原卷版+解析版)
- 病理科年终总结
- 姥爷的小人书(2024年四川泸州中考语文试卷记叙文阅读试题)
- 【营销方案】2025小红书平台营销通案
- 2024年中国碳纤维行业数据报告(纯数据版)
- 《三叉苦种植技术规程》
- 浙教版2023小学信息技术三年级上册3.9《体验在线应用》说课稿及反思
- GB/T 27697-2024立式油压千斤顶
- 工程伦理期末考试答案
评论
0/150
提交评论