Stack usage in C++ on embedded TMS320C6713 system

I spent a lot of time working on my embedded platform managing memory usage. Knowing how much stack is being used at any time was a major problem. It’s one thing to look at the assembly created by your code and be able to add up how much space each subroutine uses, but recognizing how much any other library function call uses is quite a differetn thing.

My solution was to have a routine that would initialize all of the ram in the stack to a particular pattern on the first call, and then measure how much of that ram was no longer the pattern on the second call.

extern void * _STACK_SIZE;
extern char * _stack;
int RFSAWStackCheck(char * InputBuffer, int InputBufferSize, const unsigned short LastSample, uart_init_struct &std_uart, FILE * tx)
{
	fprintf(tx,"%s\r\n",InputBuffer);
	fprintf(tx,"\t _STACK_SIZE = 0x%6x\r\n",(int)&_STACK_SIZE);
	fprintf(tx,"\t      _stack = 0x%6x\r\n",(int)&_stack);
	// Things to put in Watch Window:
	// _STACK_SIZE
	// _stack
	// B15
	// (_stack+_STACK_SIZE)-B15
	unsigned int * StackLow = (unsigned int *)&_stack;
	unsigned int * StackHigh = StackLow;
	while (*StackHigh == 0xDEADBEEF)
		StackHigh++;
	unsigned int StackUnused = (unsigned int)StackHigh - (unsigned int)StackLow;
	unsigned int StackUsed = (unsigned int)&_STACK_SIZE - StackUnused;
	fprintf(tx,"\t UnusedStack = 0x%6x\r\n",StackUnused);
	fprintf(tx,"\t   UsedStack = 0x%6x\r\n",StackUsed);
	if (InputBuffer[17] != '\0')
	{
		Uint32 gie = IRQ_globalDisable();
		fprintf(tx,"\t Writing to Stack Space = 0x%X\r\n",0xDEADBEEF);
		unsigned int ApproxCurrentStackUnused = (unsigned int)&ApproxCurrentStackUnused;
		// don't know exactly where my current variable lies in the current frame, and memset will require
		// a small amount of stack, simply for the function call itself.
		StackHigh = StackLow;
		while (StackHigh <= (unsigned int *)&ApproxCurrentStackUnused - 0x100)
			*StackHigh++ = 0xDEADBEEF;
		IRQ_globalRestore(gie);
	}
	return(0);
}

The two extern symbols _stack and _STACK_SIZE are automatically generated by the TI compiler toolset. The register B15 is the register that is used for the stack pointer.

I’m using a pattern that is human readable in hexadecimal, because it makes things easier when looking at a memory map in the debugger. 0xDEADBEEF is a simple 32 bit pattern that is not likely to occur naturally, but is quite recognizable to most english speakers.

I disable interrupts during the process of writing to the stack, but don’t do so during the process of reading from the stack. This is mostly a combination of me being lazy and the fact that I’m uncertain of possible implications of disabling interrupts.

I make a simple decision based on position 17 in the input buffer if I’m initializing the ram in the stack, or just looking to see how much of the pattern exists.

I’m interested in any feedback, suggestions of what I’m doing that’s unsafe, or better ways of accomplishing my goals.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s