您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 公司方案 > ARM嵌入式软件开发
1TMTHEARCHITECTUREFORTHEDIGITALWORLD嵌入式软件开发2TM266v06EmbeddedSoftwareDevelopment嵌入式开发过程“PC软件”helloworld独立的嵌入式应用当程序员开始开发一个基于ARM应用的时候,你可以使用ARM的ADS编写类似于“HELLOWORLD”的程序,使用ARMulator或者在评估板上来调试,但当你把他移植到独立的嵌入式应用设备中时,下面这些问题就成为我们首要考虑的:硬件环境中所使用的C库函数目标板上的存储器资源应用程序的初始化3TM366v06EmbeddedSoftwareDevelopment议程PC软件的构造定制标准C库函数到目标板定制IMAGE的存储器映射到目标板复位和初始化深层次的存储器器映象考虑编译和调试IMAGE4TM466v06EmbeddedSoftwareDevelopmentADS默认的标准C库ANSICinput/outputerrorhandlingstack&heapsetupotherSemihostingSupport应用程序调用的C库函数eg:fputc()设备驱动层使用semihostingSWI’seg:_sys_write()调试工具环境CLibraryDebugAgentC库函数功能是支持PC软件的,而目标板上的可执行软件则依赖相关的硬件资源;在ARM体系中,我们可以采用semihosting通过相应的驱动来进行调试。5TM566v06EmbeddedSoftwareDevelopmentADS默认的存储器映射在默认的情况下,我们链接、定位、运行在0x8000heap被直接放置在数据区的上面堆栈的基地址是通过调试环境从C库函数的StartupCode里读取出来的。ARMulator=fromconfigurationfile(peripherals.ami)default=0x08000000Multi-ICE=fromdebuggerinternalvariable$top_of_memorydefault=0x80000RORWZI0x8000链接时确定由调试环境提供Heap(malloc,alloc)Stack6TM666v06EmbeddedSoftwareDevelopmentCLibraryUserCode应用程序启动__maincopycodeanddatazerouninitializeddata__rt_entrysetupapplicationstackandheapinitializelibraryfunctionscalltop-levelconstructors(C++)Exitfromapplicationmain()causesthelinkertopullinlibraryinitializationcode程序入口点7TM766v06EmbeddedSoftwareDevelopmentAgenda一个PC软件的构造定制标准C库函数到目标板定制IMAGE的存储器映射到目标板复位和初始化深层次的存储器器映象考虑编译和调试IMAGE8TM866v06EmbeddedSoftwareDevelopment重定向C库函数(1)SemihostingSupportANSICinput/output你可以使用适合你目标板运行的驱动来替换标准C库中的设备驱动。Eg:printf()可打印到LCD上,而不是打印控制台上input/outputANSICCLibraryUserCodeDebugAgentTargetHardwareRetarget9TM966v06EmbeddedSoftwareDevelopment重定向C库函数(2)要重定向C库函数,简单的办法是使用你自己的可执行的semihostingSWIs来代替原来的C库函数,从而来满足你的系统要求比如说,theprintf()系列函数(sprintf()除外)都会调用fputc().在默认情况下fputc()的执行使用了semihostingSWI.用下面的语句来代替:externvoidsendchar(char*ch);intfputc(intch,FILE*f){/*e.g.writeacharactertoanLCD*/chartempch=ch;sendchar(&tempch);returnch;}可查看在ADSEmbeddedexample目录下的retarget.c,可看到更多的重定向例子你可以确定有不在连接时使用semihostingSWI的吗?…...10TM1066v06EmbeddedSoftwareDevelopment消除C库函数中的semihosting为了确保在连接时没有函数使用了semihostingSWIs,你可以在程序中加入下面的句子:#pragmaimport(__use_no_semihosting_swi)如果在程序中仍然使用了semihosting,编译时将会报错:Error:Symbol__semihosting_swi_guardmultiplydefined修改:如果使用(check-verboselinkeroutputforoccurrencesofIuse_semihosting_swi),那么连接器将会把那些使用了smeihosting的程序列出来,然后:提供你自己可运行的功能函数。在ADS1.2编译器和库函数手册,表4-2给出了所有使用了semihosting的C库函数。注意:连接器在用户自己的应用代码中不会出现任何有关semihostingSWI使用的报告。11TM1166v06EmbeddedSoftwareDevelopmentAgenda一个PC软件的构造定制标准C库函数到目标板定制IMAGE的存储器映射到目标板复位和初始化深层次的存储器器映象考虑编译和调试IMAGE12TM1266v06EmbeddedSoftwareDevelopment分散加载(Scatterloading)在一个实际应用当中,你可能并不想在0x8000处开始运行。大多数嵌入式系统都有存储器设备,他们的地址空间是在整个存储器映射中交叉出现的。分散加载提供了一种把你的代码和数据放在不同的存储器定位上的办法分散加载定义了两种类型的存储器区域。Load区:-在reset/load时保留了应用程序的代码和数据(典型应用为ROM).Execution区–在程序执行的同时保留了程序的代码和数据。在应用程序启动期间,每个load区都可创建一个或多个可执行区。分散加载了的应用把详细的存储器映射保存在一个描述文件中,作为一个参数给armlink使用eg:armlinkprogram.o-scatterscatter.scf-oprogram.axf13TM1366v06EmbeddedSoftwareDevelopmentExecuteViewRAM0x100000x180000x40000x0000ROMRO分散加载(简单例子)只读代码和数据保存在ROM中C库函数初始化代码(在__main)将:从ROM拷贝RW数据到RAM在RAM中的ZI数据初始化RAM0x100000x180000x40000x0000ROMLoadViewRORWFillwithzerosZICopyRW14TM1466v06EmbeddedSoftwareDevelopmentExecuteViewRAM0x100000x180000x40000x0000ROMROLOAD_ROM0x00000x4000{}RAM0x100000x180000x40000x0000ROMLoadViewRORWScatter描述文件通配符(*)语法允许简单的对CODE和DATA进行分组EXEC_ROM0x00000x4000{*(+RO)}RAM0x100000x8000{*(+RW,+ZI)}RWZI15TM1566v06EmbeddedSoftwareDevelopmentRORWZIROCODERO-DATARO-CODEAB链接器放置规则在每个可执行区,链接器通过一些基本的规则来放置CODE和DATA基本的排序方法是通过属性来安排的:RO领先于RW,RW领先于ZI有相同的属性时,CODE在DATA之前放置。更多的排序方法决定于:输入的组名按字母排序,在ARMLINK命令行中指定的顺序。eg:armlinkfile1.ofile2.o…AsectionAfromfile1.osectionAfromfile2.o16TM1666v06EmbeddedSoftwareDevelopment在SCATTOR文件中的对象排序为了把特定的CODE和DATA放在指定的地址上,你可以不考虑标准的放置规则使用+FIRST和+LAST,直接把第一个和最后一个对象放在可执行区。图例:把VECTOR表放在区的开始。LOAD_ROM0x00000x4000{EXEC_ROM0x00000x4000{vectors.o(Vectors,+FIRST)file1.o(+RO)file2.o(+RO)}:}在可执行区内,scattor文件中要排序的对象对输出image没有影响链接器的标准放置规则仍然适用17TM1766v06EmbeddedSoftwareDevelopmentROOT区LOAD_ROM0x00000x4000;startaddressandlength{EXEC_ROM0x00000x4000;root(load=execaddress){__main.o(+RO);copyingcode*(Region$$Table);RO/RWaddressestocopy*(ZISection$$Table);ZIaddressestozero}RAM0x100000x8000{*(+RO);AllotherROareas*(+RW,+ZI);programvariables}}Mustbeinarootregionoutsiderootregion一个root区是一个可执行区,它的加载地址等于执行地址。18TM1866v06EmbeddedSoftwareDevelopmentRoot区要点一个root区是一个可执行区,它的加载地址等于执行地址.每个scatter描述文件必须最少包含一个root区,并且最少要包含下列内容:__main.o–含有拷贝code/data的代码Region$$Table和ZISection$$Table–含有将要拷贝的code/data的地址,他是由链接器产生的,不是一个对象文件。(所以*必须用)Error:L6202E:SectionRegion$$Tablecannotbeassignedtoanon-rootregion.Error:L6202E:SectionZISection$$Tablecannotbeassignedtoanon-rootregion.注意:如果*(+RO)被定位在root区,在此之前的将被自动放置Main应用程序的入口点必须放在root区。Error:L6203E:Entrypoint(0x08000000)lieswithinnon-rootregionEXE_FLASH.19TM1966v06EmbeddedSoftwareDevelopmentRun-time存储器管理SemihostingSupportANSICStack&HeapSetupStack&HeapSetupANSICCLibraryUserCodeDebugAgentTargetHardwareRetarget如何设置stack和heap来满足我们的目标存储器?我们已经通过执行__user_initial_stackheap()把C标准库的运行存储器模式修改到目标平台上。20TM2066v06Embedde
本文标题:ARM嵌入式软件开发
链接地址:https://www.777doc.com/doc-3604531 .html