1、Heap region was used, but no heap region was defined
工程中,我使用的是自己的分散加载文件,并且没有定义ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP这些符号,因为我自己要重新定义堆栈,就没有使用这些符号,因此在C代码中加入下述代码:
// 不使用ARM提供的堆函数 __asm(".global __use_no_heap");
但是编译的时候还是报错:Error: L6915E: Library reports error: Heap region was used, but no heap region was defined。最初我以为是分散加载文件的问题,后来查看分析,觉得分散加载没问题,于是就换个方向思考。
因为我在C代码中添加了不使用ARM提供的堆函数的声明,然而ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP这些符号会在ARM官方代码的堆栈初始化函数中进行使用,那么我只要分析出是谁在调用ARM官方的堆栈初始化函数,就能够解决这个问题了。
后来发现我的启动代码中少写了一个函数__rt_entry,这个函数的作用就是一些初始化工作,当然也就包括初始化堆栈了。这个函数在ARM官方库中已经实现,由于我没有自定义__rt_entry函数,因此在启动时会调用ARM官方的__rt_entry函数,也就自然会调用ARM库中的堆栈初始化函数,在链接的过程中,当发现分散加载文件没有定义ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP这些符号就报错:Error: L6915E: Library reports error: Heap region was used, but no heap region was defined。
解决方法:自然是在我的启动文件中自定义一个__rt_entry函数,该函数会调用main()函数。
2、启动过程中出现总线异常
在解决了上面第1个问题后,工程能够成功的编译和链接,但是程序运行时会出现总线错误,而且有时候代码量减小又不会出现这个问题。最开始分析这个问题,花费了不少时间,也没有摸着门道。后来也是在我组长的指点下才解决的。
首先分析下为什么这个总线异常问题有时会出现,有时不会出现。这就得说说分散加载文件中加载域和执行域中的一个标志:NOCOMPRESS,AC6.12的armlink文档中有对这个标志的描述:
RW data compression is enabled by default. The NOCOMPRESS keyword enables you to specify that RW data in an execution region must not be compressed in the final image.
大致意思,默认情况下RW数据会被压缩放置在image中,只有在分散加载文件中相关的加载域与执行域中使用标志NOCOMPRESS时,才不会对RW数据进行压缩。
因为我没有使用NOCOMPRESS标志,因此会对RW数据进行压缩,因此在image中的RW数据会比实际的长度小一些。由于是我自己在启动代码中初始化data和bss,因此在将flash中的RW data拷贝到RAM中时,RW data的长度我仍然使用的是未压缩的数据长度,该长度大于压缩数据的长度,在将flash中的RW data拷贝到RAM中时,当长度超过压缩数据的长度,flash就会产生保护,从而触发一个总线异常,而且异常的地址存储在BFAR中。
解决方法:这里有两种解决方法。
方法1:最简单的就是在分散加载文件中RW data相关的加载域和执行域使用NOCOMPRESS标志,当然了这个方法的缺点就是产生的image文件会大一些。
方法2:可以在启动代码中配置好sp,然后就不用去对RW data和bss进行处理(屏蔽掉自己写的RW data和bss的处理代码),这些工作ARM官方库会自行处理的(压缩的RW data在拷贝到RAM中时,ARM官方库会进行解压缩的,这些ARM库代码在编译和链接的时候会自动的加入到image中)。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !