当前位置: 首页 > news >正文

ARM学习(31)编译器对overlay方式的支持

ARM学习(31)编译器对overlay方式的支持

1、overlay介绍

overlay:重叠得意思,就是可以重复利用得空间,一般在内存上使用这种空间。比如以Windows操作系统为例,其存储空间(ROM/FLASH)一般相对较大,但是内存相对较少,内存要加载Flash上面得较多数据,就得空间上面重复使用。

比如一个游侠里面油很多动态链接库dll,内存有限,只能加载一部分dll库,当用到一些库时,就会将一些库覆盖掉,然后调用这些库,当然这里有很多替换得算法,比如LRU,least recently used,最近最少使用得会被替换,由于被替换得库不确定,所以加载得地址不确定,这就要求dll可以动态加载,根据加载得地址进行偏移寻址,这就是PIC,位置无关,dll里面得代码均使用相对寻址,所以加载到任何地址均可以使用(理论上)。

嵌入式系统为了运行效率高,往往会在ram上面执行代码(相对Flash),所以ram既要放代码,也要存放数据,相对比较紧张,就会将内存空间重复使用。

嵌入式系统当中往往使用绝对地址寻址,不采用相对地址,笔者这里以不带Linux操作系统得应用场景为例。所以如果需要这种重复利用内存空间,就需要确定一块重复利用得地址,然后加载到这块得代码都需要采用这块得地址来进行编译,即在链接脚本里面指定绝对地址。
在这里插入图片描述
以上图为例,有4个功能代码1-4,都需要运行到动态内存地址,则笔者需要将这4个地址都编译到同一个动态内存的地址,然后需要哪个函数的时候就将哪个函数搬到对应的地址,然后再跳转过去执行。

2、编译器armcc/armclang对overlay的支持

armcc/armclang编译器支持overlay,主要是链接脚本这块的支持,通常情况下,

  • 如果两个.o文件放到同一块地址,
  • 或者两个函数放到同一块地址,都会报错误
    如下:两个overlay区域有重叠,因为链接器的作业就是分配运行地址,当然不能重叠,否则该怎么放置代码和执行code呢?
LR_OVERLAY0 0x30000000  0x1000
{ER_OVERLAY0 0x2001E000    0x1000 {overlay0.o(BANK_SEC, +FIRST)overlay0.o(+RO)overlay0.o(.text)}
}LR_OVERLAY1 0x30001000  0x1000
{ER_OVERLAY1 0x2001E000   0x1000 {overlay1.o(BANK_SEC, +FIRST)overlay1.o(+RO)overlay1.o(.text)}
}LR_OVERLAY2 0x30002000  0x1000
{ER_OVERLAY2 0x2001E000   0x1000 {overlay2.o(BANK_SEC, +FIRST)overlay2.o(+RO)overlay2.o(.text)}
}
"AdvanceClock.sct", line 32 (column 17): Warning: L6329W: Pattern overlay0.o(RO) only matches removed unused sections.
"AdvanceClock.sct", line 33 (column 16): Warning: L6314W: No section matches pattern overlay0.o(.text).
"AdvanceClock.sct", line 42 (column 17): Warning: L6329W: Pattern overlay1.o(RO) only matches removed unused sections.
"AdvanceClock.sct", line 43 (column 16): Warning: L6314W: No section matches pattern overlay1.o(.text).
"AdvanceClock.sct", line 52 (column 17): Warning: L6329W: Pattern overlay2.o(RO) only matches removed unused sections.
"AdvanceClock.sct", line 53 (column 16): Warning: L6314W: No section matches pattern overlay2.o(.text).
Error: L6221E: Execution region ER_OVERLAY0 with Execution range [0x2001e000,0x2001e080) overlaps with Execution region ER_OVERLAY1 with Execution range [0x2001e000,0x2001e074).
Error: L6221E: Execution region ER_OVERLAY0 with Execution range [0x2001e000,0x2001e080) overlaps with Execution region ER_OVERLAY2 with Execution range [0x2001e000,0x2001e074).
Error: L6221E: Execution region ER_OVERLAY1 with Execution range [0x2001e000,0x2001e074) overlaps with Execution region ER_OVERLAY2 with Execution range [0x2001e000,0x2001e074).
Finished: 0 information, 6 warning and 3 error messages.
make: *** [out/AdvancedClock.axf] Error 1

为了让链接器识别这种情况,把相同的地址放置多个函数,就必须加一个关键字,笔者找到手册上面的关键字overlay。

如下面例子所述,只要在多个想要执行地址的域空间描述上面加上overlay的关键字,该错误就不会报,
在这里插入图片描述
笔者做了尝试果然是这样,

