This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/LAUNCHTXL-F2.8069万M:从RAM移至Flash时出现问题

Guru**** 2558250 points
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/631065/ccs-launchxl-f28069m-problem-with-moving-from-ram-to-flash

部件号:LAUNCHTXL-F2.8069万M
主题中讨论的其他部件:controlSUITEC2000WARE

工具/软件:Code Composer Studio

您好,

最近我在Launchpad_XL上从事一个F2.8069万M微控制器的项目,现在我几乎完成了这个项目,我想在微控制器内闪存整个代码,那一刻我意识到我正面临一个超级复杂的问题! (至少我在论坛和文档中看到的内容,以及经过20个小时的工作,几乎没有找到解决方案后看到的内容)。

让我们从问题开始:

我编写了一个应用程序,它可以在某些线圈上保持电流固定,我使用DCL库中的PI控制器和F2.8069万的许多其他功能。 当我在RAM模式下通过调试器运行代码时,一切正常,我可以控制系统。 要将代码从RAM移动到闪存(或者更具技术 意义的是在 启动开始时将代码从闪存加载到RAM),我阅读了“spA 958 l ”,然后我看了示例代码, 但我遇到的问题是,我的代码在某些点被非法 ISR卡住,或者在进入功能时无法返回。 (我已根据ControlSuit中的闪存示例代码修改了链接程序文件)。


首先,我想知道如何在代码编写器中验证我是否正在将正确的内存部件/功能分配给RAM或闪存(在其中一个ControlSuit示例中推荐使用SDFlash实用程序,但它缺乏文档并且极其复杂)

其次,这是我的代码的一些部分:

在主程序中,在时钟初始化后,我有这部分代码用于复制存储器:

代码达到以下位置:

我可以将代码运行到“resetOffADU();”函数,然后代码进入非法ISR,当我评论此函数时,仍然在永远循环中,我再次陷入其他函数的计时等

 "resetOffADU():"函数只是简单的GPIO引脚设置。

这些也是 我收到的一些可疑警告:

 

