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

news/2025/2/3 23:52:46/

文章目录

  • 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__,
};

http://www.ppmy.cn/news/427870.html

相关文章

keil MDK AC5向AC6迁移后如何重定向printf

从AC5向AC6迁移,已经有很多人给出了迁移的教程,AC6的编译速度着实非常有吸引力,我也尝试根据网上的教程从AC5向AC6迁移,但程序执行到printf的时候便会有问题。 有问题的重定向代码: /* ------------------通过重定向…

MDK5.33发布,AC6编译DSP库性能重大提升,相比上一版提升6%-50%(2020-11-17)

镜像下载:http://www.armbbs.cn/forum.php?modviewthread&tid96992 官方地址:https://armkeil.blob.core.windows.net/eval/MDK533.EXE更新的AC6.15相比上一代AC6.14性能重大提升。通过基础算术函数,复数运算,滤波&#xff0…

弧一致性Arc consistency算法(AC3, AC4, AC6, AC2001)整理

AC3:再判断一致性时,会对前面已判断过的再次判断 AC4:改进AC3,在初始化时会存储所有判断,在移除值后,不用进行constraint check,只需traversal S lists和update counter。在不牵扯约束具体内容…

IMXRT10xx MDK 编译器AC5 升级AC6

1.更换编译器为AC6 2.产生链接信息,可以gotodef 3.更改编译配置 4.修改分散加载文件(重点) 修改分散加载文件第一行 #!armclang --targetarm-arm-none-eabi -mcpucortex-m7 -E -x c 如果不修改会报如下错误 flexspi_nor_release\IMXR…

5G NR基于码本的上行传输

上行传输受基站DCI调度,UE收到DCI信息后,根据PMI信息选择相应的码本。 在3GPP TS 38.211 6.3.1.5节中,定义了不同天线端口数和不同传输层数情况下的可选码本。下面截取了单层2天线端口码本和双层两天线端口码本。 gNB在什么情况下为UE选择什…

C语言编译器 clang gcc AC5 AC6

clang简介 https://blog.csdn.net/momo0853/article/details/121040320?ops_request_misc%257B%2522request%255Fid%2522%253A%2522167342781216800215098421%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id167342781216800215098421&bi…

STM32CUBEMX生成KEIL工程后使用AC6(V6)编译加快速度

普通小工程直接选择AC6即可&#xff0c;但这种时候编译速度差距也不大。 当工程内加入ETH、LWIP后编译就会出错 根据错误找到cc.h文件 注释掉 //#define LWIP_TIMEVAL_PRIVATE 0 //#include <sys/time.h> 在lwip.h文件中添加#define __CC_ARM&#xff0c;如下图 再像第…

Keil MDK 编译器 AC5 和 AC6 优化选项重要内容和区别

关注、星标公众号&#xff0c;不错过精彩内容 整理&#xff1a;黄工 参考来源&#xff1a;Arm官网 使用过Keil MDK &#xff08;Arm Compiler 6&#xff09;编译器V6版本的读者应该发现了一个问题&#xff0c;V6版本速度比V5版本编译速度快很多。 &#xff08;说明&#xff1a;…