LR_OVERLAY0 0x30000000  0x1000
{ER_OVERLAY0 0x2001E000 OVERLAY   0x1000 { overlay0.o(OVERLAY_SEC, +FIRST)overlay0.o(+RO)overlay0.o(.text)}
}LR_OVERLAY1 0x30001000  0x1000
{ER_OVERLAY1 0x2001E000 OVERLAY  0x1000 {overlay1.o(OVERLAY_SEC, +FIRST)overlay1.o(+RO)overlay1.o(.text)}
}LR_OVERLAY2 0x30002000  0x1000
{ER_OVERLAY2 0x2001E000 OVERLAY  0x1000 {overlay2.o(OVERLAY_SEC, +FIRST)overlay2.o(+RO)overlay2.o(.text)}
}

在这里插入图片描述
需要注意两点:
1、如果是独立设置加载域,则需要将入口函数声明为root属性,不然跳转的地址异常,可能跑飞等
2、保证函数声明为used,不然链接器会将overlay里面的函数stripped掉(删除掉),因为没有用到。
3、注意声明的OVERLAY 属性要放在执行域 长度属性的前面,不然会报错
4、因为笔者用的cm4架构,跳转的时候需要注意使用奇地址,不然可能会跑飞。

LR_OVERLAY0 0x30000000  0x1000
{ER_OVERLAY0 0x2001E000 OVERLAY   0x1000 { overlay0.o(+RO)overlay0.o(.text)}
}LR_OVERLAY1 0x30001000  0x1000
{ER_OVERLAY1 0x2001E000 OVERLAY  0x1000 {overlay1.o(+RO)overlay1.o(.text)}
}LR_OVERLAY2 0x30002000  0x1000
{ER_OVERLAY2 0x2001E000 OVERLAY  0x1000 {overlay2.o(+RO)overlay2.o(.text)}
}
overlay1函数实例,没有root属性,只有used属性。
__attribute__((used))  static  void overlay_handler(u8 overlay_id, u8 func_id)
{switch(func_id){case 1:{rt_kprintf("this is overlay func,overlay id=%d func id=%d\r\n", overlay_id, func_id);}break;default:rt_kprintf("this is overlay func,func id=%d,err\r\n", func_id);break;}
}

笔者尝试了如果不加root属性,则overlay1和overlay则会入口函数是编译器生成的code,会异常。
在这里插入图片描述
编译器生成的code如下:不是压栈所操作,入口地址变成了2001E00C,所以可能导致跑飞
在这里插入图片描述

正常的code应该如下所示:
在这里插入图片描述

如果不加used以及根区属性,则符号都没有被链接进来,因为overlay的函数本身需要运行态来决定运行哪个函数的,所以静态编译的时候编译器并不知道链接哪个,不过不指定used属性,则就会全部strpped掉。

 static  void overlay_handler(u8 overlay_id, u8 func_id)
{switch(func_id){case 2:{rt_kprintf("this is overlay func,overlay id=%d func id=%d\r\n", overlay_id, func_id);}break;default:rt_kprintf("this is overlay func,func id=%d,err\r\n", func_id);break;}
}

在这里插入图片描述
如果overlay属性位置放错,就会报如下错误。

"AdvanceClock.sct", line 29 (column 36): Error: L6228E: Expected '{', found 'O...'.
"AdvanceClock.sct", line 29 (column 36): Error: L6228E: Expected '}', found 'EOF'.
Not enough information to list the image map.
Finished: 1 information, 0 warning and 2 error messages.
make: *** [out/AdvancedClock.axf] Error 1

关于链接脚本的其他关于overlay的写法如下图所示:

  • region1 不是overlay属性,则region2的地址是region1地址的末地址
  • region1 是overlay属性,且offset是0,则region2和region1的地址一样
  • region1 是overlay属性,且offset不是0,则region2是region1末地址+offset
    在这里插入图片描述
    跳转的时候使用奇地址,不然会报错,因为cm4使用thumb指令,
overlay_handler_fun overlay_handler_func = (overlay_handler_fun)(overlay_EXEC_ADDR+1);

在这里插入图片描述

笔者写了一个参考例子如下:
overlay manager:
set_overlay_id,会请求切换当前的bank,
overlay_process,会处理当前的请求,并执行函数。

