解读:定义一个常数数据段,必须和const修饰关键词配置使用。该定义下的所有数据将被放置在程序只读的ROM区,并且需要.prm文件配合使用
1)在testmode.c中出现这个用法
#pragma CONST_SEG ECUINFO
Volatile const INT8U FlashECUInfo[12] ={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0x05};
#pragma CONST_SEG DEFAULT
2)查看project.prm文件有如下定义:
SEGMENTS
ROM_ECUINFO = READ_ONLY 0xFE00 TO 0xFE1F;
END
PLACEMENT
ECUINFO INTO ROM_ECUINFO;
END
3)在源程序中将FlashECUInfo的12个字节数据放在CONST_SEG ECUINFO段,之后的程序放在default段。在prm中,分配ROM_ECUINFO段的地址0xFE00-0xFF1F。在编译时,把ECUINFO的数据放入ROM_ECUINFO。这样就实现源程序到实际物理地址的连接。
查看对应地址信息,和程序中一致:0FE00 FF FF FF FF FF FF FF FF FF FF 07 05 FF FF FF FF
1)在selfcheck.c中
#pragma CONST_SEG FLASH_CHK_SUM
volatile const INT16U FlashChksum[16] ={0x55fd,0x9ea8,0xab22,0xc800,0xa345,0xbaeb,0x7397,0x17d4, 0x1fa5,0x7ce0,0x9b71,0xfc00,0xfc00,0xfc00,0xfc00,0xfc80};
#pragma CONST_SEG DEFAULT
2)查看project.prm文件有如下定义:
SEGMENTS
ROM_4000 = READ_ONLY 0x4000 TO 0x401F;
END
PLACEMENT
FLASH_CHK_SUM INTO ROM_4000;
END
3)也就是将FlashChksum的16*2个字节数据放在FLASH_CHK_SUM段,之后的程序放在default。
解读:定义变量所处的数据段。数据段名称必须和prm 文件中的数据段配置说明相关连才能真正发挥其定位作用。如果你自己命名的数据段在prm 文件中没有特别说明,那此数据段的性质等同于“DEFAULT”。数据段的“属性”可以缺省,它主要的目的是告诉编译器此段数据可适用的寻址模式。不同的寻址模式所花的指令数量和运行时间都不同。并且需要.prm文件配合使用。
属性:READ_ONLY、READ_WRITE、NO_INIT。Flash只读区一定是READ_ONLY,可读写的RAM区可以READ_WRITE或NO_INIT,两个的区别是ANSI-C的初始化代码会把定位在READ_WRITE块中的所有全局和静态变量自动清零,但NO_INIT块中的变量不会被自动清零。只是复位时不清零,掉电还是会清零。
1)在StateflowVal.c文件中出现此用法
#pragma DATA_SEG INIT_RAM
uint8_T fsSoftResetInitNo = 1;
uint16_T fsSoftResetPosAct = 32768;
#pragma DATA_SEG DEFAULT
2)查看project.prm文件有如下定义:
SEGMENTS
SRAM = NO_INIT 0x3FC0 TO 0x3FFF;
END
PLACEMENT
INIT_RAM INTO SRAM;
END
3)也就是将2个变量的3个字节数据放在SRAM段,之后的数据放在default。查看对应地址信息,和程序中一致:
03FC0 7C 86 31
解读:定义程序段在非分页区域。
使用飞思卡尔经常的中断函数前要加#pragmaCODE_SEG __NEAR_SEG NON_BANKED
飞思卡尔16位单片机的中断向量时16位的,中断函数只有在非分页区域内才能被寻址到。单片机内部非分页区域大小有限,非中断函数一般在分页区域。
NEAR_SEG可以CPU直接寻址的地方,访问时耗费时间短,适用于中断函数,实时性高;FAR_SEG是放在分页区域的,CPU访问耗费时间多,适用于普通函数。
FLASH里非分页工作机制如下:FLASH一共为128K,一页是16K,那么应该有8页才是,但是实际只有6个分页。有2个非分页放在4000-7FFF,和C000-FFFF两个逻辑地址窗里。那么,当程序的寻址在64K之内(2^16=64K,16位机的寻址能力是64K)时,就不用分页了,直接使用那两个非分页的数据。实际上,3E页 3F页是可见的,其实他们就是那2个非分页的映射。因此,使用非分页FLASH,就不须设置PPAGE寄存器,直接使用逻辑地址即可。
NON_BANKED一般位于0xc000-0xffff区域,而这个区域是16位单片机cpu可以直接寻址的区域,那么中断函数放在NON_BANKED里,就可以把函数放在64K的寻址程序段中。这么一来,进中断就方便多了,效率也高很多(因为中断函数要求的就是实时性)...而 __NEAR_SEG告诉编译器函数放在固定页中,只有固定页中的函数才能访问其他页的数据,同时CODE_SEG定义了一个代码段。
在timer.c中的中断函数会加上这个
#pragma CODE_SEG __NEAR_SEG NON_BANKED//中断函数置于非分页段
……
#pragma CODE_SEG DEFAULT//后面的程序置于分页区
解读:自动检测芯片
在derivative.h中
#pragma LINK_INFO DERIVATIVE "mc9s12XXX"
是用来改变mcu的,有了这句就不用手工改了,软件自动修改,在工程里面点击change mcu,然后再查看一下该文件,后面的芯片就会变成新选的芯片,其他文件调用时就会自动改变相应的文件配置。
解读:用以控制编译信息的显示。一般情况下这些编译信息都是有用的,特别是告警和错误信息。但有时我们会按单片机的工作特性编写一些代码,但正常程序编写时这些代码会产生一些告警信息。
如果你不想每次都看见编译器给出的这一类信息,可以先确认这一信息的编号,然后用“#pragma MESSAGE”加上“DISABLE”关键词和信息号将它屏蔽。如果你想特别关注某类信息,可以用“ENABLE”让其永远显示出来。
在globalvariable.h中
#pragma MESSAGE DISABLE C1106