2011年4月2日 星期六

DIY - PIC:MPLAB C18 C 編譯器的虛擬指令 #pragma (四十九)

DIY - PICMPLAB C18 C 編譯器的虛擬指令 #pragma  (四十九)

ANSI C 標準提供了每個 C 語言獨特語法定義結構的方法,符合不同目標處理器的架構要求,可使用 pragma 虛擬指令完成的。在 MPLAB C18 的編譯器最常見的#pragma 虛擬指令是用在 PIC18XXXX 作為內存記憶體段。#pragma 虛擬指令會告知 MPLAB18 編譯 C 語言代碼下面是這個指令進入 ”code” 段的程序存儲器。代碼段是指在相關每個 PIC18XXXX 設備的鏈接腳本,指定程序存儲器領域並可以執行。

 
 progma 指令可以顯示並插入,可以如給出的示例那樣插入該虛擬指令,也可以在該虛擬指令後直接跟目標處理器 code 區中的某個位址,從而可以完全控制代碼在記憶體中的位置。一般情況下,#pragma 並不重要,但在某些應用中。例如為引導 (bootloader),這是非常重要的,需要有嚴格控制在指定的代碼區域將被執行的應用程序。
將代碼從另一種編譯器移植到 MPLAB C18 時,原編譯器的pragma 虛擬指令的操作必須被識別並轉換成 MPLAB C18 的類似虛擬指令。無法被 MPLAB C18 識別的 pragma 虛擬指令將被忽略,從而允許將代碼從一種架構移植到另一種架構,並且不會出現編譯錯誤。 理解原編譯器中 pragma 虛擬指令的功能以及新的目標架構是工程師的職責所在,以在不同的單片機之間有效移植代碼。
在為變數分配存儲空間時,另一種最常見的 pragma 虛擬指令是 pragma udata 在此聲明之後定義的未初始化變數將使用通用寄存器進行存儲。
這與為變數和指令位於相同存儲空間內的器件編寫 C 程式不同。 IC18XXXX 上,程式記憶體和檔寄存器記憶體有很大不同,因此,必須明確地區分資料記憶體和程序記憶體中的存儲區。
▼#pragma指令在MPLAB C18見下表

▼例: 指定未初始化變數位於資料記憶體中的用戶段
#pragma udata mybss
  int gi;

▼例: 將變數MABONGA 分配到資料記憶體中的地址0X100
#pragma idata myDataSection=0x100;
  int Mabonga = 1;

▼例: 指定將一個變數存放到程式記憶體中
#pragma romdata const_table
  const rom char my_const_array[10] = {0,1,2,3,4,5,6,7,8,9};

▼例: 將函數PRINTSTRING 分配到程式記憶體中的位址0X8000
#pragma code myTextSection=0x8000;
int PrintString(const char *s){...};

例:定義配置位元的狀態
#pragma config OSC = HS

▼例: 編譯器自動保護和恢復變數 VAR1 VAR2
#pragma interrupt isr0 save=var1, var2
  void isr0(void)
 {
  /* perform interrupt function here */
  }

例:中斷服務程式
//Always include this code, it’s necessary when using a bootloader

extern void _startup (void);
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800

void _reset (void)
{
_asm goto _startup _endasm
}
#pragma code

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
;
}
#pragma code

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
;
}
#pragma code
//End bootloader code

2011 04 02 天氣報告
氣溫:20.9 @ 23:00 
相對濕度:百分之80% 
天氣:天色良好

沒有留言:

張貼留言