嵌入式系统启动及初始化——关于#pragma指令的简要说明
扫描二维码
随时随地手机看文章
本文出自一本北京航空航天大学出版的书籍,仅供学习交流。
关于#pragma指令的简要说明
#pragma声明是基于单片机开发的特点而对标准C语法的一个扩充,对充分利用MCU内各类有限的资源起到不可或缺的关键作用。下面介绍几个最常用的#pragma声明。
(1)#pragma DATA_SEG
定义变量所处的数据段。其语法形式为:
#pragma DATA_SEG 名称
数据段名称可以自己任意命名,但习惯上有些约定的名称,其作用分别为:
DEFAULT—默认的数据段,在12系列的单片机的地址为0x100以上。一般的变量定义可以放在这一区域。
MY_ZEROPAGE—特指第0页数据段,地址范围0x00~0xFF,但实际用户可用的空间不到256字节,因为前面的一些地址空间已经分配给了片内寄存器。需要频繁或快速存取的变量应该指定放在这一特殊区域,特别是位变量。
数据段名称必须和prm文件中的数据段配置说明相关连才能真正发挥其定位作用。如果自己命名的数据段在prm文件中没有特别说明,那此数据段的性质等同于DEFAULT,否则可以使用自己在prm文件中定义的名称。
(2)#pragma CONST_SEG
定义一个常数数据段,必须和变量的conet修饰关键词配合使用。其语法形式为:
#pragma CONST_SEG 名称
该数据段下定义的所有数据将被放置在程序只读的ROM区。也就是MCU内的Flash程序空间区。常数段名称可以用户自由定义,但一般用DEFAULT,让链接器按可用的ROM区域自由分配常数位置。举例如下:
//这个const将会被放置在flash区中
#pragma CONST_SEG DEFAULT
const byte prjName = “This is a demo”;
const word version = 0x0301; //这个const将会被放置在flash区中
//没有const该常量将会被放置在RAM区中
#pragma CONST_SEG DEFAULT
word version = 0x0301;//没有const该常量将会被放置在RAM区中
//尽管有const但该常量将会被放置在RAM区中
#pragma DATA_SEG DEFAULT
const word version = 0x0301;//尽管有const但该常量将会被放置在RAM区中
在嵌入式系统中,程序与变量分别放在不同的物理介质中(程序在Flash中,变量在RAM中),常数最好也被设置在Flash中
(3)#pragma CODE_SEG
用以定义程序段并赋以特定的段名,语法形式如下:
#pragma CODE_SEG 名称
一般的程序设计是无需对代码段做特殊处理的。对于项目中所有的代码文件或库文件,链接器会在最后按程序模块出现的先后顺序挨个自动安排所有程序函数在内存中所处的实际位置,用户不必太关心某一个函数的具体位置。但某些特殊设计需要将不同部分的程序分别定位在不同的地址空间,例如实现程序代码下载自动更新。这样的设计需要把负责应用程序下载更新的驱动代码固定在一个保留区域内,而把一般的程序放置在另外一个区域以便在需要时整体擦除后更新。这时就需要用CODE_SEG来分别指明不同的程序段,还必须配合并利用prm文件对程序空间进行分配和指派。
(4)#pragma TRAP_SEG
用于定义一个函数为中断服务类型。此类型的函数编译器 在将C代码编译成汇编指令时 会在代码前后增加必须的现场保护和恢复汇编代码,同时函数的最后返回用汇编指令RTI而不是针对普通函数的RTS。例如:
#pragma TRAP_PROC
void SCI1_Int (void)
{
//定义SCI1的中断服务程序
}
注意用TRAP_PROC定义的中断服务函数的实际中断矢量地址必须通过prm文件指派。