Position independent code and data (ROPI and RWPI)

本文介绍了IAR Embedded Workbench for ARM v5.50及更高版本中位置独立代码(ROPI)和位置独立数据(RWPI)的概念及其限制。通过使用特定编译选项,可以实现读写位置独立性,并提供了相关示例。

Introduction

IAR Embedded Workbench for ARM version 5.50 and later can optionally generate position-independent code and/or position-independent data.

Definition

  • ROPI = Read-Only Position Independence. This concerns everything that is readonly in the ELF output from the linker. Note that this includes const data and data initializers, i.e. typically everything that is put in FLASH.
  • RWPI = Read-Write Position Independence. This concerns everything that is readwrite in the ELF output from the linker.
  • In the present version there is also an option --pi_veneers (position independent veneers, see the Development Guide for further information)

Compiler options

The following description is an excerpt from the Development Guide:

  • Option: --ropi

    Use this option to make the compiler generate code that uses PC-relative references to address code and read-only data.

    When this option is used, these limitations apply:
    * C++ constructions cannot be used
    * The object attribute __ramfunc cannot be used
    * Pointer constants cannot be initialized with the address of another constant, a string literal, or a function. However, writable variables can be initialized to constant addresses at runtime.

    See also --no_rw_dynamic_init (below) and preprocessor symbol __ROPI__
     
  • Option: --rwpi

    Use this option to make the compiler generate code that uses the offset from the static base register (R9) to address-writable data.

    When this option is used, these limitations apply:
    * The object attribute __ramfunc cannot be used
    * Pointer constants cannot be initialized with the address of a writable variable.

    However, static writable variables can be initialized to writable variable addresses at runtime.
    See also --no_rw_dynamic_init (below) and preprocessor symbol __RWPI__
     
  • Option: --no_rw_dynamic_init

    Use this option to disable runtime initialization of static C variables. C source code that is compiled with --ropi or --rwpi cannot have static pointer variables and constants initialized to addresses of objects that do not have a known address at link time. To solve this for writable static variables, the compiler generates code that performs the initialization at program startup (in the same way as dynamic initialization in C++).

Example

In each project where ROPI/RWPI is needed, the application design and development and debugging environment will be unique. The number of different possible use cases and needs of position independent code/data are probably not possible to foresee.

It's difficult to create an exhaustive example that covers all aspects - anyway here is an example trying to show some basics of ROPI and RWPI.

Download the example and follow the instructions in readme.pdf about how to build and run. There is also a STM32F4 Discovery board example.

Note:

You will probably get build errors with newer version of IAR Embedded Workbench for ARM. The solution is to replace

static __global_reg char* rwpi_data @ "R9";

with

#if (__VER__ < 6020000)
static __global_reg char* rwpi_data @ "R9";
#else
static __no_init char* rwpi_data @ R9;
#endif

转载于:https://my.oschina.net/Jr413/blog/734178