这是我第一次遇到德州微控制器的问题,它非常复杂,而且没有适当和可靠的文档,如果 你能引导我找到解决方案,我将不胜感激。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    不确定您正在使用的controlSUITE版本(建议使用SDFlash)。 我建议您下载最新版本的c2000ware,并使用其中提供的链接程序命令文件作为起点。 至于您的问题“我想知道如何在代码编写器中验证我正在将正确的内存部件/功能分配给RAM或闪存”,如果您使用c2000ware中的链接程序命令文件,则它具有“标准”部分的所有正确分配。 对于任何用户定义的部分,是否在RAM或闪存中加载某个部分(或在闪存中加载该部分,但在引导时将其复制到RAM中)完全取决于您。

    至于警告,在代码中定义的某些部分在链接程序命令文件中没有分配。

    请查看以下帖子:
    RAM#83.9258万中的e2e.ti.com/.../83.9258万常量

    e2e.ti.com/.../18.6266万

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复,根据您的建议,我使用了C2000软件链接器命令。 通过继续测试,我意识到在某些函数中导致代码停止的主要原因是ADC ISR,我的意思是,每当我停用ADC ISR时,整个代码都能正常工作, 但是当我激活ADC ISR时,Forever循环中的代码就会卡在第一个函数中! (在闪存模式下,而不是RAM模式下)

    初始化闪存的步骤如下:

    1-定义闪存分配:

    #include "DSP28x_Project.h" //设备标题文件和示例包括文件
    #include "DCL.h"
    #include "string.h"
    
    
    //要从RAM运行的函数需要分配给
    //另一个部分。 然后,将使用
    //链接程序cmd文件映射此部分。
    //
    #pragma code_section (epwm1_isr,"ramfuncs");
    #pragma code_section (adc_isr,"ramfuncs");
    #pragma code_section (CPU_timer0_isr, "ramfuncs");
    //#pragma code_section (DCL_runpi,"ramfuncs");
    //这些由链接器定义(请参阅F2808.cmd)
    //
    extern UINT16 RamfuncsLoadStart;
    funn UINT16 RamfuncsLoadEnd;
    INTn UINT16 RamfuncsRunStart;
    Loadn U16 RamsSize; 

    2-激活中断和永久循环:

    void main (void){
    
    
    
    
    //将时间关键代码和闪存设置代码复制到RAM
    //这包括以下ISR功能:epwm1_timer_isr (),
    // epwm2_timer_isr(),epwm3_timer_isr和InitFlash();
    // RamfuncsLoadStart,RamfuncsLoadSize和RamfuncsRunStart
    //符号由链接器创建。 请参阅F2808.cmd文件。
    //
    memcpy (&RamfuncsRunStart,&RamfuncsLoadStart,(UINT32)&RamfuncsLoadSize);
    
    //步骤1。 初始化系统控制:
    // PLL,看门狗,启用外设时钟
    //此示例功能可在F2806x_sysctrl.c文件中找到。
    
    
    	InitSysCtrl();//
    
    
    步骤2. 初始化GPIO:
    //此示例函数可在F2806x_GPIO.c文件中找到,
    //说明了如何将GPIO设置为其默认状态。
    // InitGpio();//跳过此示例
    
    //对于此示例,只需初始化ePWM1,ePWM2,ePWM3的GPIO引脚
    //这些函数位于F2806X_ePWM.c文件
    	InitEPwm1Gpio()中;
    	//初始化GPIO
    	InitSciGpio();
    //步骤3中。 清除所有中断并初始化PIE矢量表:
    //禁用CPU中断
    	DINT;
    
    //将PIE控制寄存器初始化到其默认状态。
    //默认状态是禁用所有PIE中断,
    并清除标志//。
    //此函数位于F2806x_PIECTRL.c文件中。
    	InitPieCtrl();
    
    //禁用CPU中断并清除所有CPU中断标志:
    	IER = 0x0000;
    	IFR = 0x0000;
    
    //使用指向shell Interrupt
    // Service routines (ISR)的指针初始化PIE矢量表。
    //这将填充整个表,即使在此
    示例中未使用中断//。 这对于调试非常有用。
    // shell ISR例程可在F2806X_DefaultIsr.C.中找到
    //此函数可在F2806X_PieVect.C.中找到
    	本
    
    例中使用的InitPieVectorTable();//中断被重新映射到此
    文件中找到的// ISR函数。
    	EALLOW;
    	PieVectorTable.EPWM1_INT =&epwm1_ISR;		//epwm1中断
    	PieVectorTable.ADCINT1 =&ADC_ISR;			//ADC中断
    	PieVectorTable.TINT0 =&CPU_timer0_ISR;		/CPU计时器中断
    	PieIsVectTable.SCIS/FifeISVecaIS/=	
    	端头= 	
    	
    
    
    
    //
    //呼叫闪存初始化以设置闪存等待
    //此功能必须驻留在RAM中
    //
    InitFlash();
    
    //步骤4。 初始化所有设备外设:
    //此函数位于F2806x_InitPeripherals.c
    // InitPeripherals();//此示例不需要
    
    	InitAdc();		//初始化ADC
    	AdcOffsetSelfCal();
    	InitCpuTimers();	//init CPU计时器
    	scia_fifo_init();	//初始
    
    	化CPU定时器以配置每秒的SCI-A中断
    	// 90MHz CPU频率,周期(以uSeconds为单位),因此,正如它所提到的,它基于中断的周期,或者对于
    	//精确计时,延迟应除以2,以获得正确的计时。
    	ConfigCpuTimer(&CpuTimer0,90,1);
    	//要确保精确计时,请使用只写指令写入整个寄存器。 因此,如果
    	在ConfigCpuTimer和InitCpuTimers (在F2806x_CpuTimers.h中)中更改了任何//配置位,
    	也必须更新下面的//设置。
    	Cputimer0Regs.tcr.all = 0x4000;//使用只写指令设置TSS位= 0
    
    //在此示例中,仅初始化ePWM
    
    	EALLOW;
    	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    	EDIS;
    	//初
    	始化SysWM1时钟和频率****************EPWM1CLRC.= 0
    
    	
    	;sys****************************************= EPWREGL.CLNC.= 0;sys.CLNC.= 0; sys************************************************************EPWREGER.RWH.CLNC./EPW=
    	
    
    	艺发局******************************************************************************************* /
    	LoopCount = 0;
    	ConversionCount = 0;
    
    	//配置ADC
    	EALLOW;
    	AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;	//启用非重叠模式
    	AdcRegs.ADCCTL1.bit.ININTTPSEPOS = 1;// ADCINT1在AdcResults锁定后跳闸;ADC1RT1.ADCE1
    		
    		=已启用;ADC1CED1.IN1;ADCINTS1.INT1= ADCINIT1.IN1已启用ADCIN1;ADCINIT1已启用
    	//设置EOC1触发ADCINT1以触发
    	AdcRegs.ADCSO0CTL.bit.CHSEL = 4;//设置SOC0通道选择为ADCINA4
    	ADcRegs.ADCOC1CTL.bit.CHSEL = 2;//设置SOC1通道选择为ADCINA2 ADCRegs.ADCOC0CT1CT1T.CAST
    	
    	=第一个组/第一个组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组0组 //在EPWM1A上设置SOC1启动触发器,因为循环SOC0先转换SOC1
    	AdcRegs.ADCOC0CTL.bit.ACQPS =6;//将SOC0 S/H窗口设置为7 ADC时钟周期,(6 ACQPS加1) AdcRegs.ADCSO1CTL.Bit.ACQPS = 6
    	;/ACPS + 6时钟周期;
    	
    
    	//假定ePWM1时钟已在InitSysCtrl()中启用;
    	EPwm1Regs.ETSEL.bit.SOCAEN =1;		//在组
    	EPwm1Regs.ETSEL.bit.SOCASEL =4中启用		SOC;//在upcount
    	EPwm1Regs.ETPS.Bit.SORD ************************************************************************************************************************/CASEL =		1时生成SORD= 1个脉冲
    
    	/
    	/*______________________________ PI控制器初始化____________________________ ______
    	___________________________________________________________________________________________________________________________________________________________
    	
    	
    	
    	*/
    
    //步骤5。 用户特定代码,启用中断:
    //启用连接到EPWM1-3的CPU INT3 INT:
    	IER |= M_INT3;
    //在PIE中启用EPWM1 INTN:组3中断1-3
    	PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    
    	//在PIE
    	中启用ADCINT1 PIECtrlRegs.PIEIRx1 = 1; 	//在PIE中启用INT 1.1 (ADCINT1)
    
    	//在PIE中启用TINT0:组1中断7用于CPU计时器
    	PIeCtrlRegs.PIEER1.bit.INTx7 =1;
    
    	IER |= M_INT1;						//启用CPU中断1
    
    	//启用SCIa //PieCtrlRegs.PIER.1的中断
    	;	启用PIE.1位PIETRL
    	= PIE.1;启用PIETRL = PIE.1位。PIETRL = PIETRI。 // PIE组9,INT1
    	//PieCtrlRegs.PIEIER9.bit.INTx2 =1; // PIE Group 9, INT2
    	IER |= M_INT9;							//为SCIA
    
    
    	EINT启用CPU INT9;
    	//启用全局中断INTM
    	ERTM;
    	//启用全局实时中断DBGM
    
    	OffADU();
    //	Delay_US(200);
    	resetOnADU();
    
    
    /*/步骤6。 空闲循环。 只需坐下来永远循环(可选):
    EALLOW;
    gpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
    gpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
    EDIS;*/
    
    
    percpercDelay(delayT);
    
    	for (;;){
    
    		IF (operationStart){
    
    			IF (firstMoveFlag && initializationFlag){
    				firstMoveFlag =0;
    				//selfpositioning
    
    				coilatorActiv6 (selfPosDelay, selfPosCurrent);
    
    				coilActivator5 (selfPosDelay, selfPosiseCurrent);
    
    				coilActivator4 (selfPosDelay,selfPosCurrent);
    
    				coilActivator3 (selfPosDelay,selfPosCurrent);
    
    				coilActivator2 (selfPosDelay, selfposCurrent);
    
    				coilActivator1 (selfPosDelay,selfPosCurrent);
    
    				coilActivator1 (delayCS1,30.0);
    				coilActivator2 (delayCS2,30.0);
    				coilActivator3 (delayCS3,30.0);
    				coilActivator4 (delayCS4, 30.0);
    				coilActivator5 (delayCS5,30.0);
    				coilActivator6 (delayCS6,30.0);
    
    			}
    }
    

    然后ADC ISR将如下所示:

    __interrupt void ADC_ISR(void){//Voltage1[ConversionCount]
    
    	= AdcResult.ADCRESULT0;
    	Voltage2[ConversionCount]= AdcResult.ADCRESULT1;
    
    	IF (firstFlag)
    		sampleNo =5000;
    	否则{
    		firstFlag =0;
    		sampleNo =5; sampleNo =5;
    	
    	
    	如果已记录转换数=100= 0,则表示已开始转换
    		
    		数(I = 0 i <= sampleNo - 1;i++){
    			averageVoltage2 += Voltage2[i];
    		}//
    		在大小为10
    		averageVoltage2 /= sampleNo的窗口中求平均值;
    		//计算平均电压的实际值
    		Volage2 = 3.3 * averageVoltage2 / 4096.0 - voltageOffset;
    		如果(小于0)
    			
    
    		//通过电路的电流的实际值的计算
    		inputCurr=(averageVoltage2 - 0.0.0552万)/ 0.0.4928万 - currentOffset;
    		//RMS value
    		//inputCurrr*= 0.7 ;
    
    		if (inputCurr<0)
    			inputCurr= 0;
    
    		if (firstFlag){
    			firstFlag =0;
    			voltageOffset = averVoltage2; putConcurrentCount=0;
    			putConversion0
    		
    
    		
    	
    		
    
    	adcRegs.ADCINTFLGCLL.bit.ADCINT1 =1;//清除ADCINT1标志重新初始化下一个SOC
    	PieCtrlRegs.PIEACK/ALL = PIEACK_Group1;//确认中断到PIE
    
    	返回;
    } 

    另外值得一提的是,ADC由PWM中断触发,该中断包含使用数字控制器库的PI控制器内部:

    __interrupt void epwm1_isr (void){//
    	更新CMPA和CMBB值
    	//updateCompare(&epwm1_info);
    
    	//运行
    	UK的控制器= DCL_runPI(&pi1, rk, inputCurr);
    	x =(long)(UK);
    	z =(unsigned int);
    
    	//setting regypa.cmpa.cmpa.wpa.wpa.=基于输出的正确输出结果CMp.cmpa.cmpa.cmpa.wpa.cmpa.wpa.cmpa.wpa.cmpa.
    	
    	
    	//清除此计时器
    	的INT标志EPwm1Regs.ETCLR.bit.INT =1;
    
    	//确认此中断以接收来自组3
    	PieCtrlRegs.PIEACK.ALL = PIEACK_Group3;
    }的更多中断 

    因此,当我尝试逐行调试代码时,当ADC中断激活时,我陷入Forever循环中的第一个函数中,该函数只包含使用“CPU_timer0_isr”(而不是delay_us)编写的内部延迟。 我很确定该错误是由ADC功能引起的。 我还阅读 了以下 主题,但问题仍然存在。

    这是我在微控制器内闪存代码的第四天,我非常感谢任何帮助来解决这个问题。  
    此致

    米拉德

    void main (void){



      //将关键时间代码和闪存设置代码复制到RAM  //这包括以下ISR函数:epwm1_timer_isr(),  // epwm2_timer_isr(),epwm3_timer_isr和InitFlash();  // 链接  器创建RamfuncsLoadStart,RamfuncsSize和RamfuncsRunStart //符号。 请参阅F2808.cmd文件。   //  memcpy (&RamfuncsRunStart,&RamfuncsLoadStart,(UINT32)&RamfuncsLoadSize);
    //步骤1. 初始化系统控制:// PLL,看门狗,启用外设时钟//此示例函数可在F2806x_sysctrl.c文件中找到。

    InitSysCtrl();

    //步骤2. initalize GPIO://此示例函数可在F2806x_gPI.c文件中找到,//说明了如何将GPIO设置为其默认状态。// InitGpio(); //跳过此示例
    //在这种情况下,只需初始化ePWM1,ePWM2,ePWM3//这些函数位于F2806X_ePWM.c文件InitEPwm1Gpio()中;//初始化SCI GPIO InitSciGpio();//步骤3中。 清除所有中断并初始化PIE矢量表://禁用CPU中断DINT;
    //将PIE控制寄存器初始化到其默认状态。//默认状态是禁用所有PIE中断并清除标志//。//此函数位于F2806X_PIECTRL.c文件中。 InitPieCtrl();
    //禁用CPU中断并清除所有CPU中断标志:IER = 0x0000;IFR = 0x0000;
    //初始化PIE矢量表,该表带有指向shell InterrupT// Service例程(ISR)的指针。//这将填充整个表,即使在此示例中未使用interrupt //。  这对于调试非常有用。// shell ISR例程位于F2806X_DefaultIsr.c.//此函数位于F2806X_PieVect.C.中 InitPieVectorTable();
    //本示例中使用的中断被重新映射到此文件中找到的ISR函数。 EALLOW;PieVectorTable.EPWM1_INT =&epwm1_ISR;//epwm1中断PieVectorTable.ADCINT1 =&ADC_ISR;//ADC中断PieVectorTable.TINT0 =&CPU_timer0_ISR;/CPU计时器中断PieIsVectTable.SCIS/FifeISVecaIS/=端头=


      ////  调用闪存初始化以设置闪存等待//  此功能必须驻留在RAM  //  InitFlash()中;
    //步骤4. Initialize All the Device Peripherals://此函数位于F2806x_InitPeripherals.c// InitPeripherals()中 ,本示例不需要此函数
    InitAdc(); //init ADC AdcOffsetSelfCal();InitCpuTimers(); //init CPU计时器scia_fifo_init(); //初始化SCI-A
    //将CPU定时器0配置为每隔一微秒中断一次:// 90MHz CPU频率,周期(以uSeconds为单位),因此,正如它所提到的,它基于中断周期,或者对于//精确计时,延迟应除以2,以获得正确的计时。 ConfigCpuTimer(&CpuTimer0,90,1);//要确保精确计时,请使用只写指令写入整个寄存器。 因此,如果在ConfigCpuTimer和InitCpuTimers (在F2806x_CpuTimers.h中)中更改了任何//配置位,也必须更新下面的//设置。 CpuTimer0Regs.tcr.all = 0x4000;//使用只写指令设置TSS位=0
    //在此示例中,仅初始化ePWM
    EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC =0;EDIS;// EPWM1时钟和频率EPWM1init()的初始化;
    EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;EDIS;
    /*************************************** 艺发局******************************************************************************************* / LoopCount =0;ConversionCount =0;
    //配置ADC EALLOW;AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;//启用非重叠模式AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;// ADCINT1在AdcResults AdcRegs.INTSEL1N2.bit.ADC1.INTC1启用后跳闸    //将SOC0通道选择设置为ADCINA4 AdcRegs.ADCSO1CTL.bit.CHSEL =2;  //将SOC1通道选择设置为ADCINA2 AdcRegs.ADCSO0CTL.bit.TRIGSEL = 5;//在EPWM1A上设置SOC0启动触发器,因为循环SOC0,然后转换为ADC0。 //在EPWM1A上设置SOC1启动触发器,因为循环SOC0先转换SOC1 AdcRegs.ADCOC0CTL.bit.ACQPS =6;//将SOC0 S/H窗口设置为7 ADC时钟周期,(6 ACQPS加1) AdcRegs.ADCSO1CTL.Bit.ACQPS = 6;/ACPS + 6时钟周期;
    //假定ePWM1时钟已在InitSysCtrl()中启用;EPwm1Regs.ETSEL.bit.SOCAEN =1;//在组EPwm1Regs.ETSEL.bit.SOCASEL = 4中启用SOC;//在upcount EPwm1Regs.ETPS.bit.SORD= 1时从CMPA中选择SOC;生成1个脉冲/
    /************************************************************************************************ //*______________________________ PI控制器初始化____________________________ _________________________________________________________________________________________________________________________________________________________________ *///激活高侧门驱动器resetGPIOinit();//线圈选择器GPIO coilSelectorInitGPIO ()初始化;
    //步骤5. 用户特定代码,启用中断://启用连接到EPWM1-3的CPU INT3 INT:IER |= M_INT3;//在PIE中启用EPWM1 INTN:组3中断1-3 PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    //在PIECtrlRegs.PIEIER1.bit.INTx1 =1中启用ADCINT1;//在PIE中启用INT 1.1 (ADCINT1)
    //在PIE中启用TINT0:Group 1 interrupt 7 for CPU Timer PieCtrlRegs.PIEIER1.bit.INTx7=1;
    IER || M_INT1;//启用CPU中断1
    //启用SCIa的中断//PieCtrlRegs.PIECTRL.bit.ENPIE =1;  //启用PIE块PieCtrlRegs.PIEIER9.bit.INTx1 =1;   // PIE组9,INT1 //PieCtrlRegs.PIEIER9.bit.INT2 =1;   启用PIA_INIAC/组9= 9;启用PIA/ INIAC/组9

    EINT;//启用全局中断INTM ERTM;//启用全局实时中断DBGM
    resetOffADU();// delay_US(200);resetOnADU();

    /*//步骤6。 空闲循环。 只需坐并永久循环(可选):  EALLOW;  GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;  GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;  EDIS;*/

      perciseDelay(delayT);
    对于(;;){///}线圈必须始终以某种方式靠近地面,切勿让电路断路/////////////////////////////////// 以16Hz///////////////////////////////////////////////运行 如果(operationStart){
    如果(firstMoveFlag && initializationFlag){ firstMoveFlag =0;//selfPositioning
    coilActivator6 (selfPosDelay,selfPosCurrent);
    coilActivator5 (selfPosDelay,selfPosCurrent);
    coilActivator4 (selfPosDelay,selfPosCurrent);
    coilActivator3 (selfPosDelay,selfPosCurrent);
    coilActivator2 (selfPosDelay,selfPosCurrent);
    coilActivator1 (selfPosDelay,selfPosCurrent);
    //拍摄coilActivator1 (delayCS1,30.0);coilActivator2 (delayCS2,30.0);coilActivator3 (delayCS3, 30.0);coilActivator4 (delayCS4,30.0);coilActivator5 (delayCS5,30.0);coilActivator6 (delayCS6,30.0);
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果您已将ADC中断隔离为问题(从RAM运行时也是如此),则可以将ADC ISR降级并逐步添加代码以隔离问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的,但是当我从RAM运行时,没有问题,整个系统就像一个魅力, 但是当我移动到闪存时,ADC中断会被干扰,问题是我也在使用CPU timer0中断,所以我不确定在闪存时,我是否应该考虑一些修改(我指的是确认中断或类似中断的方式)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    您的应用程序适合RAM,您的工具链具有一个RTS库,它可以在调用main()函数之前复制RAM中的所有代码,就像在RAM模型中的调试器一样。 这样,您的代码应该像以前一样工作。

    请检查此项:

    Project右键单击/属性/构建/C2000编译器/高级选项/运行时模型选项/--ramfunc =开

    链接程序脚本片段:

    组
    {
    	.ti.ramfunc
    {
    	-l F021_API_CortexM3_LE.lib (.text)
    	}
    }	load = app_flash,
    		run = app_ram,
    		PALIGUN(0x10),
    		table (BINIT),
    		page =0
    
    binit:palign = 0x8,fill = 0xFF > app_flash 

    所有code_section pragma和memcpy都应该消失...

    此致,

    Janos

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢Janos非常有帮助的回复,  

    我尝试了您的方法,但当我修改F2.8069万M.cmd文件时,我遇到了一些错误。  

    我认为您共享的链接器命令文件的示例是针对另一个微控制器的,因此编译器无法识别它的某些部分。

    我从 您共享的链接中选择了更简单的部分,但我仍然收到错误。 在部分中,我应该放置什么而不是闪存和RAM??? 由于其他部分定义了不同的名称(如RAML0或等),因此代码段app_ram中的内容也没有在我的cmd文件中定义。 我已将我的cmd文件附加到此处。

    .TI.ramfunc :{} load=flash, run=ram, table(BINIT)
    
    binit :{}> flash 

    我收到的错误:


    e2e.ti.com/.../F2.8069万.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    基本上,链接程序尝试查找称为闪存和RAM的内存区域,但在附加到帖子的链接程序脚本中都找不到。

    我修复了链接器命令文件,请找到附件。

    此致,

    Janose2e.ti.com/.../3515.F28069.txt</s>2.8069万

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢Janos对您所做的修改,他们确实帮了我们很多。 我认为您的附件文件中有一个小错误,您将内存分配给我自己修改的以下部分:

    修改后,我没有收到错误,所以我所做的就是,我没有更改为RAM编写的C代码,我只是按照您的建议更改了链接程序命令文件, 现在,当我运行系统时,它似乎非常缓慢,我认为控制器运行不好。(PI控制器)

    我正在使用数字控制器库,根据该程序集文件,建议如下分配内存:

    dclfuncs			:> RAM,		page =0
    

    但即使在执行此操作后,系统运行缓慢,在微控制器上刷新.out文件后,并且在电源回收后,程序不会再次启动。 您对可能出现的问题有何看法? (我已附上新的cmd文件)e2e.ti.com/.../F2.8069万M.txt

    提前感谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    没错,我忘了在链接程序脚本中移动page-s。

    我还忘了说,如果你使用任何静态库,你必须为每个库切换--ramfunc=on。 如果它们是预编译的,则可以手动将部分移动到RAM中。

    关于性能问题,我觉得dclfuns是闪存,所以运行缓慢。 没有正确的初始化,闪存的性能相当差。 请尝试将dclfuns部分添加到binit组:

    组
    {
    	.ti.ramfunc
    	ramfuns
    	dclfuns.
    	{
    	}
    }加载=闪烁,
    运行= RAM,
    页面= 0,
    表(BIIT) 


    (请打开链接器映射文件生成,并确保所有内容都以RAM结束)。

    如果仍有问题,请在下一篇文章中附加链接器映射文件。

    此致,
    Janos
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    哇,完美,通过将dclfuns添加到binit组中,性能得到了提高,但它与RAM不同,我的意思是操作仍然比RAM慢,我检查了.map文件,似乎所有部分都已移至RAM,但为了您的评估,我将其留在此处。  

    e2e.ti.com/.../mapFile.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    void InitFlash(void)
    {
    EALLOW;
    //启用Flash管道模式以提高
    //从Flash执行的代码的性能。
    FlashRegs.FOPT.bit.ENPIPE = 1;
    
    // 注意
    //在
    给定的CPU速率下,闪存操作//所需的最小等待时间必须由TI确定。
    //有关最新信息,请参阅数据表。
    
    //设置Flash
    FlashRegs.FBANKWAIT.Bit.PAGEWAIT =3;
    
    //设置Flash FlashRegs.FBANKWAIT.Bit.RANDOM Waitstate for the Flash FlashRegs.FBANKWAIT.BIT.RANDOM WAIT
    =3;
    
    //设置OTP
    FlashRegs.FOTPIT.BIT.OTPIT =5;
    
    //的等待状态 注意
    ://仅应使用这2个寄存器的默认值
    FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
    FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
    EDIS;
    
    //强制管道刷新,以确保在
    返回
    
    前写入//最后配置的寄存器。(ASM)#7; APRPT"|NOP
    

    您的代码可能仍在某处引用闪存代码。 调试器为您设置参数,这些参数可能会影响您所看到的速度差异。

    请尝试在main开头调用此函数:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    太棒了,它现在在闪存上也像一个魅力一样工作,非常感谢Janos,我将继续测试所有的功能。但它现在似乎是完美的。
    此致
    米拉德
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉,Janos再次回来,我对系统进行了全面测试,除了SCI单元发送和接收一些格式化的字符串,所有单元都运行良好。 奇怪的是,当我在代码编辑器内使用CCS调试器刷新微控制器时,第一次直到连接调试器时SCI装置也工作正常,当我重新接通电源并重置它时,除了SCI装置外,所有装置都工作正常。 您是否知道原因是什么? (地图文件已附加)

    此致

    米拉德

    e2e.ti.com/.../map.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的,我找到了原因,在电源回收后,我必须重置整个系统一次! 再次感谢
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在这职位后,我亦改善了闪光的表现,所以对于有兴趣跟进的人士,我推荐 这职位。