2024年1月2日发(作者:)

GEL概述

GEL(General Extension Language通用扩展语言)是一种类似于C语言的一种解释性语言,它可以创建GEL函数,以扩展CCS用途。GEL是C语言的一个子集,然而它不能声明主机变量,所有的变量必须在DSP程序中定义,存在于仿真/实际目标板中,唯一不在目标板上定义的标识符是 GEL函数及其参数。

GEL函数可在任何能键入C表达式的地方调用,既可以在任何可键入C表达式的对话框中调用,也可以在其他GEL函数中调用;但不支持递归。

在实际应用中,用户只需要要按照GEL的语法,建立GEL文件并将其加载到CCS中。加载GEL文件后,为GEL菜单增加新的功能选项,这给调试程序时自动测试以及用户自定义工作空间带来很大方便。注意:GEL对于硬件仿真环境是没有太大用处的,但在软件仿真环境下,GEL可以为用户产生一个虚拟的DSP硬件初始化环境。

1、在GEL菜单中添加GEL函数

在一个工程项目中,可以将常用的GEL函数添加到CCS的GEL菜单下,此时需要使用menuitem关键词在GEL菜单下创建一个新的下拉菜单列表(一级菜单),再使用hotmenu,dialog和slider等关键词,在该菜单项中添加新的菜单项(二级菜单)。

2、GEL文件的加载和卸载

对于包含一个或多个GEL函数的文件(.gel),编写好后,必须将其加载到CCS中才能调用GEL文件中的GEL函数。有两种加载GEL文件的方法:

② 选择File→Load GEL菜单项,从文件夹中选择GEL文件加载。

②在工程窗口中,右击GEL File文件夹,在弹出的快捷菜单中选择Load GEL,然后从文件夹中选择GEL文件加载。

GEL文件一旦加载,其中的GEL函数将一直驻留在内存中,直到将其卸载为止。当一个加载的GEL文件更改后,必须先将其卸载,然后再重新加载才能使更改生效。

GEL文件的卸载很简单,右击欲卸载的GEL文件名,从弹出的局势菜单中选择Remove就可以了。

从CCS启动是自动执行GEL函数。SETUP CCS时设置环境时设置了自动执行GEL函数,自动运行StartUp()函数,这样要求每个工程建立时都载入GEL文件。

CCS提供了一系列嵌入GEL的函数。使用这些函数,用户可以控制仿真/实际目标板的状态,访问存储器,并在输出窗口中显示结果。

使用CCSStudio Setup工具,可以为系统配置中的每一个处理器指定一个启动GEL文件。当CCSStudio启动时,GEL文件加载到PC机的内存中,如果定义了StartUp()函数则执行该函数。在CCSStudio(V2.3或更早的版本中),主机和目标板的初始化工作都在Startup()函数中执行。但是对于支持Connect/Disconnect的CCSStudio(V2.4 或之后的版

本,尤其3.1版本),这样的GEL文件有可能没有正确的执行,因为CCSStudio启动时和目标处理器是断开的。这个时候,当Startup()函数试图访问目标处理器时会出错。因此,V2.4或之后的版本,尤其3.1版本CCS启动时候,一个新的回调函数OnTargetConnect()来执行目标处理器的初始化工作。

3、 GEL回调函数

3.1 Startup()函数

如果指定的GEL文件中包含Startup()函数,当CCSStudio启动时执行Startup()函数。支持Connect/Disconnect的CCSStudio的启动时,Startup()函数中不包括访问目标处理器的代码,目标处理器由回调函数OnTargetConnect()来初始化。

推荐:

建立基本的CCSStudio内存映射关系(不需要访问目标处理器)

任何不需要访问目标处理器的基本初始化

不推荐:

Get_Reset()(该函数通过仿真器复位目标处理器)

通过GEL_BreakPtAdd()设置断点

GEL_TextOUT()和GET_OpenWindow(),因为StartUp()执行时CCSStudio的任何控制窗口还没有打开

不支持Connect/Disconnect的CCSStudio GEL文件中的StartUp()函数:

/* The StartUp() function is called each time CCS is started. */

/* Customize this function to perform desired initialization. */

StartUp()

