“Expanding” MSP430 internal flash memory

I am using a MSP430F2001 on an application and faced a very common issue: my program got larger than the available (1k) memory! On this article I will show you a little hint to get some more memory of those little chips!

Texas Instruments MSP430F2001 is a 16-bit RISC microcontroller with 1KiB of code flash memory, 128 bytes of RAM, one 2-channel 16-bit timer and one analog comparator. MSP430 line is largely know for its energy efficiency and low power consumption. Packed on a 14-pin TSSOP those micros are really small but still very capable.

Along with the code memory, all MSP430 devices also include another flash area, known as information memory. This is a usually small (256 bytes) flash area designed to store non-volatile data (and some internal calibration data as well). The information memory is split into 64-byte blocks instead of the usual 512-byte blocks of the code memory.

You don’t need to be a genius to figure out that 256 bytes more on a 1KiB chip is really a lot (a 25% improvement to be precise)!

If you application does not use the information memory, what about using it for code storage? But be warned: the last block of the information memory (0x10C0 up to 0x10FF) is used for the internal oscillator calibration data! So, if you are going to use the internal osc, you better not use that area!

So, let’s consider using only the first half of the information memory, that gives us a 128-byte boost for code storage, not bad! In order to use it, we just need to make some changes on the linker control file (on IAR’s EW430 and MSP430F2001 that file is lnk430F2001.xcl): remove and modify the information memory usage and change the code memory allocation as shown below:

Before:

// -------------------------------------
// Information memory
//

-Z(CONST)INFO=1000-10FF
-Z(CONST)INFOA=10C0-10FF
-Z(CONST)INFOB=1080-10BF
-Z(CONST)INFOC=1040-107F
-Z(CONST)INFOD=1000-103F

After:

// -------------------------------------
// Information memory
//

-Z(CONST)INFO=1080-10FF
-Z(CONST)INFOA=10C0-10FF
-Z(CONST)INFOB=1080-10BF

That way, we reduced the available information memory area down to 128 bytes (0x1080 up to 0x10FF) freeing the lower half 128 bytes (0x1000 up to 0x107F) for code storage. But that area is still not going to be automatically allocated for code storage by the linker. You also need to change the code segment allocation as shown below:

Before:

// -------------------------------------
// Constant data
//
-Z(CONST)DATA16_C,DATA16_ID,TLS16_ID,DIFUNCT,CHECKSUM=FC00-FFDF
// -------------------------------------
// Code
//
-Z(CODE)CSTART,ISR_CODE,CODE_ID=FC00-FFDF
-P(CODE)CODE=FC00-FFDF

After:

// -------------------------------------
// Constant data
//
-Z(CONST)DATA16_C,DATA16_ID,TLS16_ID,DIFUNCT,CHECKSUM=1000-107F,FC00-FFDF

// -------------------------------------
// Code
//
-Z(CODE)CSTART,ISR_CODE,CODE_ID=1000-107F,FC00-FFDF
-P(CODE)CODE=1000-107F,FC00-FFDF

And that’s it, now all you have to do is write you code and enjoy the 1152 bytes of flash! See you next time!

Leave a Reply