DSP

F28377D学习系列(一)

2019-07-13 11:09发布

TI 提供的F2837xD的SysCtrl函数,该芯片是双核拥有两个CPU,具体的以后会阐述。 //########################################################################### //
// FILE:   F2837xD_SysCtrl.c
//
// TITLE:  F2837xD Device System Control Initialization & Support Functions.
//
// DESCRIPTION:
//
//         Example initialization of system resources.
//
//###########################################################################
// $TI Release: F2837xD Support Library v100 $
// $Release Date: Mon Dec  9 12:58:09 CST 2013 $
//###########################################################################



#include "F2837xD_Device.h"     // Headerfile Include File
#include "F2837xD_Examples.h"   // Examples Include File


// Functions that will be run from RAM need to be assigned to
// a different section.  This section will then be mapped to a load and
// run address using the linker cmd file.
//
//  *IMPORTANT*
//  IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION "ramfuncs"  FROM FLASH
//  TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM THROWING
//  AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE. 

//
#pragma CODE_SECTION(InitFlash, "ramfuncs");//将InitFlash函数存在ramfuncs中。


void InitSysCtrl(void)
{
    // Disable the watchdog
    DisableDog();


#ifdef _FLASH

// flash中将程序复制到RAM中,注意RamfuncsRunStart, RamfuncsLoadStart, RamfuncsLoadSize三个变量要与RAM.cmd文件中ramfuncs处的三个变量完全一致,并且这三个变量要进行全局变量申明     memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);


// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM在RAM中初始化

    InitFlash();
#endif

//复制ADC&晶振的标称值从TI的保留OTP到寄存器中。先使能时钟再调用函数#define Device_cal (void   (*)(void))0x000000 #ifdef CPU1
    EALLOW;
CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
//    (*Device_cal)();
CpuSysRegs.PCLKCR13.bit.ADC_A = 0;
CpuSysRegs.PCLKCR13.bit.ADC_B = 0;
CpuSysRegs.PCLKCR13.bit.ADC_C = 0;
CpuSysRegs.PCLKCR13.bit.ADC_D = 0;
    EDIS;


    // Initialize the PLL control: PLLCR and CLKINDIV
    // F28_PLLCR and F28_CLKINDIV are defined in F2837xD_Examples.h
   InitSysPll(XTAL_OSC,IMULT_20,FMULT_1,PLLCLK_BY_2); //PLLSYSCLK = 10Mhz(OSCCLK) * 40 (IMULT) * 1 (FMULT) /  2 (PLLCLK_BY_2)


   //Turn on all peripherals
InitPeripheralClocks();
#endif
} 看门狗定时器是一个独立于CPU的计数单元,如果不采用特定的指令周期地使看门狗定时器复位,看门狗定时器将会使系统复位。为了避免不必要的复位,要求用户软件周期的对看门狗定时器进行复位操作。如果不明原因使CPU中断程序,比如系统软件进入死循环或者CPU的程序运行到了不确定的程序空间,从而使系统不能正常的工作,则看门狗电路可产生一个复位信号使CPU复位,程序从系统软件的开始执行。看门狗可以监测软件和硬件的运行状态,提高系统的可靠性。 只有先写0x55再写0xAA才会使WECNTR(看门狗计数器)复位 void ServiceDog(void)
{
    EALLOW;
    WdRegs.WDKEY.bit.WDKEY = 0x0055;
    WdRegs.WDKEY.bit.WDKEY = 0x00AA;
    EDIS;
}//复位看门狗计数器

//---------------------------------------------------------------------------
// Example: InitFlash:
//---------------------------------------------------------------------------
// 初始化 Flash Control registers 注意:该函数必须在RAM中执行,如果在OTP/Flash中执行将有不可预知的结果 //InitSysPLL设置了PLLSYSCLK=OSCCLK x (SYSPLLMULT.IMULT + SYSPLLMULT.FMULT)/SYSCLKDIVSEL //InitPheralClocks()使能了所有的外设


1.#pragma CODE_SECTION(InitFlash, "ramfuncs") 解释:将InitFlash函数存在ramfuncs中。该语句功能是将InitFlash函数写入RAM中,因为InitFlash经常被调用,这样省得每次都从flash中写入RAM。如果还有经常反复调用的函数,也可自行添加类似语句,需注意#pragma CODE_SECTION (InitFlash, "ramfuncs") 应该写在函数Initflash()所在的C文件中,并且在函数之前声明;在CCS中,如果我们不指定变量的存放位置,编译器会自动给变量分配一个位置,但有的时候我们想要把变量放在一个特定的空间里,那应该怎么办呢?
CCS提供了以下两个指令:
#pragma CODE_SECTION#pragma DATA_SECTION,其中data_section是针对数据空间的,code_section是针对程序空间的。CODE_SECTION Pragma命令格式:#pragma CODE_SECTION (func, "section name")
为函数func分配一个段空间,且该空间不在
.text段(一般程序),段名为"section name。DATA_SECTION pragma命令格式:#pragma DATA_SECTION (symbol, "section name")。将数据对象symbol分配在不同于.bss(一般数据)的空间内,生成一个数据段,段名为"section name“.
例如:#pragma DATA_SECTION (AdcRegs,"AdcRegsFile");
           volatile struct ADC_REGS AdcRegs;
将一个结构体AdcRegs与F2812的外设AD转换寄存器相对应。使得对结构体的操作作用于寄存器。
没有调用InitFlash这个函数就不需要这个#pragma CODE_SECTION(InitFlash, "ramfuncs");
一般说来,初始化时,是需要初始化Flash的,所以是需要的。很多例程不过是没有调用的。
flash的初始化是需要在ram中运行,不能放在flash中运行。
由于在基于DSP的嵌入式系统开发中,存储资源特别是片内高速存储资源有限,在算法系统集成时Memory的管理对于提高整个系统的优化是非常重要的,这一方面影响数据的读取、搬移速度;另一方面还影响Cache(缓存)的命中率,下面分程序和数据两方面分析。
程序区:最大原则是将经常调度使用的算法模块放片内。为做到这点,TI的CCS中提供了#pragma CODE_SECTION,可以把需要单独控制存放的函数段从.text段中独立出来,从而在.cmd文件中对这些函数段进行单独物理地址映射。还可以使用程序动态的方式,将需要运行的代码段先调度进片内memory,如H.264/AVC中CAVLC和CABAC两个算法模块具有互斥性,因此可以将这两个算法模块放在片外而且对应于片内同一块运行区,在运行其中某一个算法模块之前,先将其调入片内,从而充分利用片内有限的高速存储区。程序区的管理考虑到一级程序Cache(L1 P)的命中率,最好将具有先后执行顺序的函数按地址先后顺序配置在程序空间中,同时对代码比较大的处理函数将其拆分成小函数。