|
从开端搞ARM到如今快到半年多了,第一个项目搞得有些眉目了,总算感受像是入门了,半年来,有开端的新鲜,中心的苦楚,到最终的欢喜。其间进程可谓曲折离奇,遇到了很到前人没有遇到过的疑难杂症,当然许多时分是由于我的大意变成的。从前也有过放弃的主意,那个焦虑,像得了狂躁症相同。后来下定决心即便绩效没了,作业丢了也要搞完它。本来在这个进程中,看到跟我相同的许多新人在论坛上发帖求助,可是许多时分回者屈指可数,能够疑问太天真,也能够疑问描述的不了解。我发过许多帖子,乃至直接骚扰了网上许多的牛人,他们都给了我很大的协助,可是我其时的主意太简略了,总想着某个牛人能够处置掉这个疑问,如今想想,即便是牛人,没有看到具体的疑问也很难给你一个处置方法,遇到艰难不能把期望彻底寄托在他人身上,要发掘自身潜力,一遍遍细心看手册,重复实验,不断思考,疑问肯定能处置掉,仅仅时间疑问罢了。再非有必要谢谢公司对我的忍受,一个这么简略的东东允许我搞了这么久。
本来,在前面的进程中,一向有写点啥的激动,可是其时艰难重重、出路未卜,也没了这个心境。如今能够坐下来细心总结下前面的疑问,有如今都没搞了解的,特向大家请教了;有处置掉的,那就说说经验教训,给其他人一些参阅。首要声明自个脑瓜笨,逻辑思维差,点一个灯点了一个多月,最终还发现没点对。所以说到的疑问能够很天真,说话也如同前言不搭后语,有兴趣看的那就受累了哈。
先说说咱们的这个块板子,裸奔的at91sam9260,外扩Norflash、SRAM,完结程序既能够跑在Norflash中,也能够复制到Sram中跑。使命就一个:操控一个片外AD,读出数据然后经过串口发出。很简略的吧,这我都搞了几个月呢,你说菜不菜吧。以下我将回想全部的ARM学习进程,涉及到的常识都是很简略的基础常识,老鸟就不必看了,期望能够协助到像我相同的菜鸟。
之前也在学过一些PCB制作。
前三个月首要是了解的进程,其时彻底没有想到后边程序的调试会如此的艰难,想当然地以为又不上体系,无非是32位的单片机嘛。板子做回来一大段时间内,元器件都没有凑齐,其时傻了呀,大概先了解了解编程环境,每天就为几个破元件折腾,啥都没干。
后来板子焊接好了,才发现只会用H-JTAG辨认芯片,其他的啥都不了解。然后开端看例程,只玩过51的我,初度触摸32位的单片机,其时看到AT91C_BASE_PMC->PMC_PCER=(0x1<<3)这样的句子,竟然不晓得是啥意思,一是迷惑->代表个啥?二是为啥写成0x1<<3的姿态?后来不知过了多久才了解,AT91C_BASE_PMC是个基地址,PMC_PCER是相对这个基地址的偏移,移位赋值是为了给32位寄存器赋值的便利。
先说说开发嵌入式linux要用到的软件以及东西吧,这段时间我接连运用了IAR、KEIL、h-jtag、JLink,都会用可是都不精通。最终是在KEIL+Jlink下完结的。
开发东西的挑选:
1、编译环境:IAR、KEIL、GCC、……
开端我想也没想就挑选了IAR,缘由很简略:ATMEL的例程很都是依据IAR的,而KEIL装置目录下的例程很少。匆忙装置了IAR其时的最新版IAR5.20,彻底没有思考可用的资本和沟通的便利。然后才发现IAR5.X跟4.X有很大的不一样,首要即是其间的链接器从XLINK换成了ILINK,所以装备文件也由XCL文件换成了ICF文件,初看后者如同比前者更简略更易懂了,可是由所以新版,运用的人还不多,网上上的参阅材料大有些仍是依据4.X的,关于菜鸟哪几条句子仍是很隐晦。
不过一根筋的我仍是硬着头皮坚持运用IAR5.20,直到遇到IAR的杀招:体系从慢时钟想快时钟切换时就跑飞了,都是死在lowlevelinit()中的这一句上:AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK;然后将这一句放在主程序中,照死不误。运用进程中,总弹出一个警告,大致意思即是说:IAR装置目录下,bin文件夹下的armlibsupport.dll may be missing or corrupt.从头装后仍是老姿态。在LED闪烁程序上折腾一个多月未果后,才痛下决心转向KEIL。
用上KEIL才发现这玩意不是传说中的弱智,相反格外合适我等菜鸟,感受首要有三个方面格外好:发动代码的图形化装备;在Flash跑不需求啥装备文件,直接在option中添两个地址值就能够了;只需点击鼠标就能够完结将代码从Flash主动复制到RAM中履行,不需求再写啥代码复制程序了。
GCC,没用过,不了解。
2、调试东西:JLINK、H-JTAG、ULINK、……
开端运用h-jtag,合作Wiggler运用,小巧且廉价,不得不敬服Twentyone长辈,在RAM中调试很便利,也能够经过H-Flasher将程序下载到Flash跑,运用h-flasher时要一个初始化文件,首要是初始化Flash有关寄存器。
后来看到DB的JLINK都白菜价了,就从taobao买了一个JLINK,首要是不必再用并口了,如今百元以内的JLINK大把,用JLINK是个不错的挑选,可是调试片外的flash如同还不能无限断点。
ULINK,不太了解,如同只支撑KEIL,不过没用过。
这次首要说说首次搞ARM格外是从51直接跳到ARM的有必要面临的几个概念:REMAP、Bootloader、Flashloader。
1、REMAP:
说到REMAP。首要应想到啥是MAP,英语欠好,开端就断章取义,MAP即是地图嘛,Memory Map即是存储器地图,不过这个地图的参阅坐标不是经纬度,而是地址,进而叫做存储器映射。由于要习惯不一样存储器容量要求的用处,ARM处置器自身的RAM、ROM并不是满足大,所以许多时分要外扩一些存储器,Norflash、NANDFlash、SDRAM、SRAM……而关于ARM来说怎样辨认这些不一样的存储器呢,只能给每个分配一个独立的地址,就相当于每个人有不一样的姓名。片内存储器的地址通常出厂就固化好的,片外的话就依据每个存储器所衔接的外部总线片选而具有不一样的地址。
所以REMAP,断章取义即是存储器的从头映射,即某些存储器的地址又发作了改动。我就很不了解了,这地址正本就欠好记,还变来变去的,麻不费事呀,学51的时分咋就没这玩意呢?后来查了些材料,有些了解了,51是8位机,更重要的是51的主频不高,8位的ROM或Flash满足匹配51的主频,不必刺进等候指令,所以程序直接在ROM或Flash中跑影响不到体系的速度。而ARM就不一样了,ARM是32位机,可是Flash通常是8位或16位,32位的也有吧,如同报价很高。并且ARM的成品很高,动辄上百M,所以Flash的技术达不到这个速度。假如程序跑在Flash中就要刺进过多的等候指令,所以会影响ARM的功能。而RAM通常存取速度对比快,很简略构成32位,能够与高速的ARM匹配。更重要的是ARM上电后有必要从0x0地址处获得指令,因而上电后有必要将ROM或Flash映射位0X0地址处,其时还产生了一个弱智的主意,已然RAM这么好,为啥还要ROM或Flash,直接将程序下载到RAM中不就得了,后来才猛地想到RAM是易失型存储器,掉电后啥也没了,再上电后0X0处啥都没有。并且还有一条,ARM的中止向量表,既寄存各个中止进口地址的地方,通常放在0x0处,即ROM或Flash中,为了加速中止响应速度,也大概将0X0映射到RAM中去。因而,ARM通常从ROM或Flash发动完结初始化,然后将应用程序复制到RAM,然后跳到RAM履行。
方才说的是,为啥要REMAP,接下来说怎样REMAP。开端的时分我就不了解,都说REMAP,那怎样才能完结REMAP呢?都是手册看得少呀,本来上面说的现已很了解了,咱们用的at91sam9260更是简略,有专门的寄存器能够装备,MATRIX_MRCR—Master Remap Control Register,向这个寄存器相应位写1就能够了。网上还看到Samsung的某些ARM能够经过编程相应Bank寄存器改动其开端地址,来完结REMAP。
下面以咱们的at91sam9260的板子为例具体说说我对at91sam9260 REMAP的了解,开端Flash没有任何程序,当然也没有REMAP,此刻将BMS接高,然后上电,此刻的0X0地址处坐落片内的ROM,由于ROM内如同固化了引导程序,所以此刻串口会输出“Rom Boot…>”字样。而内部的SRAM0的开端地址仍是在0x20 0000处,而片外Norflash开端地址是0x1000 0000处。然后咱们运用h-flasher或J-Flash将生成的Bin文件下载到Norflash内,即开端地址为0x1000 0000处。然后将BMS接低,此刻Norflash被映射在0X0地址处,即此刻Norflash的开端地址为0X0,(你能够要问那ROM的地址如今在哪儿呢?我也不晓得,由于Norflash的地址规模是0X0~0X1F FFFF,而ROM的开端地址默许是0X10 0000,恰好在Norflash的规模内,所以此刻ROM哪儿去了?)此刻上电,由于0X0地址处即Norflash开端地址有八个合法的中止向量,程序会从Norflash发动,接着履行发动代码,初始化SMC、PMC,然后Copy中止向量表到内部SRAM0,然后,将MATRIX_MRCR寄存器相应方位1,完结REMAP,此刻,Norflash的开端地址又变回0X1000 0000,而内部的SRAM0的开端地址又变回0x0了,体系假如发作反常,将从地址0X0处即内部SRAM0取中止向量,而内部SRAM的访问速度显然高于外部的Norflash,所以进步程序功能。这是我对at91sam9260 REMAP的了解,期待评论指导。
2、Bootloader:
说实话,这个概念到如今也不是很了解。能够关于裸奔的体系来说,Bootloader这个概念自身就对比含糊吧,断章取义的话,Boot,靴子,Load,穿上靴子走路才对比舒畅(这个比方如同对比烂喔),关于ARM来说,初始化好,并将向量表以及数据啥的复制到RAM,运转起来才顺利。即是传说中的引导装载。所以我了解的Bootloader即是完结ARM的初始化、树立中止向量表并映射到RAM中、将数据段和必要的代码段复制到RAM、完结REMAP、跳转到Main,这一系列进程。说白了即是发动代码干的活。这个了解我自个都感受很牵强,还请大家多多点拨。
3、Flashloader:
这个概念更是含糊,总感受跟Bootloader差不多,只不过Flashloader能够完结对Flash的读写、擦除等操作,并与调试软件合作完结将程序下载到Flash中。IAR中有一个选项:Use Flashloader,不过如同通常都是对于片内Flash的,咱们的板子是外扩的Norflash,如同就没有用到这个东东。
接下来预备说说依据KEIL MDK下的发动代码的了解。
当Norflash被映射在0X0地址处时,此刻Norflash的开端地址为0X0,那ROM的地址如今在哪儿呢?由于Norflash的地址规模是0X0~0X1F FFFF,而ROM的开端地址默许是0X10 0000,恰好在Norflash的规模内,所以此刻ROM哪儿去了?
该死的发动代码
提起发动代码,我就嗷嗷抑郁,IAR下的程序都死在了这儿,Keil中呈现的疑问许多都是经过对发动代码的修修补补才处置的,一句话:成也发动代码,败也发动代码。
发动代码大概是刚触摸ARM的菜鸟有必要面临而又很头痛的疑问吧,刚开端我也很疑惑,为啥搞个这玩意,学51的时分咋就没见过呢。并且还都是汇编写的,俺的汇编还停留在“MOV”期间,其他的不是很懂,没办法,谁让汇编的效率高呢。说到发动代码还不得不陈词滥调一下其间要完结的使命:
1、树立反常中止向量表,ARM从0X0开端给每个反常中止分配4个字节的空间,通常寄存一个跳转指令(B)或PC的装载指令(LDR PC,X_Vector),当发作反常时,ARM从此处获得相应反常中止处置程序进口地址,再跳转履行;
2、ARM都是高速处置器,而在高速下发动很能够会不稳定,所以在发动代码从慢时钟开端运转,在恰当的方位,从32.768K切换到高速运转;
3、ARM通常带有片外存储器,Flash、SDRAM等,这些存储器都需求初始化才能运用,这都是在发动代码中完结,可是Norflash的初始化要在时钟初始化之前;
4、ARM有不一样的形式,每种形式都需求相应的仓库;
5、Copy反常中止向量表到RAM,并完结REMAP,具体请参照上一节;
6、Copy可履行映像的数据段到RAM,并将ZI区清零。这个通常都是由编译器完结的,IAR下是?main来完结,Keil中由__main完结。
如今发动代码能够看懂一些,不过自个写发动代码仍是很悠远的工作。假如开端对发动代码很冲突,能够思考运用Keil,由于Keil由发动代码的图形化装备,直接点击鼠标操作就能够完结自个的发动代码。下面联系咱们at91sam9260的板子,说说Keil中的发动代码。
翻开Keil生成的SAM9260.S,点击左下角的“Configuration Wizard”进入图形化装备导游,依据你的需求挑选参数,全部挑选结束后,再点击"Text Editor",将会看到生成的发动代码。
我靠,不是吧,快到2000行,开端你能够会很灰心,但细心一看,前面不都是些宏界说嘛,跟图形化装备导游一一对应的,只要从1200多行的这一句开端的才是真实的发动代码有些。
|
|