如何在DSP20335的RAM中初始化PIE 向量表


如何從RAM中初始化PIE 中斷向量表 ?

答:系統上電時, 所有中斷向量PIE必須從FLASH復制到PIE_VECT 中 進行初始化。

PIE_VECT是CMD文件的塊,在數據空間中的起始地址是0X000D00,長度為256個字。

如下圖所示

 

 

 

 

上述的操作有很多方法實現,其中一個方法是

 

第一步 由上面可知PIE中斷向量表存儲在    0X0000 0D00~0X0000 0DFF 所在的256個字

為了使這段存儲器與中斷向量表對應 要進行以下工作 。

 

  1. 定義函數型指針變量

    一個函數在存儲器中要占據一定的存儲空間,這個空間的起始地址是用函數名表示的,稱為 函數的入口地址 。

    可以使用指針指向這個入口地址。

    並通過指針來調用這個函數

    這種指針變量稱為 函數型指針變量 其一般的形式為:

     

    數據類型標識符 (*指針變量名) ()

     

    例如 int ( * p) ( ) ;

    上式定義了指針p , p 指向的函數返回整型數據 ,

    注意:(*p)中的括弧不可缺少,標識p是先與*結合 表示是指針變量,。然后在與后面()結合,表示此指針指向函數。

    在TI提供的DSP2833x_PieVect.h 中 (DSP2833x_PieVect.h 包含在DSP2833x_Device.h 中 )

     

    在DSP2833X_PieVect.h 中定義了 PINT , 是指向中斷函數類型的指針變量,然后利用結構體 建立 中斷向量表 類型 PIE _VECT_TABLE

    (PIE_VECT_TABLE 只是建立的一個數據類型)

     

    Typedef interrupt void (*PINT) (void)

     

    在上面的語句中,定義了指針PINT 為指向interrupt 型函數 的指針類型。

    由於在使用interrupt時,函數應被定義成返回void ,而且無參數調用,

因此在(*PINT)的后面加上(void),表示PINT是指向函數的指針,且無參數調用。

在(*PINT)的前面加上interrupt void 表示 PINT 指向中斷函數。

 

 

 

 

這樣 在描述 PIE 中斷矢量表 的時候,可以定義如下結構

Struct PIE_VECT_TABLE()

{

PINT PIE1_RESERVED;

PINT PIE2_RESERVED;

PINT PIE3_RESERVED;

 

}

 

 

 

 

 

 

 

 

 

開頭

 

結尾

開頭 結尾 一共 128個 中斷函數

 

即 該結構體的元素 為函數指針類型,。 而PIE_VECT_TABLE 是一個結構類型,

結構類型中所有成員均為中斷函數的首地址(即指向中斷函數的指針)。因此

在定義其成員 如 PIE1_RESERVED 等時,要在其前面加上PINT 表示PIE1_RESERVED

是PINT 類型的變量,即指向中斷函數的指針。

 

至此 定義了一個 新的結構體數據類型 PIE_VECT_TABLE

並且聲明了 一個 變量 PieVectTable 數據類型是 PIE_VECT_TABLE

注意 這個聲明 是 引用性 聲明 加關鍵字extern 表示 它在別的地方 .C文件中被聲明和定義 ,。

 

extern struct PIE_VECT_TABLE PieVecTable

(2)定義PIE中斷向量表類型 變量 並分配地址

 

在 TI 提供的DSP2833X_Gllobal VaribleDefs.c 文件中定義了中斷向量表類型變量

PieVectTable , 並通過該變量定義 "在數據空間的段名"PieVectTableFile

 

#pragma DATA_SECTION( PieVectTable, "PieVectTableFile")

Struct PIE_VECT_TABLE PieVectTable;

如下圖所示

 

插入知識點 #pragma 的語法 :

#pragma CODE_SECTION(symbol ,"section name")

#pragma DATA_SECTION(symbol,"section name")

 

說明 :

(1)Symbol 是符號。可以實函數名。也可以實全局變量。Section name 使用戶自己定義的段名。

(2)CODE_SECTION 用來定義代碼段。 DATA_SECTION 用來定義數據段,

 

使用#pragma 需要注意

  1. 不能在函數體內 聲明 #pragma
  2. 必須在符號被定義和使用前 使用#pragma.

     

    例如: 將全局數組變量a[128]單獨編譯成一個新的段,取名為"mynewsect"

     

    #pragma DATA_SECTION (a,"mynewsect");

    Unsigned int a [128]

    Main()

    {

    ………..

    }

 

 

 

 

 

 

定義完了 PIE 中斷向量表類型的 變量    PieVectTable

並且把變量定義在段 "PieVectTableFile"

則下一步就是

在CMD文件中為中斷向量表 確定存儲空間

 

MEMORY

{

PAGE1 : /*Data Memory */

………

//PIE Vector Table

PIE_VECT : origin=0X000D00 , length =0x000100

………..

}

 

SECTIONS

{

 

PieVectTable: >PIE_VECT ,PAGE=1

 

}

 

綜上:

至此 我已經完成了一個重要的事情:

我在DSP2833X_PIEVECT.h 中 定義了 函數型指針變量

Typedef interrupt (*PINT) (void)

PINT 是指向函數的指針變量

然后我 定義了 結構體 新的數據類型 PIE_VECT_TABLE

里面的類型是 函數型指針變量 。

 

