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/MSP432P401R:使用__attribute__((ramfunc))并缩短代码执行时间。

Guru**** 2589280 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/629377/ccs-msp432p401r-using-__attribute__-ramfunc-and-realizing-a-reduction-in-code-execution-time

部件号:MSP432P401R

工具/软件:Code Composer Studio

部件号:MPS432P401R (特别是第2版MSP432启动板)

7.2 :代码编辑器Studio v.0.0.0013万

Compilier:TI v 16.9 .4.LTS

有两个计算密集型函数,我需要从RAM中运行,以减少执行时间。

__attribute__(ramfunc) void Proj_BP2_Detection_Filter (RECEVIVE_APP *prx)

和 在Proj_BP2_Detection_Filter (RECEVIVE_APP *prx)中调用的函数

__attribute__((ramfunc)) void Biquad_section_bandpass (Int16 *Pio,biquad_section*PBQ)。

项目*。map文件指示

.ti.ramfunc
* 00000 0000ec5.8万 0000.0464万运行ADDR = 100.8218万
0000ec58 000003d45800.0003万d4 Proj_BP2_Detection_Filter.obj (.ti.ramfunc)
0000f02c 0.0004万 --孔--[填充=0 ]
0000f030 0000008c0.3亿8c Biquad_Section.obj (.ti.ramfunc)

远称蹦床

被叫方名称trampoline名称
被叫方地址tramp地址呼叫地址呼叫信息
-------- -------- ------------------- --------
Proj_BP2_Detection_Filter $Tramp$TT$S$Proj_BP2_Detection_Filter
100.8219万 0000d740 00006d6c000006d6c Proj_BP2_Receiver_Signal_Detect.obj (.text)

[1个蹦床]
[1次蹦床呼叫]

