0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于ARM编译器版本5的工程迁移与适配-堆栈初始化以及总线异常问题

嵌入式那些事 来源:嵌入式那些事 2023-11-16 16:28 次阅读

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中)。







审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8653

    浏览量

    361875
  • RAM
    RAM
    +关注

    关注

    7

    文章

    1322

    浏览量

    113710

原文标题:基于ARM编译器版本5的工程迁移与适配到ARM编译器版本6.12 后续2 - 堆栈初始化以及总线异常问题

文章出处:【微信号:嵌入式那些事,微信公众号:嵌入式那些事】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Keil修改ARM编译器及配置方法

    Keil MDK自 V5.36 版本之后,默认就不带 Arm Compiler V5版本编译器。如果需要使用 V5 版本
    发表于 09-19 10:41 2247次阅读
    Keil修改<b class='flag-5'>ARM</b><b class='flag-5'>编译器</b>及配置方法

    使用SEGGER Embedded Studio编译器发现变量无法自动初始化

    使用SEGGER Embedded Studio编译器发现变量无法自动初始化, 例如声明静态变量static uint8_t i = 0;这种写法i成了静态变量,但没有初始化成功,声明的结构体也是
    发表于 01-11 14:21

    ARM堆栈学习笔记

    R13,在用户应用程序的初始化部分,一般都要初始化每种模式下的R13,使其指向该运行模式的栈空间,这样,当程序的运行进入异常模式时,可以将需要保护的寄存放入R13所指向的
    发表于 06-15 11:50

    学习ARM过程中的堆栈初始化详解

    指令强制性的要 求使用R13作为堆栈指针。由于处理的每种运行模式均有自己独立的物理寄存R13,在用户应用程序的初始化部分,一般都要初始化
    发表于 04-20 14:11

    使用新版本IAR编译版本的STM32工程

    问题,本文将介绍如何解决该问题。2、打开工程原材料:老版本IAR工程:一个使用IAR for ARM v5.x
    发表于 08-24 06:08

    IAR C编译器中如何选择才能不初始化片内RAM

    IAR C编译器中如何选择才能不初始化片内RAM?配置IAR时器件与代码选型不一致怎么办呢?
    发表于 01-27 06:22

    S32K146 ECC初始化,为什么不初始化堆栈空间?

    S32K146 ECC初始化,为什么不初始化堆栈空间?
    发表于 04-20 12:55

    ARM编译器for Embedded Version 6.20移植和兼容性指南

    Arm®编译器嵌入式迁移和兼容性指南为从旧版本Arm编译器
    发表于 08-10 07:17

    Arm编译器迁移和兼容性指南

    Arm®编译器迁移和兼容性指南为从旧版本Arm编译器迁移
    发表于 08-10 06:57

    ARM编译器5.06版迁移与兼容性指南

    尽管不能保证不同版本ARM编译器之间的兼容性,但有一些方法可以帮助您实现兼容性。 ARM编译器生成的代码符合
    发表于 08-21 07:50

    ARM编译器优化版本1.0

    ARM编译器armcc可以优化您的代码以实现小代码和高性能。 本教程介绍了编译器执行的主要优化技术,并解释了如何控制编译器优化。 本教程假定您已经安装并许可了
    发表于 08-28 07:11

    用于嵌入式FUSA的ARM编译器移植和兼容性指南

    《用于Embedded FUSA的ARM®编译器迁移与兼容性指南》为从旧版本ARM编译器
    发表于 08-29 07:02

    ICC AVR编译器的安装与使用

    ICCAVR编译器的安装、运行、破解、使用 用ICCAVR编译器产生初始化程序和程序框架
    发表于 07-09 18:06 258次下载

    EE-88:使用21xx编译器初始化C语言中的变量

    EE-88:使用21xx编译器初始化C语言中的变量
    发表于 05-19 21:08 1次下载
    EE-88:使用21xx<b class='flag-5'>编译器</b><b class='flag-5'>初始化</b>C语言中的变量

    基于ARM编译器版本5的工程迁移适配ARM编译器版本6.12

    AC5和AC6的主要差异是AC6使用armclang代替了armcc,因此在AC6中就没有armcc这个编译工具了。并且armclang的编译参数相对于之前的armcc的编译参数也有许多不同。
    的头像 发表于 11-12 11:17 7516次阅读
    基于<b class='flag-5'>ARM</b><b class='flag-5'>编译器</b><b class='flag-5'>版本</b>5的<b class='flag-5'>工程</b><b class='flag-5'>迁移</b>与<b class='flag-5'>适配</b>到<b class='flag-5'>ARM</b><b class='flag-5'>编译器</b><b class='flag-5'>版本</b>6.12