然后我在DSP2833X_GlobalVariableDefs.c

定義了 數據類型是 PIE_VECT_TABLE 的 變量 PieVectTable

在定義這個變量之前 用

#pragma DATA_SECTION(PieVectTable ,"PieVectTableFile")

 

這樣這個變量 編譯的時候生成的段 就是 "PieVectTable "

 

 

接下來 通過 CMD 文件 把這個生成的段 放進數據存儲空間 0X000D00起始地址開始的128個字中去 。 (重要)

 

通過memory 划分了存儲空間 PIE_VECT PIE_VECT 就是 以0X00D000為起始地址的128個字。

 

綜上 第一個階段已經完成

 

 

下面的第二個階段 是需要定義一個 常量 結構體 里面的成員全部是 PIE中斷函數的首地址 用const 關鍵字修飾

在DSP2833X_PieVect.c 中定義該 常量結構體

 

並且還要定義 void InitPieVectTable(void) 函數

 

 

 

 

 

 

在主函數中掉用 InitBoard () //InitBoard()中 有    InitPieVectTable();

 

 

InitBoard() 雖然是在DC_Config.c 里面定義的, 但是在DC_Types.h 中聲明了。

所以在main.c 文件里面 包含了頭文件DC_Types.h

所以直接可以拿過來用了。

 

 

 

 

 

 

 

 

 

說明 這樣就完成了 所有的中斷向量 從FLASH 中賦值到PIE_VECT 中進行初始化

PIE_VECT 是實際的硬件地址 起始地址為0X000D00 長度為256字

 

 

這個文章的標題叫做 如何從RAM中初始化PIE中斷向量表?

操作要求: 系統上電的時候,所有中斷向量的PIE必須從FLASH 復制到PIE_VECT進行初始化。 PIE_VECT 是CMD 文件中的塊。在數據塊中的起始地址是0X000D00,長度是256個字

方法: 首先定義一個 函數指針類型的變量

函數指針類型變量的定義方法:

數據類型標識符號 (* 指針變量名)(;)

Uint16 (*P)( ) // 則 P指向的函數 返回數據是整型

//P是指向函數的指針變量

 

定義了 一個 指向中斷函數的指針變量

Typedef interrupt void (*PINT) (void )

 

然后定義了一個結構體數據類型 結構體的成員名是 指向中斷函數的指針變量

Struct PIE_VECT_TABLE()

{

PINT PIE1_RESERVED

PINT PIE2_RESERVED

PINT PIE3_RESERVED

………

 

}

 

然后需要定義一個變量 這個變量經過編譯器產生的段 名稱是PieVectTableFile

 

#pragma DATA_SECTION (PieVectTable,"PieVectTableFile")

Struct PIE_VECT_TABLE PieVectTable ;

 

結構體數據類型 變量的 定義 格式

Struct 類型名稱 變量名稱

 

類型名稱是前面 用struct 定義的

例如類型名稱是PIE_VECT_TABLE

在頭文件 定義如下

Struct PIE_VECT_TABLE()

{

PINT PIE1_RESERVED

PINT PIE2_RESERVED

PINT PIE3_RESERVED

………

 

}

 

 

然后調用    CMD文件 把這個編譯器生成的段名 PieVectTableFile 通過SECTION

 

偽指令 放到 通過MEMORY 偽指令 定義的 PIE_VECT 空間中去 。

 

PIE_VECT空間就是 起始地址為0X0000D00 length =0x0000100

 

 

 

 

 

然后在DSP2833X_PieVect.c 中定義了 一個PIE_VECT_TABLE 類型的結構體

 

PIE_VECT_TABLE 結構體里面的成員都是 函數型指針變量

 

因為此時 成員名的函數指針變量都是確定的地址 是一個常數

 

所以用關鍵字const 修飾 ,

備注:const 通常用於定義常數表。    CCS在進行編譯的時候,會將這些常數放在.const段。並置於程序存儲空間 使用示例如下

Const int digts[]={0,1,2,3,4,5,6,7,8,9};

 

回歸正題

 

Const struct PIE_VECT_TABLE PieVectTableInit={

 

PIE_RESERVED,

PIE_RESERVED,

PIE_RESERVED,

…..

// Non-Peripheral Interrupts

INT13_ISR

INT14_ISR

……

 

 

}

 

注意上面的PIE_RESERVED 就是函數名。 是函數的首地址 是一個常量

在DSP2833X_DefaultIsr.c 中聲明定義

 

 

 

 

 

 

void * 就是無類型指針類型,他所指向的內存空間沒有被認為是某一種特定的類型。

 

(void *)0 把0強制轉換為 void *,

例如 (unsigned char *)j,意思是把j強制類型轉換為unsigned char *型

 

下來看

 

都需要先取出來 結構體的首地址。&PieVectTableInit;

然后在強制轉換為 指向無類型的指針變量。 (void*)&PieVectTableInit

 

注意 指針變量的賦值格式 :

 

先看一個例子:

 

 

 

 

 

 

 

 

void InitPieVectTable(void)

{

int16 i;

Uint32 *Source = (void *) &PieVectTableInit;

Uint32 *Dest = (void *) &PieVectTable;

 

EALLOW;

for(i=0; i < 128; i++) {

*Dest++ = *Source++;

}

EDIS;

}

 

百度網盤地址 

 


免責聲明!

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



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