C语言再学习24——__attribute__ (at())地址定位

前言:

为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。

在这里插入图片描述


1. __ attribute __((at)) 绝对定位

__ attribute __( at(绝对地址) )的作用:

(1)绝对定位到 Flash;

(2)绝对定位到 RAM。

__ attribute __ :用来指定变量或结构位域的特殊属性,关键字后的双括弧中的内容是属性说明;

at:用来设置变量的绝对地址,指定某个变量处于内存或 FLASH 里面的某个给定的地址。

1.1 定位到 FLASH

定位到 flash 中,常用于固化信息,例如:设备的出厂信息,FLASH 标记等;

const uint8_t usFlashInitVal[] __attribute__((at(0x00030000))) = {0x11,0x22,0x33,0x44,0x55,0x66};//定位在flash中,0x00030000开始的6个字节信息固定

1.2 定位到 RAM

常用于数据量较大的缓存,如:串口接收数据。也用于某个位置的特定变量。

uint8_t ucUsartRecvBuffer[USART_RECV_LEN] __attribute__ ((at(0x00025000)));	//接收缓冲,最大USART_RECV_LEN个字节,起始地址为 0x00025000

注:

  1. 绝对定位不能在函数中定义,局部变量是定义在栈区,栈区是自动分配、释放,不能定义为绝对地址,只能于函数外定义;

  2. 定义的长度不能超过栈或 Flash 的大小,否则导致栈、Flash 溢出。

1.3 测试

比如:在 0x08010000 的 flash 地址上固定写入数据,如下图:

在这里插入图片描述
如果不加 const 修饰,则定位到了 RAM 。

编译出来各部分文件大小:

在这里插入图片描述

打开编译出来二进制文件,如下图:

C语言再学习24——__attribute__ (at())地址定位_第1张图片
最后,我们来看一下加与不加 const uint8_t ucaSysFlashVal[] attribute((at(0x08010000))) =
{0x11, 0x22, 0x33, 0x44}; 的 map 表的区别:

原编译结束的 map 文件各部分文件大小:

C语言再学习24——__attribute__ (at())地址定位_第2张图片

添加定位代码后的 map 文件各部分的大小:

C语言再学习24——__attribute__ (at())地址定位_第3张图片
可以发现添加后,RO Data 的大小发生了变化,即定位后 FLASH 的空间占用加大,并且打开 bin 文件,可以发现中间部分由全 0 填充。


参考:

  1. C语言中__attribute__ ((at())绝对定位的应用
  2. STM32学习笔记之__attribute__ ((at())绝对定位分析
  3. MDK const U16__attribute__((at(0x0800E400)))RO-data统计特别大

你可能感兴趣的:(STM32学习笔记,C语言小记)