Keil AC5/Keil AC6/IAR指定数据绝对存储地址

2023-05-16

文章目录

  • 1 前言
  • 2 实现方法
  • 3 例子


1 前言

  编译过程中,指定数据绝对存储地址在实际项目中会经常使用到或者必须用到,这样使得项目实现某些功能可以非常灵活,常用的场景有:

  • IAP升级时候,中断向量表存储
    IAP升级,STM32F0系列Cortex-M0内核芯片,192字节中断向量表需存储在RAM起始地址(0x20000000)中

  • 在指定flash地址存储固件信息,用于查询固件信息,或者升级过程对固件进行校验
    —项目名称
    —项目唯一id号
    —版本号
    —编译时间
    —编译器版本


2 实现方法

  指定数据绝对存储地址,实现方法与编译器相关,不同编译器实现方式不一样;常用的有Keil、IAR、Gcc,Keil AC5和AC6版本编译器实现方法也不同。


  例如,定义一个u32变量data,存储起始地址在0x20010000上,不同编译器下实现如下。

  • Keil AC5编译器:
uint32_t data __attribute__((at(0x20010000)));
  • Keil AC6编译器:
uint32_t data _attribute__ ((section(".ARM.__at_0x20010000")));
  • IAR编译器:
#pragma location = 0x20010000
__no_init uint32_t data;
__root __no_init uint32_t data @0x20010000

__root:强制函数或者变量不被编译器优化;函数或者变量没有被任何函数引用的情况下,编译器可能会将其优化掉。

__no_init 强制不执行内存初始化动作;正常情况下,应用程序启动时,IAR将全部全局和静态变量初始化为0,__no_init声明的变量不会执行初始化。

“@”是IAR中的地址操作符,通过“@”或“#program location ”指令来把全局变量/静态变量/代码Text 存放到绝对存储地址空间上;即是“#pragma location = address” 等价于 “@ address”


3 例子

  以STM32为例,指定flash地址空间存储固件信息。

/* 固件信息 */
typedef struct __attribute__ ((packed)) project_info 
{
    char name[20];			/* 项目名称 */
    char id;				/* 项目ID */
    char ver_major;			/* 主版本号 */
    char ver_minor;			/* 次版本号 */
    char ver_revision;		/* 修订版本号 */
    char build_date[12];	/* 编译日期 */
    char build_time[10];	/* 编译时间 */
    /* todo : other info */
} project_info_t;

/* 声明指定存储地址 */
#define PROJECT_INFO_ADDR           0x08024000U

#if defined(__CC_ARM) || defined(__ARMCC_VERSION)   /* Keil */
#if defined ( __CC_ARM )    /* AC5 */
    #define __AT(__ADDR)    __attribute__ ((at(__ADDR), used))
#elif defined ( __ARMCC_VERSION )   /* AC6 */
    #define __AT(__ADDR)    __attribute__ ((section(".ARM.__at_" #__ADDR)))
