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.

I need help! program will not fit into available memory. placement with alignment fails for section ".text" size 0x1914 . Available memory ranges:

Hello everyone,

I'm using MSP430G2452. CCS version: 6.1.0 Compiler version: 4.4.3

There is a mathematical equation that I had to write in my code and when I did that I got 2 errors.

And I couldn't find my way around it. So I need someone to explain me how to do it.

The mathematical equation is :

count= count+(19839*(3.1607-ui16Voltage))-19.839;

I am fairly new to this so please make sure you explain what to do in detail.

Thanks a lot!!!

  • Is "ui16Voltage" a variable? If so, what is its type? How does it get its value? What is the range of its value?
    Same questions for "count"/
  • both ui16Voltage and count are unsigned integers.

     This is how the code is. (I am not sure about their range)

  • If those variable are unsigned 16-bit integers, you can only store integers between 0 and 65536 (inclusive) into them. Otherwise the result will be wrong with no warning or error massages.

    Part of your code include floating-point, such as 3.1607 and 19.839, this forces c-compiler to use floating-point math library, which takes a lot of code (in the .text section) and a long time to execute.

    Your immediate problem is, the chip you use does not have enough Flash memory to accommodate your code. CCS linker tried to tell you that.

    You could use a chip with more Flash to solve this immediate problem. But I think the result will be "strange".

    If the value of "ui16Voltage" is larger than 3, after a long floating-point calculation, the value of "count" will not change at all.

    If the value of "ui16Voltage" is 3, 2, 1, or 0, after a long floating-point calculation, the value of "count" will increase (modular 65536) by 62685, 42846, 23007, or 3168 respectively.

    Are these results what you expect? If so, you could have done it using a switch statement with 4 cases and a default.
  • Typo, "can only store integers between 0 and 65535 (inclusive)", not "can only store integers between 0 and 65536 (inclusive)"
  • Thanks very much for your well explained answer. I am expecting ui16Voltage to be between 3.1 and 2.2 and count to be between 60000 and 45000. My supervisor want me to work with particularly the existing chip, so changing the chip is not an option. Would changing the variable type solve the problem? or should I get rid of the equation and figure out an alternative way to do it?
  • So the range of ui16Voltage is between 3.1 and 2.2 and the range of counter is between 60000 and 45000. That answers my question.

    If you directly store quantity between 3.1 and 2.2 into an unsigned integer, you will end up always storing either a 3 or a 2. This, I think, is a misrepresentation of you intention.

    If you change the variable type to floating-point, the value stored will be closer to your expectation. However, you probably do not have enough Flash memory to do Floating-point calculations.

    In order to use smaller amount of Flash and carry calculations faster, you have to figure out a way to represent quantities and do math in fixed point. TI Q-math package may be useful in this respect.
  • Canberk Gurel said:
    The mathematical equation is :

    count= count+(19839*(3.1607-ui16Voltage))-19.839;

    The floating point constants (3.1607 and 19.839) are implicitly double-precision (64-bits). When that single calculation was placed in a CCS project using compiler v4.4.6, 4146 bytes of flash were used.

    The floating point constants were then changed to single-precision (32-bits) by adding a "f" suffix:

    #include <msp430.h> 
    #include <stdint.h>
    
    uint16_t count = 0;
    uint16_t ui16Voltage = 12345;
    
    /*
     * main.c
     */
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    
        count= count+(19839*(3.1607f-ui16Voltage))-19.839f;
    	
    	return 0;
    }
    

    This allows the compiler to use single-precision instead of double-precision calculations. As a result of this change, the flash usage dropped from 4146 to 1002 bytes. By making this change, your complete program may then be able to fit into flash.

  • Chester,

    "The floating point constants (3.1607 and 19.839) are implicitly double-precision (64-bits). When that single calculation was placed in a CCS project using compiler v4.4.6, 4146 bytes of flash were used. ..."

    I did not know that. Thanks for pointing it out. So, CCS will generate even bigger code and take even longer time to execute than I suspected.

    Using CCS v4.46 and use either single- or double-precision constants, am I correct to say that when ui16Voltage is larger than 3 (such as 12345), that statement will not change the value of count?

    When in CCS, we must speak CCS.

    --OCY
  • old_cow_yellow said:
    am I correct to say that when ui16Voltage is larger than 3 (such as 12345), that statement will not change the value of count?

    When ui16Voltage is larger than 3 then the calculation will attempt to convert a negative float to an unsigned integer. From a quick search, this is undefined behavior as far as the C standard is concerned, so not sure what the TI compiler will do (without testing the behavior).

  • Canberk Gurel said:
    I am expecting ui16Voltage to be between 3.1 and 2.2 and count to be between 60000 and 45000.

    The range of expected value for ui16Voltage suggests a floating point variable. Yet, the code shows ui16Voltage has the type uint16_t which is an unsigned integer.

    This suggests that ui16Voltage has been given the wrong type.

**Attention** This is a public forum