{

setup_memory_map();

GEL_Reset(); /* Do not call in StartUp() with CCStudio v2.4 or higher */

init_emif(); /* Do not call in StartUp() with CCStudio v2.4 or higher */

}

支持Connect/Disconnect的CCSStudio GEL文件中的StartUp()函数:

/* The StartUp() function is called each time CCS is started. */

/* Customize this function to perform desired initialization */

/* that will not access the target. */

StartUp()

{

setup_memory_map();

}

3.2 OnTargetConnect()函数

绝对最小的系统初始化处理,保证CCSStudio在目标处理器上处于一种可信赖的状态。例如:禁止看门狗时钟、DSP复位结束

每一次和目标处理器建立连接时都调用OnTargetConnect()函数。

/* OnTargetConnect() is called every time a target is connected.*/

/* Its execution finishes before anything else occurs. Customize*/

/* this function to perform essential target initialization. */

OnTargetConnect()

{

// place critical target initialization steps here

GEL_Reset();

init_emif();

}

对某些平台,必须调用GEL_Reset()函数使得CCSStudio处于一种“Good”状态,可以通过测试来确定是否需要调用GEL_Reset()函数。应该尽可能的降低GEL startup functions复杂度-包括减少GEL_Reset()的调用。

3.3 OnPreFileLoaded()函数

在加载program/symbol(.out)文件之前该回调函数执行。在该函数中执行另外的目标处理器初始化操作以保证程序可以加载和调试是一个好的选择。

/* This function is called automatically when the 'Load Program'*/

/* Menu item is selected. */

OnPreFileLoaded()

{

FlushCache();

IER = 0;

IFR = 0;

init_emif();

}

3.4 OnReset()函数

当目标处理器复位后该函数被调用。如果你需要每次重新启动程序设计了软复位,GEL_Restart()在此处调用。

/* This function is called automatically after a SW Reset has been executed.

OnReset(intnErrorCode)

{

init_emif();

}

3.5OnRestart()函数

当程序复位时调用该函数。

This function is called by CCS when you do Debug->Restart. The goal is to put

the C6x into a known good state with respect to cache, edma and interrupts. Failure

to do this can cause problems when you restart and run code multiple times.

OnRestart(intnErrorCode )

{

Turn off L2 for all EMIFA CE spaces. App should manage these for coherency

GEL_TextOut("Turn off cache segmentn");

*(int *)0x1848200 = 0; /* MAR0 */

*(int *)0x1848204 = 0; /* MAR1 */

*(int *)0x1848208 = 0; /* MAR2 */

*(int *)0x184820c = 0; /* MAR3 */

/* Disable EDMA events and interrupts and clear any pending events. */

GEL_TextOut("Disable EDMA eventn"); */

*(int *)0x01A0FFA8 = 0; /* CIERH */

*(int *)0x01A0FFB4 = 0; /* EERH */

*(int *)0x01A0FFB8 = 0XFFFFFFFF; /* ECRH */

*(int *)0x01A0FFE8 = 0; /* CIERL */

*(int *)0x01A0FFF4 = 0; /* EERL */

*(int *)0x01A0FFF8 = 0xFFFFFFFF; /* ECRL */

/* Disable other interrupts */

IER = 0;

IFR = 0;

}

4、存储器映射

CCSStudio存储器映射告诉调试器目标处理器的那些存储区域可以访问那些不能访问。CCSStudio存储器映射一般在StartUp()函数种执行。

4.1 、GEL_MapAdd()函数

该函数添加一个存储区域到存储区映射中。

4.2 、GEL_MapOn()和GEL_MapOff()函数

可以调用GEL_MapOn() or GEL_MapOff()来打开或关闭存储区映射。当存储区映射关闭时,CCSStudio假定可以访问所有的存储区空间。

4.3 、GEL_MapReset()函数

GEL_MapReset()函数清除所有的存储区映射。没有存储区映射时,缺省设置是所有的存储区空间都不能访问。

4.4、尽量避免使用GEL初始化

可以考虑在GEL文件中使用GEL_MapAdd()建立存储区映射以准许CCSStudio可以调试,但是不在GEL文件中执行外设设置例如:EMIF寄存器初始化、看门狗禁止。

