使用ADS1.2进行嵌入式软件开发(下).

上传人:jiups****uk12 文档编号:90756071 上传时间:2019-06-16 格式:DOC 页数:5 大小:31.51KB
返回 下载 相关 举报
使用ADS1.2进行嵌入式软件开发(下)._第1页
第1页 / 共5页
使用ADS1.2进行嵌入式软件开发(下)._第2页
第2页 / 共5页
使用ADS1.2进行嵌入式软件开发(下)._第3页
第3页 / 共5页
使用ADS1.2进行嵌入式软件开发(下)._第4页
第4页 / 共5页
使用ADS1.2进行嵌入式软件开发(下)._第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《使用ADS1.2进行嵌入式软件开发(下).》由会员分享,可在线阅读,更多相关《使用ADS1.2进行嵌入式软件开发(下).(5页珍藏版)》请在金锄头文库上搜索。

1、使用ADS1.2进行嵌入式软件开发(下)上期主要介绍了基于ARM的嵌入式系统软件开发中,怎样来对必要的C库函数进行移植和重定向,以及如何根据不同的目标存储器系统进行程序编译和连接设置。本期介绍程序中的存储器分配和如何根据设置正确初始化系统。放置堆栈和heapScatterloading机制提供了一种指定代码和静态数据布局的方法。下面介绍如何放置应用程序的堆栈和heap。* _user_initial_stackheap重定向应用程序的堆栈和heap是在C库函数初始化过程中建立起来的。可以通过重定向对应的子程序来改变堆栈和heap的位置,在ADS的库函数中,即_user_initial_stac

2、kheap()函数。_user_initial_stackheap()可以用C或汇编来实现,它必须返回如下参数:r0:heap基地址;r1:堆栈基地址;r2:heap长度限制值(需要的话);r3:堆栈长度限制值。当用户使用分散装载功能的时候,必须重调用_user_initial_stackheap(),否则连接器会报错:Error: L6218E: Undefined symbol Image$ZI$Limit (referred from sys_stackheap.o)*存储器模型ADS提供了两种实时存储器模型。缺省时为one-region,应用程序的堆栈和heap位于同一个存储器区块,使

3、用的时候相向生长,当在heap区分配一块存储器空间时需要检查堆栈指针。另一种情况是堆栈和heap使用两块独立的存储器区域。对于速度特别快的RAM,可选择只用来作堆栈使用。为了使用这种two-region模型,用户需要导入符号use_two_region_memory,heap使用需要检查heap的长度限制值。对这两种模型来说,缺省情况下对堆栈的生长都不进行检查。用户可以在程序编译时使用 -apcs/swst 编译器选项来进行软件堆栈检查。如果使用two-region模型,必须得在执行_user_initial_stackheap时指定一个堆栈限制值。 图9 重定向_user_initial_s

4、tackheap()图10 基本初始化过程图11 ROM/RAM重定向和映射表1系统复位和初始化目前情况,一般假设程序从C库函数的初始化入口_main开始执行。实际上,所有的嵌入式程序在启动时都要执行一些系统级的初始化操作。在此讨论这方面的内容。初始化过程图10中显示了一个基于ARM的嵌入式系统的基本初始化过程。可以看到,在_main之前加入了一个复位处理模块reset handler,它在系统上电复位时立即启动。标识为$sub$main的新代码块在进入主程序之前执行。复位处理模块reset handler通常是一小段汇编代码,在系统复位时执行。它至少完成应用程序中使用到的所有处理器模式的堆栈

5、初始化工作。对于含有本地存储器系统的内核(比如含cache的ARM内核),配置工作也必须在这一段初始化过程中完成。当完成系统初始化之后,通常程序会跳向_main,开始C库函数的初始化过程。系统初始化过程一般还包括另外一些内容,中断使能等,这些大多安排在C库函数的初始化完成之后执行。$sub$main()完成这部分功能。向量表(vector table)所有的ARM系统都有一张中断向量表当出现异常需要处理时,必须调用向量表。向量表一般要位于0地址处。表2表3表4表5表6表7表8表9表10存储器配置*ROM/RAM重定向当系统启动的时候,为了保证0地址处有正确的启动代码存在,需要非易失性的存储器。

