如何在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;

}

 

百度网盘地址 

 

posted @ 2020-05-14 21:58  STEVEN-SUN  阅读(1902)  评论(0编辑  收藏  举报