<think>我们正在处理一个IAR编译错误,错误信息为:Error[Ta114] Option --no_literal_pool only valid for ARMv7 and ARMv6-M non-ROPI/RWPI。这个错误表明,用户在使用`--no_literal_pool`编译选项时,目标处理器架构不符合要求。 ### 错误原因分析 在IAR编译器中,`--no_literal_pool`选项用于控制是否禁止生成文字池(literal pool)。文字池是编译器用于存储常量数据(如浮点数、大整数等)的一块内存区域。该选项仅适用于特定的ARM架构版本: - ARMv7 - ARMv6-M(且非ROPI/RWPI模式) 如果用户的目标处理器不是上述架构之一,或者虽然目标处理器是ARMv6-M但使用了ROPI(Read-Only Position Independent)或RWPI(Read-Write Position Independent)模式,那么使用`--no_literal_pool`选项就会导致这个错误。 ### 解决方法 根据错误原因,我们可以采取以下步骤: 1. **检查目标处理器架构**: - 确认项目设置的处理器架构是否为ARMv7或ARMv6-M。如果不是,则不能使用`--no_literal_pool`选项。 - 在IAR Embedded Workbench中,可以通过项目选项(Project > Options)中的“General Options”>“Target”选项卡来查看和修改处理器架构。 2. **检查是否启用了ROPI/RWPI**: - 如果目标处理器是ARMv6-M,还需要检查是否启用了ROPIRWPI模式。在“General Options”>“Target”选项卡下的“Position Independence”设置区域,确保没有选择ROPIRWPI。 - 如果启用了ROPIRWPI,则不能使用`--no_literal_pool`选项。 3. **移除或替换编译选项**: - 如果目标处理器架构不符合要求,或者启用了ROPI/RWPI,那么需要移除`--no_literal_pool`选项。 - 在项目选项中的“C/C++ Compiler”>“Extra Options”或“Command Line”选项卡中,检查是否添加了`--no_literal_pool`选项,将其删除。 - 如果项目确实需要避免使用文字池(例如,为了优化性能或减少代码大小),可以考虑其他替代方案,例如使用`--literal_pool`选项(如果可用)或者调整代码以减少常量数据的使用。 4. **替代优化方法**: - 如果目标处理器是Cortex-M0/M0+(属于ARMv6-M架构),但项目启用了ROPI/RWPI,那么可能需要权衡是否必须使用ROPI/RWPI。如果不必要,可以关闭ROPI/RWPI以使用`--no_literal_pool`。 - 如果必须使用ROPI/RWPI,那么就不能使用`--no_literal_pool`,此时可以尝试其他优化选项,如`--optimize`调整优化级别,或者使用`--inline`控制内联函数等。 ### 示例步骤(IAR Embedded Workbench IDE) 1. 打开项目选项(右键点击项目 > Options)。 2. 选择“General Options”>“Target”选项卡: - 确认Device是否正确,并查看Core是否为ARMv7或ARMv6-M(如Cortex-M0/M0+)。 - 在“Position Independence”区域,确保ROPIRWPI都未勾选。 3. 选择“C/C++ Compiler”>“Extra Options”选项卡,检查是否有`--no_literal_pool`,如果有则删除。 4. 或者,在“C/C++ Compiler”>“List”选项卡中,可以查看实际使用的命令行,确认是否有该选项。 5. 重新编译项目。 ### 总结 该错误的根本原因是编译选项与目标架构不兼容。解决方法主要是调整目标架构设置或移除冲突的编译选项。在调整设置时,需要根据项目的实际需求来权衡。 §§相关问题§§ 1. 如何查看IAR项目中当前使用的编译选项? 2. 在ARM架构中,文字池(literal pool)的作用是什么? 3. ROPI/RWPI模式在ARM嵌入式开发中有什么作用? 4. 除了移除`--no_literal_pool`选项,还有哪些方法可以优化代码大小?</think>### IAR编译错误 `Error[Ta114]` 解决方法 #### 错误原因分析 该错误的核心是 **编译选项与目标架构不兼容**: 1. **`--no_literal_pool` 选项的限制**: - 该选项仅适用于特定 ARM 架构: - ARMv7(如 Cortex-M3/M4/M7) - ARMv6-M(如 Cortex-M0/M0+)**且未启用 ROPI/RWPI 模式** - 其他架构(如 ARMv7-M with ROPI/RWPI、ARMv8-M)或配置不满足条件时使用会触发此错误。 2. **ROPI/RWPI 模式冲突**: - ROPI(Read-Only Position Independence)和 RWPI(Read-Write Position Independence)是位置无关代码技术。 - 当项目启用 ROPI/RWPI 时,`--no_literal_pool` 与位置无关需求冲突,导致错误[^1]。 --- #### 解决步骤 ##### ✅ 方法1:移除不兼容选项(推荐) 1. 在 IAR 中打开项目选项: **Project > Options > C/C++ Compiler > Extra Options** 2. 删除 `--no_literal_pool` 或取消勾选其启用状态。 3. 重新编译项目。 ##### ✅ 方法2:调整目标架构(按需选用) - **情况1:目标为 ARMv6-M(如 Cortex-M0)且启用了 ROPI/RWPI** 在 **Project > Options > General Options > Target** 中: - 关闭 ROPI/RWPI 模式(取消勾选) - 或移除 `--no_literal_pool` 选项(优先推荐) - **情况2:目标非 ARMv7/ARMv6-M** 检查设备型号是否选择正确: - 路径:**Project > Options > General Options > Target > Device** - 确保选择兼容架构(如 Cortex-M3/M4 属于 ARMv7)。 ##### ✅ 方法3:替代优化方案 若需减少文字池(literal pool)使用: 1. 使用 `--literal_pool` 替代(自动管理) 2. 启用编译器优化: **Project > Options > C/C++ Compiler > Optimizations** 选择 **High** 或 **Balanced** 3. 减少全局常量:将大型常量数组移至函数内部(需权衡 RAM/ROM 占用)。 --- #### 配置验证示例 ```c // 测试代码(编译后观察文字池使用) const float DATA[] = {3.14, 1.618}; // 可能触发文字池 int main() { return (int)DATA[0]; } ``` - **正确配置**:无 `--no_literal_pool` 时编译通过 - **错误配置**:在 ARMv8-M 或 ROPI 模式下强制启用该选项时触发 Ta114 --- ### 相关问题 1. 如何检查 IAR 项目中的 ROPI/RWPI 设置状态? 2. ARMv7 与 ARMv6-M 架构在文字池处理上有何区别? 3. 位置无关代码(ROPI/RWPI)在嵌入式开发中有哪些应用场景? 4. IAR 编译器优化选项对代码大小和性能有何影响? [^1]: IAR C/C++ Development Guide, Section "ARM-specific compiler options".
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值