#include "main.h"#define overlay_EXEC_ADDR 0x2001E000#define overlay0_SAVE_ADDR  0x08020000
#define overlay1_SAVE_ADDR  0x08020400
#define overlay2_SAVE_ADDR  0x08020800
#define overlay_FLASH_BASE  overlay0_SAVE_ADDRtypedef void (*overlay_handler_fun)(u8 overlay_id,u8 func_id);u8 current_overlay_id_g = 0;
u8 set_overlay_id_g = 0;
void overlay_init()
{u32 current_overlay_flash_addr = overlay_FLASH_BASE + current_overlay_id_g*0x400;STMFLASH_Read(current_overlay_flash_addr, (u32*)overlay_EXEC_ADDR, 0x400);overlay_handler_fun overlay_handler_func = (overlay_handler_fun)(overlay_EXEC_ADDR+1);(*overlay_handler_func)(current_overlay_id_g, current_overlay_id_g);
}void set_overlay_id(u8 req_overlay_id)
{set_overlay_id_g = req_overlay_id;
}void overlay_process()
{if(set_overlay_id_g != current_overlay_id_g){current_overlay_id_g = set_overlay_id_g;u32 current_overlay_flash_addr = overlay_FLASH_BASE + current_overlay_id_g*0x400;STMFLASH_Read(current_overlay_flash_addr, (u32*)overlay_EXEC_ADDR, 0x400);overlay_handler_fun overlay_handler_func = (overlay_handler_fun)(overlay_EXEC_ADDR+1);(*overlay_handler_func)(current_overlay_id_g, current_overlay_id_g);}
}
#include "main.h"overlay0.c
__attribute__((section("overlay_SEC"),used))  static void overlay_handler(u8 overlay_id, u8 func_id)
{switch(func_id){case 0:{rt_kprintf("this is overlay func,overlay id=%d func id=%d\r\n", overlay_id, func_id);}break;default:rt_kprintf("this is overlay func,func id=%d,err\r\n", func_id);break;}
}
overlay1.c
__attribute__((section("overlay_SEC"),used))  static  void overlay_handler(u8 overlay_id, u8 func_id)
{switch(func_id){case 1:{rt_kprintf("this is overlay func,overlay id=%d func id=%d\r\n", overlay_id, func_id);}break;default:rt_kprintf("this is overlay func,func id=%d,err\r\n", func_id);break;}
}
overlay2.c__attribute__((section("overlay_SEC"),used)) static  void overlay_handler(u8 overlay_id, u8 func_id)
{switch(func_id){case 2:{rt_kprintf("this is overlay func,overlay id=%d func id=%d\r\n", overlay_id, func_id);}break;default:rt_kprintf("this is overlay func,func id=%d,err\r\n", func_id);break;}
}

实际效果如下:
在这里插入图片描述
在这里插入图片描述
如果有Trace32调试器,可以通过Trace32对overlay的支持来进行调试。
trace32 设置指令:

  1. system.option.ovarlay ON
  2. symbol.overlay.AUTOID 自动识别ID
  3. symbol.overlay.list 查看当前处于哪个overlay
    由下图可以可以看到笔者的overlay 处于overlay1,根据右边的打印,然后trace32调试器也显示的overlay1.
    在这里插入图片描述
    笔者切到overlay2,则对应的调试器显示overlay2。
    在这里插入图片描述

3、参考

armcc官方手册
DUI0472M_armcc_user_guide
DUI0474M_armlink_user_guide

相关文章:

ARM学习(31)编译器对overlay方式的支持

ARM学习(31)编译器对overlay方式的支持 1、overlay介绍 overlay:重叠得意思,就是可以重复利用得空间,一般在内存上使用这种空间。比如以Windows操作系统为例,其存储空间(ROM/FLASH)…...

【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常

问题现象 BeetISQL中间件版本:2.13.8.RELEASE 客户在调用BeetISQL提供的api向yashandb的表中执行batch insert并将返回sequence设置到传入的java bean时,报如下异常: 问题的风险及影响 影响业务流程正常执行,无法获得batch ins…...

软件测试——用例篇(上)

概念 什么是测试⽤例? 测试⽤例(Test Case)是为了实施测试⽽向被测试的系统提供的⼀组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素 设计测试⽤例原则⼀: 测试⽤例中⼀个必需部分是对…...

Flink中三种模式:YARN Session 模式、YARN Per-Job 模式和 YARN Application 模式提交任务命令