因为GEL语法和C兼容,inif_emif()函数可以在.c文件中实现,和应用程序链接在一起。但是要注意以下几点:

使用“volatile”来保证变量不被优化。例如:

*(volatile int *)EMIFA_SDRAMTIM = 0x00000618; /* SDRAM timing (refresh) */

在编译调试过程中避免在GEL文件中进行外设设置,当到达了最终程序时,需要一个智能加载软件从FLASH或主机加载程序对EMIF进行设置,然后通过 (E)DMA或memcpy()拷贝程序/数据。

加载了GEL文件以后,并不一定所有的寄存器都是复位值,主程序中没有赋值的寄存器并不一定就是它的上电复位值,因为加上了仿真器,加载了GEL文件,起到了作用。

*.gel是你的秘书,可以帮你打杂

Gel文件用来处理一些繁琐的事情,例如我总是用Gel来自动初始化DSP系统,代码如下:

StartUp()

{

inti;

//setup_memory_map();

for(i=0; i<1000; i++) i=i;

GEL_Reset();

for(i=0; i<1000; i++) i=i;

init_emif();

for(i=0; i<1000; i++) i=i;

GEL_ProjectLoad( "D:");

for(i=0; i<10000; i++) i=i;

GEL_Load( "D:");

for(i=0; i<10000; i++) i=i;

GEL_Go( main);

}

只要打开CCS,它就会自动依次执行:系统软件复位、配置EMIF的各种寄存器、打开项目文件、装载项目文件,并且自动执行到MAIN(),停在那里等着你继续操作。

如果不用Gel,你就麻烦了。

GEL 文件的功能同 的功能基本相同,用于初始化DSP。但它的功能比emuinit

的功能有所增强,GEL 在CCS 下有一个菜单,可以根据DSP 的对象不同,设置不同的初始化程序。以TMS320LF2407 为例:

#define SCSR1 0x7018 ;定义scsr1 寄存器

#define SCSR2 0X7019 ;定义scsr2 寄存器

#defineWDKEY 0x7025 ;定义wdkey寄存器

#defineWDNTR 0x7029 ;定义wdntr寄存器

StartUp() ; 开始函数

{

GEL_MapReset(); ; 存储空间复

GEL_MapAdd(0x0000,0,0x7fff,1,1); 定义程序空间从0000-7fff可读写

GEL_MapAdd(0x8000,0,0x7000,1,1); 定义程序空间从8000-f000 可读写

GEL_MapAdd(0x0000,1,0x10000,1,1); 定义数据空间从0000-10000 可读写

GEL_MapAdd(0xffff,2,1,1,1); 定义i/o 空间0xffff 可读写

GEL_MapOn(); 存储空间打开

GEL_MemoryFill(0xffff,2,1,0x40); 在i/o 空间添入数值40h

*(int *)SCSR1=0x0200; 给scsr1 寄存器赋值

*(int *)SCSR2=0x000C; 给scsr2 寄存器赋值,在这里可以进行mp/mc 方式的转换

*(int *)WDNTR=0x006f; 给wdntr寄存器赋值

*(int *)WDKEY=0x055; 给wdkey寄存器赋值

*(int *)WDKEY=0x0AA; 给wdkey寄存器赋值

}

GEL文件只是在仿真器和目标系统上电的时候起到初始化DSP的作用。在上电后再改变GEL文件将不会对DSP产生影响,除非断电后再上电

贴上DSP5416的GEL文件

/* set PMST to: MP = OVLY = 1; DROM off, CLKOUT on */

#define PMST_VAL 0x0ffe0u

/* set wait-state control reg for: 2 w/s or more on i/o; one for ext memory */

#define SWWSR_VAL 0x2009u

/* set external-banks switch control for: no bank switching; BH set */

#define BSCR_VAL 0x02u

/* Set Default Reset Initialization Value */

#define ZEROS 0x0000u

这一部分是对寄存器初始化

/* Set Peripheral Control Register Addresses for DEV_RESET */

#define DMPREC 0x0054u

#define DMSA 0x0055u

#define DMSDI 0x0056u

