IAR編程環境 _no_init的問答


extern volatile BYTE sppRxStatus;

extern volatile BYTE sppTxStatus;

__no_init SPP_RX_STRUCT rxData @ "PM0_XDATA";

__no_init SPP_TX_STRUCT txData @ "PM0_XDATA";

大俠告訴我,后兩句是什么意思?_no_init在編程環境中是藍色的字。

@ 符號什么意思。

答案

@是指定地址,__no_init 是一個SEGMENT,是給LINKER用的,定義到不初始化的塊中去。
@就是指定地址,這個應該沒什么好說的了,大部分編譯器都這么用。你應該理解這個吧。
你定義全局變量的時候比如int char;  即使你沒有賦值給他,編譯器還是會給他一個初始化值0,編譯的時候編譯器把他分配到初始化為零的那個SEGMENG中去了。編譯器默認的有幾個塊,初始化為零的塊,初始化不為零的塊,和不初始化的塊,你可以定義自己的塊,如你的PM0_XDATA,這個就是你自己定義的一個塊,那你的這個塊是個什么屬性呢,就是,__no_init 屬性,有了這個屬性,編譯器只給你分配空間,不給你初始化。

 

 

回答2:今天在閱讀RF_Example_Code_v1.0中頭文件cc430x613x.h時發現了幾部分的疑問。
首先來看一下cc430x613x.h 中的3個#define的例子:

#define DEFC(name, address) __no_init volatile unsigned char name @ address;
#define DEFW(name, address) __no_init volatile unsigned short name @ address;
#define DEFCW(name, address) __no_init union 

struct 

    volatile unsigned char name##_L; 
    volatile unsigned char name##_H; 
}; 
volatile unsigned short   name; 
} @ address;

前面的兩個#define的用法是一樣的。首先我可以發現,在宏定義里面都有一個關鍵字__no_init。查看了《MSP430 IAR C/EC++ Compiler Reference Guide》內的IAR Language Extension Overview 可以發現,__no_init是IAR擴展語法里面的一個擴展關鍵字。作用是聲明一個non-volatile類型的內存地址(Support non-valotile memory)。
於是解決了__no_init的問題。
再者對@這個字符存在一定的疑問,於是上網查了查資料。雖然對於@這個字符的用法還是不是很明確,但是可以明確的是:
#define DEFC(name, address) __no_init volatile unsigned char name @ address;
#define DEFC(name, address) sfrb name = address;
這兩種定義是等價的,但是后者是基於匯編嵌入式編程的情況下才成立。也就是說“=”是MSP430匯編中數據分配偽指令中的一種。我們來看一下MSP430匯編的數據分配偽指令有哪些:

SET (VAR, ASSIGN) 賦予一個臨時值;
EQU (=) 在當前模塊中賦予一個永久的值;
DEFINE 定義一個整個文件中都有效的值;
sfrb 寄存器類型的字節;
sfrw 寄存器類型的字。

使用語法如下:
label SET expr
label EQU expr
label = expr
label DEFINE expr
[const] sfrb register = value
[const] sfrw register = value
其中,
label 定義一個標志符、
expr 標志符的值、
register 特殊功能寄存器、
value 特殊功能寄存器的值。

在下面的例子中使用了局部變量與全局變量,在模塊add1 中定義了符號value ,同樣在
模塊add2 中也定義了符號value,但它們表示兩個不同的量,都只在各自的模塊內部有效,
這是局部變量。而在模塊add1 中定義的locn 則為全局變量,在兩個模塊中表示同一個值。
NAME add1
locn DEFINE 100H
value EQU 77
MOV locn,R4
ADD #value,R4
ENDMOD

NAME add2
value EQU 88
MOV locn,R5
ADD #value,R5
END

很明顯,“=”也就是EQU,作用是:在當前模塊中賦予一個永久的值。
至此,
#define DEFCW(name, address) __no_init union 

struct 
{
    volatile unsigned char name##_L;
    volatile unsigned char name##_H;
};
volatile unsigned short   name;
} @ address;
這種定義也變得相對好理解。以上的這種定義只是多了一個union的定義,將一個16位的地址存儲空間分成2個8bits或者1個16位。可以實現字訪問,也可以實現字節訪問。以上定義是將一個無名的union與address聯系起來,使得訪問address對應的內存時,就像訪問union一樣。

那么對於下面的一些看起來貌似比較復雜的定義就相對比較好理解了:
#define RF1AIFCTL1_         (0x0F02u) 
DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)
#define RF1AIFIFG         RF1AIFCTL1_L 
#define RF1AIFIE          RF1AIFCTL1_H
可以發現,第一個宏定義,“RF1AIFCTL1_”在字符串的最后帶一個下划線,其實代表這只是一個地址。而通過宏擴展DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_),將會被擴展為: 
__no_init union 

struct 

    volatile unsigned char RF1AIFCTL1_L;
    volatile unsigned char RF1AIFCTL1_H; 
}; 
volatile unsigned short   RF1AIFCTL1;
} @ (0x0F02u);

關於@的用法,今天查閱了《MSP430 IAR C/EC++ Compiler Reference Guide》,找到了結果:
A variable that has been explicitly placed at an address, for example by using the compiler @ syntax, will be placed in either the DATA16_AC or the DATA16_AN segment.
從中可以看出,@是一種語法。那么它的作用很明顯就是將變量放置到對應的地址中。使用@,一個變量可以明確的制定一個存儲地址。

因此之前的宏定義就變得好理解了。
#define DEFC(name, address) __no_init volatile unsigned char name @ address;
就是將name變量存放在address地址中,那么如此一來就可以為每個寄存器進行命名了,也就是說可以實現每個寄存器對應一個或者多個變量。

至此頭文件中另外一個問題也迎刃而解:
#define RF1AIFCTL1_         (0x0F02u) 
DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)
#define RF1AIFIFG         RF1AIFCTL1_L 
#define RF1AIFIE          RF1AIFCTL1_H 
我們將DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)展開:
__no_init union
{
struct
{
    volatile unsigned char RF1AIFCTL1_L;
    volatile unsigned char RF1AIFCTL1_H;
}; 
volatile unsigned short   RF1AIFCTL1; 
} @ (0x0F02u);
那么可以知道,RF1AIFCTL1,RF1AIFCTL1_L,RF1AIFCTL1_H已經聲明成為一個變量,存放的地址分別是0x0F02u,0x0F02u+1,0x0F02u。因此接下來后面兩條宏定義就自然的解開了。

#define RF1AIFIFG         RF1AIFCTL1_L 
#define RF1AIFIE          RF1AIFCTL1_H
功能只是為變量RF1AIFCTL1_L,RF1AIFCTL1_H定義了另外的一種名字作為替換。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM