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.

Error[e16]: Segment CSTACK (size: 0x32 align: 0x1) is too long for segment definition.

Other Parts Discussed in Thread: MSP430G2231

Hello all, 

I am currently coding the MSP430G2231 for my senior design project and I am getting an error that I can't seem find a solution for. This program reads a voltage from pins 1.2 and 1.3, does an ADC conversion, converts the values to an ASCII characters then outputs it via UART. If only using 2 pins, it works perfectly. When I add in the 3rd pin, I get the error:

Error[e16]: Segment CSTACK (size: 0x32 align: 0x1) is too long for segment definition. At least 0x1 more bytes needed. The problem occurred while processing the segment placement command
"-Z(DATA)CSTACK+_STACK_SIZE#", where at the moment of placement the available memory ranges were "CODE:24f-27f"
Reserved ranges relevant to this placement:
200-24e DATA16_Z
24f-27f CSTACK

This is beyond my knowledge and I would appreciate if anyone had any suggestions for this can be changed or corrected. I am still new to using the MSP430 so if you could please provide specific details or someone where I could find, that would be greatly appreciated and helpful.

Here is the code:

/******************************************************************************
* MSP-EXP430G2-LaunchPad Application
*
*
* -Measures voltage at pin 1.1 and voltage at pin 1.2
* -Transmits data as two bytes in format: temp_byte,a7_byte\n\r
* -Blinks the red LED during UART transmission at 2400bps
*
******************************************************************************/

#include "msp430g2231.h"

#define LED_RED BIT0
#define LED_GRN BIT6
#define LED_DIR P1DIR
#define LED_OUT P1OUT

#define TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2

#define APP_STANDBY_MODE 0
#define APP_APPLICATION_MODE 1

#define TIMER_PWM_MODE 0
#define TIMER_UART_MODE 1
#define TIMER_PWM_PERIOD 2000
#define TIMER_PWM_OFFSET 20

//Conditions for 2400 Baud SW UART, SMCLK = 1MHz
#define Bitime_5 0x05*4 //~0.5 bit length + small adjustment
#define Bitime 13*4

#define UART_UPDATE_INTERVAL 200 //Controls the frequency of data transmission

//Variables for UART transmission
unsigned char BitCnt;
unsigned char TXByte;

/* Variables for a 4-value moving average filter on sampled ADC values */
unsigned char measuredPosition=0;
long pinONE[4]; // Pin 1.2
long pinTWO[4]; // Pin 1.1
long pinTHREE[4];

long pinONEaverage;
long pinTWOaverage;
long pinTHREEaverage;

// Functions to Convert an 8-bit binary value to two ASCII chars
char hexChars[16];

//Function prototypes
void InitializeLeds(void);
void ConfigureADC(void);
void ConfigureTimerUart(void);
void Transmit(void);
void InitializeClocks(void);
void InitHexChars(void);
char convertNumToHex_Low(int num); // could pass in int if ADC makes 10 bit or 12 bit num
char convertNumToHex_Med(int num);
char convertNumToHex_High(int num); // could pass in int if ADC makes 10 bit or 12 bit num


void main(void)
{
unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL;
unsigned char i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

InitializeClocks(); // Configure system clocks
InitializeLeds(); // Configure both LEDs for output
ConfigureADC(); // Setup the ADC
ConfigureTimerUart(); // Configure timers for use in software UART

__enable_interrupt(); // Enable interrupts.
InitHexChars(); // initialize an array of the ASCII hex 0, 1 ... F

/* Main Application Loop */
while(1)
{
ADC10CTL0 &= ~ENC; // Disable conversion
ADC10CTL1 = INCH_2 + ADC10DIV_3; // Temp Sensor, Clock = ADC10CLK/4
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

//Add ADC measurement to the averaging array
pinONE[measuredPosition] = ADC10MEM;

ADC10CTL0 &= ~ENC; // Disable conversion
ADC10CTL1 = INCH_3 + ADC10DIV_3; // Input A7, Clock = ADC10CLK/4
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

//Add ADC measurement to the averaging array
pinTWO[measuredPosition] = ADC10MEM;

ADC10CTL0 &= ~ENC; // Disable conversion
ADC10CTL1 = INCH_4 + ADC10DIV_3; // Input A7, Clock = ADC10CLK/4
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

//Add ADC measurement to the averaging array
pinTHREE[measuredPosition] = ADC10MEM;

//Increment our position in the averaging array and reset if at end
measuredPosition++;
if (measuredPosition == 4) measuredPosition = 0;


//Reset final average value variables
pinONEaverage = 0;
pinTWOaverage = 0;
pinTHREEaverage = 0;

//Sum previous four measurements for average
for (i = 0; i < 4; i++){
pinONEaverage += pinONE[i];
pinTWOaverage += pinTWO[i];
pinTHREEaverage += pinTHREE[i];
}
pinONEaverage >>= 2; // Divide by 4 (via bitwise shift) to get average
pinTWOaverage >>= 2; // Divide by 4 (via bitwise shift) to get average
pinTHREEaverage >>= 2; // Divide by 4 (via bitwise shift) to get average

if (--uartUpdateTimer == 0)
{
//Turn on the green LED
LED_OUT |= (LED_RED);

//TXByte = (unsigned char)(pinONEaverage);
TXByte = convertNumToHex_High( (int) (pinONEaverage) );
Transmit();
TXByte = convertNumToHex_Med( (int) (pinONEaverage) );
Transmit();
TXByte = convertNumToHex_Low( (int) (pinONEaverage) );
Transmit();
//TXByte = (unsigned char)(pinONEaverage);

//Transmit a comma separator
TXByte = ',';
Transmit();

//TXByte = (unsigned char)(pinTWOaverage);
TXByte = convertNumToHex_High( (int) (pinTWOaverage) );
Transmit();
TXByte = convertNumToHex_Med( (int) (pinTWOaverage) );
Transmit();
TXByte = convertNumToHex_Low( (int) (pinTWOaverage) );
Transmit();

//Transmit a comma separator
TXByte = ',';
Transmit();

//TXByte = (unsigned char)(pinTHREEaverage);
TXByte = convertNumToHex_High( (int) (pinTHREEaverage) );
Transmit();
TXByte = convertNumToHex_Med( (int) (pinTHREEaverage) );
Transmit();
TXByte = convertNumToHex_Low( (int) (pinTHREEaverage) );
Transmit();


//Transmit a comma separator
TXByte = ',';
Transmit();

Transmit();

//Transmit the end-of-line characters
TXByte = '\n';
Transmit();

TXByte = '\r';
Transmit();

//Reset the UART interval timer
uartUpdateTimer = UART_UPDATE_INTERVAL;

//Turn off the green LED
LED_OUT &= ~(LED_RED);
}
}
}