6、一种简单的方法,就是把系统0x0000开始的一块地址分配给ROM。其缺点是,由于ROM的访问速度比RAM慢很多,当执行中断响应需要从中断向量表跳转时,会给系统性能带来损失;同时,在ROM中的向量表内容也不能被用户程序动态修改。另外一种可行的方案如图11所示。ROM位于地址0x1000开始的地方,但是在系统复位时又被存储器控制器映射到0x0000地址处。这样当系统启动之后,在地址0x0000看到的是ROM,系统执行这块ROM中的启动代码,启动代码跳转到真正的ROM的地址,并让存储器控制器移除对ROM的地址映射。这时0x0000地址处的存储器又恢复回了RAM。_main中的代码把向量表copy到0

7、x0000处的RAM中去,使得异常时能被正确响应。表1为ARM汇编中执行ROM/RAM重定向和映射的一个例子。它以ARM公司的Integrator平台为基础的,该方法适用于类似ROM/RAM重定向方法的所有平台。第一条指令完成从ROM的映射地址(0x00000)到真实地址的跳转。地址标号instruct_2是ROM的真实地址(0x180004)。然后通过设置Integrator平台上的相应控制寄存器,移除ROM的地址映射。代码在系统一启动就被执行。所有关于地址重定向/映射的操作必须在C库函数初始化之前完成。*本地存储器配置许多ARM处理器都有片上存储器系统,如cache和紧密耦合存储器(TCM

8、)、存储器http:/ target=_blank class=infotextkey管理单元(MMU)或存储器保护单元(MPU)。这些设备都要在系统初始化过程中正确配置,并且有一些特殊的要求需要考虑。由前文可知,_main中的C库函数初始化代码负责程序运行时的存储器系统设置。因此,整个存储器系统本身必须得在_main之前完成初始化工作,如MMU或MPU必须在reset handler里面完成配置。紧密耦合存储器(TCM)的初始化同样须在_main之前完成(通常在MMU/MPU之前),因为一般程序都需要把代码和数据分散装入TCM。需要注意的是当TCM被使能后,不再访问被TCM屏蔽的存储器。关于

9、cache的一致性问题,如果cache在_main之前使能的话,那么当_main里面进行从装载区到执行区的代码和数据拷贝时(因为在拷贝过程中指令和数据在本质上都是被当作数据处理),指令会出现在数据缓冲区。避免此问题的方法是在C库函数初始化完成后再使能cache。*Scatter loading与存储器配置无论是通过ROM/RAM重定向还是MMU配置的方法,如果系统在启动和运行时存储器分布不一致,scatterloading文件中的定义就要按照系统重定向后的存储器分布情况进行。以上文ROM/RAM重定向为例:LOAD_ROM 0x10000 0x8000EXE_ROM 0x10000 0x800

10、0reset_handler.o (+RO, +FIRST).RAM 0x0000 0x4000vectors.o (+RO, +FIRST).装载区LOAD_ROM被放置在0x10000处,代表了重定向之后代码和数据的装载地址。堆栈的初始化程序中可能用到的处理器模式,都需要定义一个堆栈指针。在表2中,堆栈位于stack_base标识的地址中。这个符号可以是存储器系统中的一个直接地址,也可以在另外的汇编文件中定义,由scatter文件来定义分配地址。表2代码为FIQ和IRQ模式各分配了一个256字节的堆栈,用户可以用同样的方法为其他模式也分配堆栈。最简单的方法就是进入相应的模式,然后为SP寄存

11、器指定相应的值。如果想使用软件堆栈检查,还必须指定一个堆栈长度限制值。堆栈指针和堆栈限制的数值会作为参数自动传递到C库函数的初始化代码_user_initial_stackheap中,在_user_initial_stackheap中不应该修改这些值。硬件初始化 $sub$main()一般来说,应该把所有的系统初始化代码与主应用程序分离开来,但是有几个例外,比如cache和中断的使能,需要在C库函数初始化之后执行。表3代码显示了如何使用 $sub和 $supper 。连接器把呼叫main()的函数替换成呼叫$sub$main(),完成cache和中断的使能,并最终跳向main()。执行模式考虑为主应用程序选择一个处理器执行模式非常重要,这取决于系统的初始化代码。许多在启动过程中使用到的功能,如MMU/MPU的配置、中断的使能等,只能在特权级模式下进行。如果需要在特权极模式下运行自己的应用程序,只要在退出初始化过程之前改变到相应的模式就行了,没有其他任何问题。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号