#endif  /* __CC_ARM */
#define AT_ADDR(__ADDR)  __AT(__ADDR)
const project_info_t project_info AT_ADDR(PROJECT_INFO_ADDR) =
#elif defined(__ICCARM__)   /* IAR */
#define AT_ADDR(__ADDR)  __AT(__ADDR)
#pragma location = PROJECT_INFO_ADDR
__root const project_info_t project_info @PROJECT_INFO_ADDR =
#else
#error Not select compiler.
#endif  /* __CC_ARM || __ARMCC_VERSION */
{
    .name = "xxx",
    .id = 0xAA,
    .ver_major = 1,
    .ver_minor = 0,
    .ver_revision = 0,
    .build_date = __DATE__,	
    .build_time = __TIME__,
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Keil AC5/Keil AC6/IAR指定数据绝对存储地址 的相关文章

随机推荐

  • TypeError: iter() returned non-iterator of type

    在使用Python迭代器时出现错误 xff1a class Fibs def init self self a 61 0 self b 61 1 def next self self a self b 61 self b self a 43
  • 【Linux应用编程】一个异步信号处理引起死锁问题的思考

    文章目录 1 前言2 为什么会产生死锁2 1 死锁2 2 分析2 3 结论 3 避免死锁4 举一反三5 死锁例子代码6 参考文章 1 前言 最近在维护别人的代码时 xff0c 遇到一个线程死锁问题 xff0c 一番折腾 xff0c 最终定位
  • 【RT-Thread】SGM706独立看门狗软件包

    文章目录 1 简介1 1 目录结构1 2 许可证 2 芯片介绍3 支持情况4 使用说明4 1 依赖4 2 获取软件包4 3 初始化4 4 启动看门狗4 5 msh finsh测试查看设备注册通过msh启动看门狗 5 注意事项6 联系方式 1
  • 利用tldr工具再也不怕记不住Linux命令

    文章目录 1 前言2 tldr3 安装4 使用 1 前言 linux命令非常多 xff0c 少用的命令往往易忘记 xff0c 甚至常用的语法较为复杂的命令也不好记住 当然有些太复杂的命令也不需要死记硬背 xff0c 我们往往会借助man命令
  • C++中的二阶构造函数

    文章目录 1 前言2 二阶构造3 总结 1 前言 构造函数用于创建对象时对象成员的初始化 xff0c 如赋初值 申请内存 加载文件等 xff0c 即是自动完成对象的初始化任务 在C 43 43 语言中 xff0c 构造函数执行顺序是 xff
  • open函数簇与fopen函数簇区别和用法

    文章目录 1 前言2 open与fopen区别2 1 标准不同2 2 层次不同2 3 适用对象不同 xff08 返回值不同 xff09 2 4 缓冲区2 5 效率不同 3 使用方法3 1 open3 2 fopen 1 前言 linux系统
  • 基于STM32的OLED多级菜单GUI实现(简化版智能手表)

    前言 xff1a 本文的OLED多级菜单UI 为一个综合性的STM32小项目 xff0c 使用多传感器 与OLED显示屏 实现智能终端 的效果 项目中的多级菜单UI使用了较为常见的结构体索引法 去实现功能与功能之间的来回切换 xff0c 搭
  • 【RTD】铂电阻测温原理与具体方法

    文章目录 1 基本原理2 铂电阻2 1 铂电阻测温原理2 2 铂电阻类型和测量方法2 2 1 两线式铂电阻2 2 2 三线式铂电阻2 2 3 四线式铂电阻 3 小结 相关文章 xff1a RTD 铂电阻测温原理与具体方法 RTD AD779
  • 【RTD】AD7793三线式铂电阻PT100/PT1000应用

    文章目录 1 AD7793简介2 AD7793 三线式铂电阻测量2 1 阻值计算 3 小结 相关文章 xff1a RTD 铂电阻测温原理与具体方法 RTD AD7793三线式铂电阻PT100 PT1000应用 RTD AD7793四线式铂电
  • 【RTD】AD7793四线式铂电阻PT100/PT1000应用

    文章目录 1 前言2 AD7793 四线式铂电阻测量2 1 阻值计算 3 小结 1 前言 上一篇文章描述的是RTD驱动芯片AD7793特点 xff0c 以及其与三线式RTD连接使用方法 本文描述四线式RTD与AD7793的使用 相关文章 x
  • 【RTD】AD7793两线式铂电阻PT100/PT1000应用

    文章目录 1 前言2 AD7793 两线式铂电阻测量2 1 阻值计算 3 小结 1 前言 上一篇文章描述的是RTD驱动芯片AD7793与四线式RTD连接使用方法 本文描述两线式RTD与AD7793的使用 相关文章 xff1a RTD 铂电阻
  • 【RTD】AD7793驱动程序

    文章目录 1 前言2 AD7793驱动程序2 1 spi访问接口2 2 寄存器和常用配置值2 3 初始化2 4 原始数据获取2 5 阻值换算 3 使用4 完整工程代码 1 前言 前面文章主要描述AD7793分别与两线 三线 四线RTD连接电
  • 【RTD】二分法查找和分段线性插值算法在RTD中应用

    文章目录 1 前言2 二分法查找2 1 复杂度2 2 实现 3 分段线性插值4 RTD实例 1 前言 处理器通过RTD采集电路 xff08 芯片 xff09 精确获得当前RTD电阻值后 xff0c 再结合RTD与温度线性关系表 xff0c
  • 24系列EEPROM/FRAM通用驱动库移植到RT-Thread

    文章目录 1 前言2 接口实现2 1 i2c收发函数实现2 2 页写延时函数2 3 写保护函数2 4 设备注册 3 对接RT Thread设备驱动3 1 标准设备驱动接口3 2 注册到RT Thread3 3 导出到msh3 4 测试 4
  • 【RT-Thread】TCA9534 8位I/O扩展器驱动软件包

    文章目录 1 简介1 1 目录结构1 2 许可证 2 芯片介绍3 支持情况4 使用说明4 1 依赖4 2 获取软件包4 3 初始化4 4 访问设备4 5 msh finsh测试查看设备注册执行sample 5 代码仓库 1 简介 tca95
  • 【代码质量】RAII在C++编程中的必要性

    文章目录 1 前言2 什么是RAII3 为什么用RAII4 RAII应用5 小结 1 前言 C C 43 43 相比其他高级编程语言 xff0c 具有指针的概念 xff0c 指针即是内存地址 C C 43 43 可以通过指针来直接访问内存空
  • C++ RAII典型应用之lock_guard和unique_lock模板

    文章目录 1 前言2 lock guard3 lock guard使用4 unique lock5 相关文章 1 前言 常用的线程间同步 通信 xff08 IPC xff09 方式有锁 xff08 互斥锁 读写锁 自旋锁 xff09 屏障
  • 基于STM32的实时操作系统FreeRTOS移植教程(手动移植)

    前言 xff1a 此文为笔者FreeRTOS专栏 下的第一篇基础性教学文章 xff0c 其主要目的为 xff1a 帮助读者朋友快速搭建出属于自己的公版FreeRTOS系统 xff0c 实现后续在实时操作系统FreeRTOS上的开发与运用 操
  • 通过sysinfo获取Linux系统状态信息

    系统运行状态信息是我们关注的重点 xff0c 通过当前系统的输出信息 xff0c 如内存大小 进程数量 运行时间等 xff0c 以便分析CPU负载 软硬件资源占用情况 xff0c 确保系统高效和稳定 Linux系统中 xff0c 提供sys
  • Keil AC5/Keil AC6/IAR指定数据绝对存储地址

    文章目录 1 前言2 实现方法3 例子 1 前言 编译过程中 xff0c 指定数据绝对存储地址在实际项目中会经常使用到或者必须用到 xff0c 这样使得项目实现某些功能可以非常灵活 xff0c 常用的场景有 xff1a IAP升级时候 xf