Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

PSoC™ 5, 3 & 1 Forum Discussions

WiFl_1166056
Level 3
Level 3
10 replies posted 10 questions asked 5 replies posted

I’m getting a HardFault that I’ve been fighting all week with no success. 

The problem seems to be stack corruption, but I haven’t been able to find the culprit.  The timing is random, but usually happens within an hour, sometimes immediately on startup.  This makes me think it has something to do with an interrupt.   I’ve tried using some tricks to preserve the stack after a hard fault by implementing an assembly/C hardfault handler.  This hasn’t provided much useful information. 

A strange thing I notice is that the stack trace after the crash almost always has __cy_stack_limit() at the bottom (see attached image), but the stack is not overflowing and my stack pointer is at a very reasonable place.  I even made a function to clear RAM on startup so I can see wherever data has been written.   I’m only using about half my stack space (unless something is writing all zeros).  FYI, the code that's crashing is emWin.  I have also noticed that one variable, stored in a register, that should hold the string length, seems to have been overwritten by a value that would be a valid stack address.  I'm not sure if this is a cause or effect of the crash.  This function will run correctly thousands of times without crashing, but it does seem to be related to the crash.  But, I digress... the real question I'm trying to answer is about __cy_stack_limit() because it seems like an important clue.

A google search doesn’t find much about __cy_stack_limit(), and I can’t find it in the source code. I'm guessing it's a fault vector triggered by the stack pointer register exceeding a value, but I haven't found it in the PSoC5LP documentation.  If I'm right about that, I would still need to know exactly what could trigger it, considering there's no evidence of stack overflow.

Can anyone find any documentation about what __cy_stack_limit() means?

Thanks!

-Will

0 Likes
1 Solution

Solution was to change to the Keil compiler.

Thanks to everyone for your support.

View solution in original post

0 Likes
8 Replies
GeonaP_26
Moderator
Moderator
Moderator
250 solutions authored 100 solutions authored 50 solutions authored

(1) Have you tried increasing the Stack Size in cydwr System window?

(2) Instead of zeros, can you fill the stack with unusual data at the startup. Please use an arbitrary number such as 0xFEEDBEEF that would stick out visually and the probability of application being written with it will be low. Later, please check the memory window to observe stack usage.

0 Likes

geon​  any feedback based on will's latest update?

If Will can send his HW to someone at Cypress can they help debug this?

Regards,

Kevin

0 Likes
KevinR_91
Employee
Employee
25 replies posted 10 likes received 10 replies posted

Will,

Can you add your latest findings here?

Thanks,

Kevin

0 Likes

I tried the suggestions from geon​, which confirmed that stack size is not my issue and my problem is stack corruption, not stack overflow.

I believe the IDE shows "__cy_stack_limit" because it is trying to correlate a function name with data in the stack that should be a return address.  Since the stack has been corrupted, the data in that location is invalid but happens to be an address within stack space.  I assume the stack-unwinder, essentially, looks at the .map file and displays the section within which the address exists.  In my particular case, the address is within the stack, and the stack memory address range starts at __cy_stack_limit, so that is what the stack-unwinder displays in the call stack.

As can be seen in this image, the "address" of __cy_stack_limit() is 0x20007C10.  This address is within the stack, and is actually the address of the string that should be getting displayed by the GUI (as can be seen in the argument list of GUI__DispLine).

__cy_stack_limit with addr_cropped.png

0 Likes

Hello Will,

There seems to be an error in the function _DispLine. The parameter maxNumChars is too high, and the const char * s is referring to an invalid address. Can you kindly check how these parameters are evaluated before getting passed to _DispLine function?

Thanks, and regards,

Sampath

0 Likes

Hi Sampath,

Good observation.  The invalid data appears to be the result of stack corruption because the values are correct in GUI_DispLine, and are simply passed, unchanged, to _DispLine.  There is also no linear way in the code of GUI__DispLine for char* s or MaxNumChars to change.

There is also no way to go from _DispLine to GUI__GetPresentationForm, so I expect this is also an artifact of trying to unwind a corrupted stack.

It looks a lot like the stack pointer is off by 1 word.  When returning from _DispLine, it should execute at 0x00002B4F (inside GUI__DispLine), but instead went to 0x00000004.  There's a similar pattern lower in the stack, where it should return to 0x000039db, but instead the stack unwind saw 0x20007C10.  This error occurs at random times, so I suspect something like interrupt interference, but I haven't been able to prove that.

Does anyone know of a way for the stack pointer to be incremented or decremented incorrectly?  Perhaps some timing issue that could cause a push or pop to be repeated?

Thanks!

__cy_stack_limit with addr_cropped_marked.png

0 Likes

Hello Will,

It seems like we need more inputs to understand this issue well enough to debug it. Can you kindly attach a minimal project which can reproduce this issue?

Best regards,

Sampath

0 Likes

Solution was to change to the Keil compiler.

Thanks to everyone for your support.

0 Likes