Jump to content
43oh

Strange Stack Issue


Recommended Posts

Hey all.

So I'm working on this project and for the last month have been battling the weird bug ever. I will provide as much code as I can which is very little unfortunately.

I have a reset problem to put it simply. I have narrowed it down to this bit of code which is intended to repack an array of 16 bit ints with 12 bits of significance so that the 12 bits which are significant are back to back reducing the number of bytes by 25%.

 

The code the way it is will cause resets. Yet, if I add a variable to the function (such as int t) and assign a value to it (so as to make sure it doesn't get optimized away) the program no longer crashes. Thus it seems to be a stack issue. But of what kind? And how do I solve it? It is possible I am close to overflowing flash but my IDE (Rowley Crossworks) doesn't give me a clear answer as to what the stack usage is.

 

This code seems to cause the resets. First I'll link it:

int repack12BitArray(unsigned char *buffer, int buffer_length, unsigned int *data, int data_length)
{    
   int i;
   int cur;

   const int BYTE_LOW_MASK = 0x00FF;
   const int BYTE_HIGH_MASK = 0xFF00;

   if (buffer_length < (3* data_length / 2))
       return 0;

for (i = 0; i < data_length/2; i++)
   {
       cur = (unsigned char) ( ( data[2 * i] >> 4) & BYTE_LOW_MASK);
       buffer[3 * i] = cur;  // Grab the highest 8 bits of the first 12 bit number
       cur = (unsigned char) ( ( ( data[2 * i] << 4) & BYTE_LOW_MASK) + ( ( data[(2 * i) + 1 ] >> 8) & BYTE_LOW_MASK));
       buffer[(3 * i) + 1] = cur; // Grab the lowest 4 bits of the first, highest 4 bits of the second
       cur = (unsigned char) ( data[(2 * i) + 1] & BYTE_LOW_MASK);
       buffer[(3 * i) +2] = cur; // Grab the lowest 8 bits of the second number
   }

   return (3 * data_length / 2);
}

 

So here's where things get...weird. This code seems to be causing resets but if I do the following in that function all is well:

int t = 63;

 

...Anyone got any ideas?

Link to post
Share on other sites

Don't know how much experience you have with C on non-virtual memory machines

but just because a crash occurs inside a function doesn't mean that said function is

actually causing the crash. Do you have any interrrupts active when this function is

running?

 

If adding the 'int t = 63;' prevents the problem, is the problem averted if this definition

is placed elsewhere within the function? I'm thinking that the value of 'i' could be getting

corrupted while in the for() loop. With 'i' getting corrupted could lead to memory anywhere

in the system to be FUBAR'd, including the stack.

 

Any chance you're manipulating enough data in this function that the Watchdog is not

getting "feed"?

 

Have you tried stepping through the code with a debugger? The results?

 

Just some thoughts... If they don't work you can have consultation fees refunded in full!!! :-)

 

-Rusty-

Link to post
Share on other sites

Ha! Good man. Thanks.

I forgot to mention the WDT is off. No lpm either atm. As for interrupts they can likely be ruled out as the cause as this is 100% repeatable at the same spot in code regardless of when I invoke this call. I can't debug because my RTOS conflicts with debugging. The problems are not averted by moving the call around. Simply having the assignment in the function anywhere fixes the issue which is why I'm so confident its a stack issue.

As for my experience level: low. :)

 

Thanks for your ideas. Should have answered those in the original post.

Link to post
Share on other sites

One thing that I do when I'm trying to isolate a problem in a single function is to

take that function and compile it somewhere I can debug it; preferably on a similar

architecture. If you have a Launchpad to EZ-430, I'd compile the function with

some test data and debug it there.

 

But, quite frankly, the function appears to be sound and I tested it on my laptop with

no ill effects. If the algorithm works then something external is causing problems,

either the system itself or the compiler.

 

I'd suggest getting the listing of this function from the compiler with the assembler

statements and see if everything is going where it should and in the right quantities.

 

I also modified your for() loop for a bit of efficiency. You can get rid of both the

'cur' and 'BYTE_HIGH_MASK' variables since they are not used. This might free

up 4-bytes from your stack if you're pinched for space.

for (i = 0; i < data_length; i+=2)  {
   // Grab the highest 8 bits of the first 12 bit number
   *buffer++ = (unsigned char) ( ( data[i] >> 4) & BYTE_LOW_MASK);

   // Grab the lowest 4 bits of the first, highest 4 bits of the second
   *buffer++ = (unsigned char) ( ( ( data[i] << 4) & BYTE_LOW_MASK)
                                + ( ( data[i + 1] >> 8) & BYTE_LOW_MASK));

   // Grab the lowest 8 bits of the second number
   *buffer++ = (unsigned char) ( data[i + 1] & BYTE_LOW_MASK);
}

On an x86 I saved about 64-bytes of code. Will probably be higher on the 430.

And yes, the output will be the same as your original loop.

 

Personally, I'd return a -1 on an error at the top of the function simply because

a zero could legitimately be passed in data_length. With no error, your function

will return 0 as well.

 

Somethings to think about...

 

-Rusty-

Link to post
Share on other sites
  • 2 weeks later...

Sorry to take so long to get back here! I blame the holiday. That and that I've been busy on other projects since last post.

 

I appreciate you taking the time out to run my algorithm on your PC. Thanks for the results and optimizations! I'll be sure to let you know if I see anything in the listing when I get to doing that.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...