应用C语言的 at 函数

平常很少接触单片机程序,都是系统的应用程序,windows 、linux下一些应用程序

 

C语言本身没啥问题,本身就跟C++风格接近,linux下很多代码也用c来实现

但基本上用不到一些特殊函数,例如 at 函数

 

先来了解下 at是干嘛用的

绝对定位,可以把变量或函数绝对定位到Flash中,或者定位到RAM

 

是一个功能比较底层的操作,往往要跟__attribute__ 一起使用。

例如:uint8_t byMemp[15000u] __attribute__((at(0xc1405208)))

就是说把 byMemp 强制定位到 0xc1405208 这个地址上面去。

如果仅仅是 uint8_t byMemp[15000u]; 那么意味着是堆栈里进行分配,对于单片机而言,一下子分配那么多,就要考虑是否不够用等情况

如果用at指令,就可以把地址定位到其他地方去,比如外部sdram上面,这样就不用占用内部的堆栈。

 

以上大概 可以说明 at 的作用了。

 

那么,再来看下map信息(不知道平时有没有关注过这个文件)用at过的地方map里面都能够看到具体信息:

 

 从map里也可以看到 byMemp  是被映射到 0xc1405208 这个地址上,大小也有显示

 

这些信息都是存放在

Image Symbol Table

这里的 Local Symbols 里面

 

 

 

问:如果连续at有重叠会怎么样?

例如:

uint8_t byMemp[15000u] __attribute__((at(0xc1405208)))

uint8_t byMempTest[15000u] __attribute__((at(0xc1405308)))

 

此时编译的时候,就会报错:

 

 这个报错很好理解

 

 

__attribute__( at(绝对地址) )的作用分两个,一个是绝对定位到Flash,另个一是绝对定位到RAM。
1、定位到flash中
一般用于固化的信息,如出厂设置的参数,上位机配置的参数,ID卡的ID号,flash标记等等

const u16 gFlashDefValue[512] __attribute__((at(0x0800F000))) = {0x1111,0x1111,0x1111,0x0111,0x0111,0x0111};//定位在flash中,其他flash补充为00const u16 gflashdata__attribute__((at(0x0800F000))) = 0xFFFF;

 
2、定位到RAM中
一般用于数据量比较大的缓存,如串口的接收缓存,再就是某个位置的特定变量

u8 USART2_RX_BUF[USART2_REC_LEN] __attribute__ ((at(0X20001000)));//接收缓冲,最大USART_REC_LEN个字节,起始地址为0X20001000.

注意:
1、绝对定位不能在函数中定义,局部变量是定义在栈区的,栈区由MDK自动分配、释放,不能定义为绝对地址,只能放在函数外定义。
2、定义的长度不能超过栈或Flash的大小,否则,造成栈、Flash溢出。
posted @ 2020-09-18 17:09  小刚学长  阅读(1152)  评论(0编辑  收藏  举报