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/MSP430FR4133: problem with an optimization

Part Number: MSP430FR4133

Tool/software: Code Composer Studio

I receive the next advice:

#1530-D (ULP 5.1) Detected divide operation(s). Recommend moving them to RAM during run time or not using as these are processing/power intensive

Then I follow the instructions of the next link:

https://processors.wiki.ti.com/index.php/Compiler/diagnostic_messages/MSP430/1530

But the advice still appears and I don't why. I do the next:

in rtc.h:

#pragma CODE_SECTION(ADC_getVcc,".run_from_ram")
uint16_t ADC_getVcc(void);

in rtc.c:

uint16_t ADC_getVcc(void)
{
return (((unsigned long)1023 * (unsigned long)150) / (unsigned long) (ADC_getVref()));
}

in main.c:

void main(void)
{

// copy processing intensive routines into RAM
memcpy((void*)0x2000,(const void*)0xC400,0x0050);

while()

{ 
adcresult = ADC_getVref();
}
}

and in the linker command lnk_msp430fr4133:

SFR : origin = 0x0000, length = 0x0010
PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100
RAM_EXECUTE : origin = 0x2000, length = 0x0050
RAM : origin = 0x2050, length = 0x0750
INFOA : origin = 0x1800, length = 0x0200
FRAM_EXECUTE : origin = 0xC400, length = 0x0050
FRAM : origin = 0xC450, length = 0x3A30

..........

.bss : {} > RAM /* Global & static vars */
.data : {} > RAM /* Global & static vars */
.TI.noinit : {} > RAM /* For #pragma noinit */
.cio : {} > RAM /* C I/O buffer */
.sysmem : {} > RAM /* Dynamic memory allocation area */
.stack : {} > RAM (HIGH) /* Software system stack */

.run_from_ram: load = FRAM_EXECUTE, run = RAM_EXECUTE

.infoA (NOLOAD) : {} > INFOA /* MSP430 INFO FRAM Memory segments */

I don't put all code, however, I think that these modifications are needed to the optimization let appear. 

  • The ULP Advisor issues "Advice", not Warnings. You can ignore its advice without guilt.

    I don't think the compiler has any way of knowing whether your division operations (library functions) are running in RAM or not, since that's a linker decision.

    Running code from RAM is a relatively small optimization. The better optimization is to do fewer divisions if you have a choice. But your program should do what it needs to do.

    You can disable ULP advice using "Build Settings->Build->Compiler->ULP Advisor"

  • Hello!

    As was pointed by previous contributor, placement to RAM is likely a linker job, so compiler has no knowledge, was it done or not.

    Second, I don't know the logic behind repeated call to ADC_getVref(). If that about to change every time, there is little you can do about that. However, if Vref is rather constant value, then you may pre-calculate that value once at init stage and then proceed with some technique. For example, one may get rid of division using multiplicative inverse. Say, if Vref is constant and constant are readings of ADC_getVref(), then one may calculate 1/ADC_getVref() in advance and multiply with that value instead of division. Care to be taken to properly scale.

    One more suspicious place is memcopy(). Are you sure that is needed? In my world this kind of placement is arranged at linking stage and followed by loader. memcopy() in user's main() looks unusual to me.

  • ok, thanks for answering! I think I'm going to disable them then.

  • Thanks for answering and for your help! I use the function  ADC_getVref() to monitor the battery.