执行时间没有缩短。 帮助?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Scott,
    您能否确认您正在比较需要等待状态1的闪存和不需要等待状态的SRAM之间在48Mhz时的执行时间。

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

    我将在下面为您提供相关代码部分。

    我不确定这是否证实了这一假设。

    以下函数在main.c早期被调用,用于为两个闪存库设置48MHz时钟和1个等待状态。

    我不知道有任何特定的DriverLib调用为RAM执行设置零等待状态。 您能详细说明从RAM执行0等待状态所需的特定设置吗?

    布尔Proj_BP2_Receiver_Clock (void)
    {
    // BOOL bReturnVal;
    
    #ifdef MSP432WARE_CONFIGURATION
    
    //为HFXT外围设备/晶体使用配置引脚
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin (GPIO端口PJ,GPIO _PIN2 | GPIO _PIN3,GPIO主要模块功能);
    
    //显式设置外部时钟频率
    MAP_CS_setExternalClockSourceFrequency(3.2768万,48000000);</s>48000000
    //使用直流-直流转换器VCORE1允许48MHz操作,将MCU置于活动模式
    如果(!MAP_PCM_setPowerState (PCM_AM_DCC_VCORE1))
    {
    返回RSC_false;
    }
    MAP_PCM_enableRudeMode();
    
    //根据MSP432P401数据表的第31页,在48MHz,DCDC时允许等待状态为1
    MAP_FlashCTL_setWaitState(FLASH_BANK0, 1);
    MAP_FlashCTL_setWaitState(FLASH_Bank1, 1);
    //在非旁路模式下启动HFXT,超时
    如果(!MAP_CS_startHFXTWithTimeout(false,0x1万))
    {
    返回RSC_false;
    }
    
    //为活动模式时钟启用外围设备模块时钟请求
    MAP_CS_enableClockRequest ((CS_MCLK | CS_HSMCLK | CS_SMCLK));
    
    //初始化MCLK到HFXT,48MHz
    MAP_CS_initClockSignal (CS_MCLK,CS_HFXTCLK_SELECT,CS_CLock_diver_1);
    // MCLK是CPU时钟的来源
    
    //初始化HSMCLK至HFXT除以2,24MHz
    MAP_CS_initClockSignal (CS_HSMCLK,CS_HFXTCLK_SELECT,CS_CLock_diverer_2);
    // HSMCLK可能是某些外设的时钟源:ADC14
    
    //初始化SMCLK至HFXT除以4,12MHz
    MAP_CS_initClockSignal (CS_SMCLK,CS_HFXTCLK_SELECT,CS_CLock_diverer_4);
    // SMCLK可能是某些外设的时钟源:SPI,UART,计时器等
    
    //初始化BCLK至REFO,3.2768万 Hz
    MAP_CS_setReference振 荡器频率(CS_REFO_32kHz);
    MAP_CS_INITClockSignal (CS_BCLK,CS_REFCLK_SELECT,CS_CLock_DIAER_1);
    #endif
    
    返回RSC_TRUE;
    
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    否,SRAM执行中没有等待状态。 这可以确认您正在准确地比较闪存和SRAM,并且您应该会看到性能的提高。 让我再进一步探讨一下,看看在SRAM空间内进行调用是否会产生任何影响,以及代码如何对齐。

    Chris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    为了加快响应速度并使响应尽可能相关,我将为您提供其他代码段以及链接器命令文件。 

    //***********
    //链接器命令
    //***************

    --retain=flashMailbox memory { INTVECS (RX):原点= 0x0万,长度= 0x0.01万 APP_MAIN (RX):原点= 0x0.01万,长度= 0x0001EF00 NV1 (RX):原点= 0x0001F000,长度= 0x0.1万 更新 (Rx):原点= 0x2万,长度= 0x0001EF00 NV2 (RX):原点= 0x0003F000,长度= 0x0.1万 信息 (Rx):Origin = 0x20万,length = 0x0.4万 #ifdef __TI_Compiler_version__ #if __TI_Compiler_version__>= 1500.9万 别名 { SRAM_CODE (rwx):原始= 0x100万 SRAM_DATA (RW):原点= 0x2000万 } 长度= 0x1万 //从RAM运行代码的规定:总代码长度< 0x0.04万 //SRAM_VEC_table (rwx):原点= 0x2000万,长度= 0x0.01万 //SRAM_RESERVED (rwx):原点= 0x2000.01万,长度= 0x0.04万 //SRAM_DATA (RW):原点= 0x2000.05万,长度= 0x1万 - 0x0.05万 //SRAM_CODE_RESERVED (rwx):Origin = 0x100.01万,length = 0x0.04万 #else /*提示:如果用户要使用ram功能,请观察SRAM_CODE */ /*和SRAM_DATA存储器区域重叠。 您需要采取措施进行分离 */ /* RAM中代码的数据。 这仅对早于15.09 .0.STS.*/的编译器版本有效 SRAM_CODE (rwx):原始= 0x100万,长度= 0x1万 SRAM_DATA (RW):Origin = 0x2000万,length = 0x1万 #endif #endif }/* 以下命令行选项作为CCS项目的一部分进行设置。 */* 如果您使用命令行进行构建,或者出于某种原因希望*/* 在此处定义这些命令行,您可以根据需要取消注释并修改这些命令行。 */* 如果您使用CCS进行构建,最好 在CCS项目中进行任何此类*/*修改,而不要使用此文件。 */* */* 当计划使用printf()*/* 将调试输出输出到控制台窗口时,建议使用1024字节的堆大小。 */* */ /*--heap_size=0 */ /*--stack_size=1024 */ /*--library=rtsv7M4_T_le_eabi.lib */* 内存中的节分配*/ 节 { intvecs:> INTVECS text:> app_main //.code_romToram:run_start (cod_romToram_run_start),run_size (code_romToram_run_size)> app_main const:> app_main .cinit:> app_main Pinit:> app_main init_array: > app_main 二进制 :{}> app_main /*以下各节显示INFO闪存的使用情况 */ /* INFO闪存用于以下用途 */ /*设备特定用途: */ /*用于设备安全操作的闪存邮箱 */ .flashMailbox:>0x20万 /*用于设备识别和表征的TLV表 */ .tlvTable :> 0x20.1万 设备引导加载程序的/* BSL区域 */ .bslArea :> 0x20.2万 .vtable:> 0x2000万 //.sRAM_RESERVED:run_start(SRAM_RESORT_RUN_START)> SRAM_RESERVED //.sRAM_CODE_RESERVED:run_start (SRAM_CODE_RESERT_RUN_START)> SRAM_CODE_RESERVED 数据:> SRAM_DATA .bss:> SRAM_DATA sysmem:> SRAM_DATA stack:> SRAM_DATA (高) #ifdef __TI_Compiler_version__ #if __TI_Compiler_version__>= 1500.9万 .TI.ramfunc :{} load=app_main, run=sRAM_code, table(BINIT) #endif #endif }/* RTS的WDTCTL寄存器符号定义*/ WDTCTL_sym = 0x400.048万C;
    //***************
    // biquad部分
    //**********
    //===================================================================================================================
    //说明:Biquad数字过滤器(一次迭代)
    //函数声明没有传递的变量,因此它
    可以//从RAM中复制和运行。
    ////
    注意:这已针对带通应用进行了优化,即a0 == 1和b1 == 0。
    //		x2 = x1;
    //		x1 = x0;
    //		x0 =(float)*pio;
    //		y2 = y1;
    //		y1 = y0
    //		y0 = a0*(b0*x0 + B1*x1 + B2*x2)- A2*Y2 -A1*y1;////
    
    注:这已针对10位ADC和16位存储进行了优化。
    //注:通过允许截断与舍入//
    		*PIO =((Int16) PBQ->y0);
    ////
    ALERNATIVELY:
    //		*PIO = Math_RoundToInt16(Y0);
    //
    //////===========================================================
    #if 0
    #if __TI_Compiler_version__>= 1500.9万
    __attribute_((ramfunc))
    #endif
    #endif
    
    void Biquad_Section_bandpass(Int16 *PIo, biquad_section*PBQ)
    {//
    	输入偏移
    	PBQ->x2 = PBQ->x1;
    	PBQ->x1=
    	PBQ>y1
    
    	= PBQ>y1 = PBQ= PBQ>y1; PBQ>y1= PBQ>y1= PBQ= PBQ>y1= PBQ= PBQ>y1= PBQ= PBQ>y1= PBQ>y1= PBQ= PBQ= PBQ= PBQ>y1= PBQ= PBQ>y
    	
    	
    
    	//过滤器计算
    	// PBQ->y0 =(PBQ->a0 *((PBQ->b0 * PBQ->x0)+(PBQ->B1 * PBQ->x1)+(PBQ->B2 * PBQ->ix2))-(PBQ->A2 * PBQ->Y2)-(PBQ->B1 =
    	
    	优化的应用程序:PBQ/ E= Y1)注:
    	//+(PBQ->B1 * PBQ->x1)已被省略;
    	//注:已针对带通应用优化,即a0 == 1。
    	// PBQ->a0 *已被忽略;
    	PBQ->y0 =((PBQ->b0 * PBQ->x0)+(PBQ->B2 * PBQ->x2)-(PBQ->A2 * PBQ->Y2)-(PBQ->A1 * PBQ->Y1);
    
    #if 0*Pio=16
    	Round_Matter_Toq-
    	的相关部分(PBQ->PBQ>Matter_16)
    	//另外,由于ADC为10位,我们使用Int16存储过滤器结果
    	//我也用于溢出保护。
    	if (PBQ->y0 >=0)
    	{
    		*PIO =((Int16)(PBQ->y0 + 0.5);
    	}
    	else
    	{
    		*PIO =((Int16)(PBQ->y0- 0.5 })
    	
    #endif
    
    	//通过容差截断与舍入
    	* PIO =(((Int16) PBQ->y0);
    },进一步提高了速度
    
    

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

    //检测过滤器

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

    //===================================================================================================================
    //说明:
    ////
    X,Y,Z BPF (仅限基础)。
    // X,Y,Z RMS计算
    //===================================================
    #if 0
    #if __TI_Compiler_version__>= 1500.9万
    __attribute___((ramfunc)
    #endif
    #endif
    
    void Proj_BP2_Detection_Filter(RECEVIVE_APP *prx)
    {
    Word		wi;
    #if 0
    Word		WJ;
    
    DWORD		dwX_Sum;
    dword		dwY_Sum;
    DWORD		dwZ_Sum;
    #endif
    
    Int16		* PX_IO;
    Int16		*py_io;
    Int16		* PZ_IO;
    
    #IF 0
    浮点		FX_RMS;
    浮动		FY_RMS;
    float		fs_RMS;
    #endif
    
    	//初始化通道RMS过滤器
    prx->fx_RMS = 0;
    PRX->FY_RMS = 0;
    prx->fffs_rms = 0;
    
    	//初始化通道IO起点
    	px_io =&prx->x_rx[prx->wSpStart];
    py_io =&prx->Y_rx[prx->wSpStart];
    PZ_IO =&prx->Z_Rx[prx->wSpStart];
    
    	用于(wi = prx->wSpStart;wi < prx->wSpEnd;wi++)
    	{
    		Biquad_section_bandpass(PX_IO,&_X_F0_BPF_S0);
    		Bique_Section_bandpass(PX_IO, &_X_F0_BPF_S1);
    
    		Biquad_Section_bandpass (py_IO,&_Y_F0_BPF_S0);
    		Biquad_Section_bandpass (py_IO,&_Y_F0_BPF_S1);
    
    		Biquad_section_bandpass (PZ_IO,&_Z_F0_BPF_S0);
    		Biquad_Section_bandpass (PZ_IO,&_Z_F0_BPF_S1);
    
    #if 0
    		if ((wi >= prx->wRMS_valid_Index)&! wprwprx->wrMS_Interval_Sum w_wJ= w_Sum
    		
    			
    			wx; w_wJ= wJ_wJ_Sum wx; wx_wJ= wx_wx; wJ_wJ= wJ_wx_wx_wx_wx; wJ= wx; wJ= wx_wx_wx_wx_wx_wx_wJ= w_w_wx_w_wx; wJ= w_wx_w_
    			
    			
    
    			
    			
    				
    				dwY_Sum +=(prx->Y_Rx[WJ]* prx->Y_Rx[WJ]);
    				dwZ_Sum +=(prx->Z_Rx[WJ]* prx->Z_RMS[WJ]);
    			}//dwFX_RMS
    			
    			= sqrtf((float)X_Sum)
    			
    			
    
    			RMS =wfx_rfx_rfx;rfx=wrfx_rfx_rfx=)rfx=wrfx=wrfx_rfx_RMS =wfx=wfx=)rfx_rfx_rfx=wrfx=wrfx=wrfx=wrfx=wrfx=wrfx=wrf_rfx=wrfx_rfx_rfx=wrfx_rfx=wrfx=wrfx=wrf= 0.875 0.125
    			
    			PRX->FY_RMS =(0.875 * prx->FY_RMS)+(0.125 * FY_RMS);
    			prx->FZ_RMS =(0.875 * prx->FZ_RMS)+(0.125 * FZ_RMS);
    
    			//已过滤
    			
    			
    				
    			
    			
    			
    				
    			
    			
    			
    				
    			的门限值测试(prx->FX_RMS >最小值){prx->FX_Rrierx_RMS =正确=FZ_R=正确的R=正确的<RMSZ_RMS_RMS_RMS_RMS=正常的<=正常值={=正常值=========================================TRX_RM_RM_RM_RM_RM_RM_RM_RMX正常的
    
    #if 0//
    			!WIP在无信号条件下查找峰值以调整滤波系数
    			(prx->FX_RMS > prx->fXYZ_RMS)
    			{
    				prx->fXYZ_RMS = prx->FX_RMS;
    			}
    			IF (prx->RMS_RMS > prx->fXYZ_RMS)
    			{prx->fx_rs_RMS
    				= prx>fx_rs_RMS =fx_fx_fx_fx_fx_fx_fx_fx_fx_fx_fx=}{>
    			
    			
    			
    				
    			
    #endif
    		}//
    		内联"Math_RoundToInt16 (FRMS)"显著提高了速度。
    		//由于ADC是10位的,我们使用Word来存储结果,
    		//我也要进行溢出保护。
    		通过容差截断与舍入,可以进一步提高速度//。
    		//这也可以填补prx->wRMS_Interval
    		prx->X_RMS/wi]=(worth) prx->fx_RMS;
    		prx->y_RMS [wi]=(worth) prx->fx->fx_RMS);
    		prx->z_RMS [wi]=(worth) prx->enable_RMS /sync
    
    
    		
    		,如果有的话,还必须
    		检测出/fz+信号,要检测出一个/f/ f/信号,要检测到的运营商
    		
    	py_io++;
    	PZ_IO++;
    	}
    }
    
    

    此外,样例ISR可能会从RAM执行中受益

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

    // ISR示例

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

    //************************************************************************
    //	说明:
    //	此例程对时间非常重要。 IRQ间隔可能短至5用户。
    ////
    	清除TA3 CCR0捕获比较中断。
    //	读取XYZ
    //	增量索引
    //	触发ADC序列。
    //************************************************************************
    #IF 0
    //**************************************************************
    //	使用"ramfunc"属性将50 % 添加到ISR的执行时间
    //************************************************************************
    #if __TI_Compiler_version__>= 1500.9万
    __attribute_((ramfunc)
    #endif
    #endif
    
    void Proj_Dev_BP2_Receiver_TA3_CCR0_ISR(void){//***********************************************************************************************************************************
    
    	
    	//LED1_RED_ON();
    	//HWREG16 (((UINT32_t) P1 +((UINT32_t)&P1->输出-(UINT32_t) P1))|= LED1_RED_BIT;
    	//*******************************************************************************************
    
    #IF 0//***********************************************************************************************************
    	
    	// debug -检查ADC14 TOV或OV错误
    	,如果(ADC14->IFGR1和****************30)
    	{//
    		获取错误标志
    		_RECEIVE_App.dwdebug =(ADC14->IFGR1和0x0.003万);
    		ADC14->CLRIFGR1 = 0x0.003万;//
    		计数错误
    		标志_RECEIVE_App.werror_cnf+/
    	********************************************************************************/*******************************************
    
    
    	
    	//map_timer_a_clearCaptureCompareInterrupt (timer_a3_base,timer_a_CAPTURMPare_register_0);
    	////idx
    	=(timer_a_CAPTURECOMPare_register_0>1)-1;//BITBAND_PERI(********_A_CMSS_PERI_TIME_1_COFF_0_1_CCFS_ME_0)****************_CCFS_TIME_COMFS_TIME_1_ME_A0_POSS_TIME_1_TIME_A0_ME_A0_ME_ME_A0_CO0_TIME_A0_ME_TIME_A0_COFF_ME_A0_A0_ME_A0_ME_ME_A0_ME_CO0_ME_ME_A0_A0_ME_A0_CO0_ME_ME_A0(2000)********_CCFS_A0_COFF_ME_A0)********
    	
    	
    	
    
    	//读取上次转换
    	_receive _App.wRxIndex]
    	= ADC14->MEM[3];_receive _App.Z_Rx[_receive _App.wRxIndex]= ADC14->ME[4];_receive _App.Y_Rxrx[_Receive_App.wRxIndex]= ADC14->ME_ME_4]_RECE_Rebure_Re_RxTimer_A3_A3_RE_WAST_ME__ME___ME__ME__ME__REMAGE_SE__ME_5.=
    	
    
    		
    	
    	
    	
    		
    	Timer_a_CMSIS (timer_a3_base)->CTL &=~timer_a_CTL_MC_3;
    
    	//MAP_ADC14_clearInterruptFlag (0xFFFFFFFFFFFF);
    	ADC14->CLRIFGR0 |= 0xFFFFFFFF;
    	ADC14->CLRIFGR1 |= 0xFFFFFFFF;
    	}
    	其它
    	{//***********************************************************************************************************
    		
    		//map_ADC14_toggleConversionTrigger();//
    		开始下一个ADC14序列
    	BITBAND_PERI(ADC14->CTL0,ADC14_CTL0_SC_OFS)=1;
    	}
    
    //*******************************************************************************************************************
    	//LED1_RED_OFF();
    	//HWREG16 (((UINT32_t)P1 +((UINT32_t)&P1->输出-(UINT32_t) P1))&=~LED1_RED_BIT;
    	//*******************************************************************************************************************************************
    }
    
    
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Scott,
    我将尝试设置一个相当简单的示例来重新创建。 您使用什么来测量时钟和/或执行时间?

    谢谢!
    Chris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我使用的是432 Launchpad。 我使用LED 1的GPIO (开/关)测量执行时间。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢Scott。 我相信我已经能够重现该问题并仍在进行调查。 您可能需要检查预取缓冲区(FLCTL_BANK0_RDCTL)的状态,但我无法根据该设置获得令人满意的分辨率。

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

    Chris,

    感谢您的更新。 请继续调查。

    我不确定您希望我查找有关预取缓冲区的内容?

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我只是想确认您的代码中未启用预取缓冲区。

    谢谢!
    Chris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否给出一个线索,说明这在CCS7中属于哪个部分的项目属性?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它位于设备的闪存控制寄存器中,而不是IDE中。