//Configure the ADC registers
void ConfigureADC(void)
{
unsigned char i;

//Reference = Vref+
//Sample Lenght = 16 CLKs
//Internal 1.5V Reference Generator = On
//ACD10 = On
//ADC Interrupt = Enabled
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;

// Wait for ADC Ref to settle
__delay_cycles(1000);

//Initialize averaging arrays
for (i=0; i < 4; i++){
pinONE[i] = 0;
pinTWO[i] = 0;
pinTHREE[i] = 0;
}
pinONEaverage = 0;
pinTWOaverage = 0;
pinTHREEaverage = 0;
}


void ConfigureTimerUart(void)
{
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; // SMCLK/8, continuous mode
P1SEL |= TXD + RXD; // Peripheral module selected (?)
P1DIR |= TXD; // Set TXD pin as output (P1.1)
}

// Function Transmits Character from TXByte
void Transmit()
{
BitCnt = 0xA; // Load Bit counter, 8data + ST/SP
while (CCR0 != TAR) // Prevent async capture
CCR0 = TAR; // Current state of TA counter
CCR0 += Bitime; // Some time till first bit
TXByte |= 0x100; // Add mark stop bit to TXByte
TXByte = TXByte << 1; // Add space start bit
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE ); // Wait for TX completion
}

// Timer A0 interrupt service routine, used by UART
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += Bitime; // Add Offset to CCR0
if (CCTL0 & CCIS0) // TX on CCI0B?
{
if ( BitCnt == 0)
CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt
else
{
CCTL0 |= OUTMOD2; // TX Space
if (TXByte & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
TXByte = TXByte >> 1;
BitCnt --;
}
}
}

void InitializeClocks(void)
{

BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 1 = 1MHz
}

void InitializeLeds(void)
{
LED_DIR |= LED_RED + LED_GRN;
LED_OUT &= ~(LED_RED + LED_GRN);
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Return to active mode
}


//*****************************************
// Handle Hex to Ascii Conversion
void InitHexChars(void)
{
// Init the hex ASCII char array
hexChars[0] = '0';
hexChars[1] = '1';
hexChars[2] = '2';
hexChars[3] = '3';
hexChars[4] = '4';
hexChars[5] = '5';
hexChars[6] = '6';
hexChars[7] = '7';
hexChars[8] = '8';
hexChars[9] = '9';
hexChars[10] = 'A';
hexChars[11] = 'B';
hexChars[12] = 'C';
hexChars[13] = 'D';
hexChars[14] = 'E';
hexChars[15] = 'F';
}

char convertNumToHex_Low(int num) // LSB 1st ASCII char of number
{
unsigned char i;
i = (unsigned char) num & 0x00F; // Only keep lower 4 bits (3..0)
return( hexChars[i] ); // return the selected hex char
}
char convertNumToHex_Med(int num) // 2nd ASCII char of number
{
unsigned char i;
i = (unsigned char) ( (num & 0x00F0) >> 4); // Only keep lower next 4 bits (7..4)
return( hexChars[i] ); // return the selected hex char
}
char convertNumToHex_High(int num) // MSB 3rd ASCII char of number
{
unsigned char i;
i = (unsigned char) ( (num & 0x0F00) >> 8); // Only keep lower next 4 bits (7..4)
return( hexChars[i] ); // return the selected hex char
}

Thanks for any help you can provide. 

  • The error message contains all information. You apparently have 128 bytes of ram, where your uninitialized global variables (DATA16_Z) occupy 79 bytes and the stack is set for 50 bytes. Which sums up to 129 bytes, one byte more than you have.
    You may lower teh reserved space for stack. This actually doesn't change your resulting code at all, since the reserved stack space is just that: a reservation. Th elinekr will complain if there isn't at least so much space still available in ram after placing all the other stuff like variables. And in your case there wasn't. However, the stack will grow as large as it will grow during the program execution. This stack size settign is only there to produce this linker error and allow the debugger to complain. The MSP will never see this value not will it care for it.

    The default (which can be changed in the project settigns9 is 50 bytes, and you can lower it if you want (making the error disappear), but you should carefully calculate how much stack space your program will really need, or else you'll see stack overflow or stack corruption during program execution - no matter what you enter in the project settings.

**Attention** This is a public forum