在 Apache Flink 中,YARN 提供了多种模式来提交和管理作业,每种模式都有其独特的特点和适用场景。主要有以下三种模式:YARN Session 模式、YARN Per-Job 模式和 YARN Application 模式。 1. YARN Session 模式 在 YARN Session 模式中,一个长时间运行的 Flink 会话(Sess…...

DBMS-1.2 关系运算

本文章的素材与知识均来自于李国良老师的数据库管理系统课程。 关系代数 一.基本关系代数运算 基本关系代数运算包括:选择、投影、并、差、笛卡尔积、重命名。 1.选择(select) 选择运算用于从关系R中获取满足条件的元组。 (1…...

Python——继承

一、继承 1. 什么是继承? 继承是一种面向对象编程的机制,允许一个类(子类)从另一个类(父类)继承属性和方法。子类可以扩展或修改父类的功能。 2. 如何实现继承? 在Python中,实现…...

程序员转型AI大模型好转吗?成功率高吗?

前言 在程序员圈子中,技术转型近年来一直是热门话题。随着AI技术的迅猛发展,优秀人才短缺,程序员向AI大模型转型似乎成为了一条通往职场先机的路径。但是,这条转型之路是否容易走,成功率又如何呢? 一、程…...

关于 Postman 这些你都知道吗?

Postman是接口测试工具,在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各种http请求,将请求的数据发送到服务端,获取对应的结果,从而测试接口是否能够满足业务功能要求,很直…...

ReentrantLock

ReentrantLock ReentrantLock 是一个可重入的互斥锁,它提供了比 synchronized 关键字更灵活的锁机制。它属于 java.util.concurrent.locks 包。 特点: 可重入性:同一个线程可以多次获取锁而不会造成死锁,锁的计数器会递增。公平…...

python | TypeError: list indices must be integers or slices, not tuple

python | TypeError: list indices must be integers or slices, not tuple 在Python编程中,TypeError: list indices must be integers or slices, not tuple 是一个常见的错误。此错误通常发生在尝试使用非整数(如元组)作为列表索引时。本…...

链码简介及MATLAB提取彩色图像链码

一、链码 链码(又称为freeman code)是一种通过带有给定方向的单位长度的线段序列来描述轮廓边界的方法,常被用来在图像处理、计算机图形学、模式识别等领域中表示曲线和区域边界。在二维图像中,链码可以表示为一系列的方向码,每个…...

二叉树,二叉查找树,平衡二叉树

一.绪论: 二.数据结构(二叉树): 1.简介: 1)每一个节点(也叫结点)都是一个独立的对象-->当中不仅要存数据值,还要存父节点地址值,左子节点地址值,右子 节点地址值 2)没有父节点或者子节点的节点就记为null 2.遍历方…...

《零散知识点 · SpringBoot 整合邮件功能》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...

编程小白如何成为大神?大学新生的最佳入门攻略

目录 方向一:选择适合的编程语言 方向二:制定有效的学习计划 方向三:避免常见的学习陷阱 方向四:额外建议 编程已成为当代大学生的必备技能,但面对众多编程语言和学习资源,新生们常常感到迷茫。如何选择…...

使用 PyInstaller 和 Hook 文件打包 APK 解析工具

错误信息如下&#xff1a; Traceback (most recent call last):File "test.py", line 4, in <module>File "<frozen importlib._bootstrap>", line 991, in _find_and_loadFile "<frozen importlib._bootstrap>", line 975, …...

【分布式】分库分表知识点大全

为什么要分库分表 随着业务量的增加导致数据库中数据量的增加&#xff0c;可能拖慢查询的性能&#xff0c;影响业务的可用性&#xff1b;如果数据库采用读写分离&#xff0c;可能会导致从库的延迟较大&#xff0c;主库进行写操作后&#xff0c;从库因为延迟无法及时同步&#…...

FreeRTOS中的定时器:xTimerCreate ,xTimerStart ,xTimerStop

1. 创建定时器 定时器的创建使用 xTimerCreate 函数。该函数有以下参数&#xff1a; pcTimerName&#xff1a;定时器的名字&#xff0c;主要用于调试。xTimerPeriodInTicks&#xff1a;定时器的周期&#xff0c;以系统节拍计时。uxAutoReload&#xff1a;定时器是否自动重载。如…...

【网络安全】文件上传黑白名单及数组绕过技巧

不安全的文件上传&#xff08;Unsafe FileUpload&#xff09; 不安全的文件上传是指Web应用程序在处理用户上传的文件时&#xff0c;没有采取足够的安全措施&#xff0c;导致攻击者可能利用这些漏洞上传恶意文件&#xff0c;进而对服务器或用户造成危害。 目录 一、文件上传…...

4.2、存储管理-页式存储

页式存储和段氏存储会考 页式存储几乎必考&#xff0c;段氏存储可能会考 页式存储 页式存储是操作系统的一种存储管理方式。 因为我们的程序往往是远远大于内存的&#xff0c;所以程序在执行的时候&#xff0c;是不会一次性把所有内容都装入到内存中&#xff0c;它会把程序分…...

60个常见的 Linux 指令

常见60个Linux指令 1.ssh 登录到计算机主机2.ls 列出目录内容3.pwd 当前终端会话所在的完整路径4.cd 切换当前工作目录5.touch 创建空文件或更新文件的时间戳6.echo 终端输出文本或变量值7.nano 在终端中编辑文件8.vim 文本编辑器9.cat 查看、连接和创建文件10.shred 安全删除敏…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...