#define DMA_CH0_DMFSC_SUB_ADDR 0x0003u

#define DMA_CH1_DMFSC_SUB_ADDR 0x0008u

#define DMA_CH2_DMFSC_SUB_ADDR 0x000Du

#define DMA_CH3_DMFSC_SUB_ADDR 0x0012u

#define DMA_CH4_DMFSC_SUB_ADDR 0x0017u

#define DMA_CH5_DMFSC_SUB_ADDR 0x001cu

#define MCBSP0_SPSA 0x0038u

#define MCBSP0_SPSD 0x0039u

#define MCBSP1_SPSA 0x0048u

#define MCBSP1_SPSD 0x0049u

#define MCBSP2_SPSA 0x0034u

#define MCBSP2_SPSD 0x0035u

#define MCBSP_SPCR1_SUB_ADDR 0x0000u

#define MCBSP_SPCR2_SUB_ADDR 0x0001u

#define MCBSP_SRGR1_SUB_ADDR 0x0006u

#define MCBSP_SRGR2_SUB_ADDR 0x0007u

#define MCBSP_MCR1_SUB_ADDR 0x0008u

#define MCBSP_MCR2_SUB_ADDR 0x0009u

#define SRGR1_INIT 0x0001u

#define PRD0 0x0025u

#define TCR0 0x0026u

#define PRD1 0x0031u

#define TCR1 0x0032u

#define TIMER_STOP 0x0010u

#define TIMER_RESET 0x0020u

#define PRD_DEFAULT 0xFFFFu

#define GPIOCR 0x0010u

StartUp()

{

C5416_Init();

GEL_TextOut("Gel StartUp complete.n");

}

menuitem "C5416_Configuration";

hotmenuCPU_Reset()

{

GEL_Reset();

PMST = PMST_VAL;

/* don't change the wait states, let the application code handle it */

/* note: at power up all wait states will be the maximum (7) */

/* SWWSR = SWWSR_VAL;

*/

BSCR = BSCR_VAL;

GEL_TextOut("CPU Reset Complete.n");

}

/* All memory maps are based on the PMST value of 0xFFE8 */

hotmenu C5416_Init()

{

GEL_Reset();

PMST = PMST_VAL;

/* don't change the wait states, let the application code handle it */

/* note: at power up all wait states will be the maximum (7) */

/* SWWSR = SWWSR_VAL; */

BSCR = BSCR_VAL;

C5416_Periph_Reset();

GEL_XMDef(0,0x1eu,1,0x8000u,0x7f);

GEL_XMOn();

GEL_MapOn();

GEL_MapReset();

GEL_MapAdd(0x80u,0,0x7F80u,1,1); /* DARAM */

GEL_MapAdd(0x08000u,0,0x8000u,1,1); /* External */

GEL_MapAdd(0x18000u,0,0x8000u,1,1); /* DARAM */

GEL_MapAdd(0x18000u,0,0x8000u,1,1); /* SARAM */

GEL_MapAdd(0x28000u,0,0x8000u,1,1); /* SARAM */

GEL_MapAdd(0x0u,1,0x60u,1,1); /* MMRs */

GEL_MapAdd(0x60u,1,0x7FA0u,1,1); /* DARAM */

GEL_MapAdd(0x08000u,1,0x8000u,1,1); /* DARAM */

GEL_TextOut("C5416_Init Complete.n"); }

/* ****************************** */

C5416_Periph_Reset()

{

IFR = 0xFFFFu;

IFR = 0x0000u;

DMA_Reset();

MCBSP0_Reset();

MCBSP1_Reset();

MCBSP2_Reset();

TIMER0_Reset();

GPIO_Reset();

}

DMA_Reset()

MCBSP0_Reset()

MCBSP1_Reset()

MCBSP2_Reset()

TIMER0_Reset()

GPIO_Reset()

在上面的各个初始化函数中,多半是把0值付给寄存器。当然这些初始化值如果用户不使用的话必须在主程序中做修改。

所以加载了GEL文件以后,并不一定所有的寄存器都是复位值,主程序中没有赋值的寄存器并不一定就是它的上电复位值,因为加上了仿真器,加载了GEL文件,起到了作用。