Memory issues with stack/heap

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

cross mob
lock attach
Attachments are accessible only for community members.
jakac_1482786
Level 3
Level 3
First like received

I have a PSoC5LP project (a scientific instrument measuring pH and temperature) that uses the U8Glib library to drive a oled screen.  It uses newlib-nano  (with the floating point formatting option.  It uses snprintf liberally to format text to be used on the OLED.  It also uses strcmp a few times to parse some of the commands coming from USB or BLE.  The code seems to run fine most of the time and interfaces via UART with PRoC to do the USB stuff.  So it is making liberal use of the heap memory, I suppose.

   

From time to time there seems to be a memory issue that is unpredictable- the pH and temperature values (both floats) stop reading correctly.  The instrument continues to run with all of the interrupts acting properly as well as the communications via USB and UART/BLE.  But the pH and temp values are no longer there.  I have attached pictures of the display.  Interestingly, there is not a consistent amount of time that leads to this issue- sometimes it runs fine for days, other times it fails within hours.  I have both the stack and the heap set at 0x2000 (8kB) which should be plenty.  I am baffled as to why this happens and why it is so unpredictable.  My assumption is that it's a memory management issue.

   

Unfortunately this is a commercial project and I can't share the code.  But has anyone had these kinds of issues and maybe have some insight?  Could it be something to do with newlib nano?  I have plenty of space in SRAM to not use the nano version.  It is so sporadic that I don't even know how to debug the thing.

   

Thanks guys!

   

Jason

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Jason,

   

WDT, NMI and hardware fault interrupt cannot be stopped with a critical section. A  component API might not use an interrupt, so it would probably work correctly. Let me construct an example.

   

Even a putstring() equivalent to a communication interface might work: When there is room in the buffer the call will return after copying. When there is no room, the API will stall while waiting for the buffer to become free (which will not happen with disabled interrupts.

   

 

   

Bob

View solution in original post

0 Likes
7 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Can you (as a try) encapsulate the sprintf() between CyEnterCritical Section() and CyExitCriticalSection().

   

And: Yes, I had some troubles with a program that uses malloc() and free() heavily, I could not get sprintf() to work at all.  I mastered by writing my own conversion routines,

   

 

   

Bob

0 Likes
jakac_1482786
Level 3
Level 3
First like received

Thanks Bob.  I had trouble with malloc and free as well.  My firmware uses a bunch of global variables that are used by nearly

   

all functions.  There's an isr that calls the communication to UART and USB every second. I think that's when things are getting deranged.  I will try encapsulating the sprintf.  

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I will try encapsulating the sprintf   Write your own conversion regarding floats. sprintf() for integers works flawlessly. Because the printing of pH is using a fixed format you need just two sprintf()-calls to build your conversion string.

   

 

   

Bob

0 Likes
jakac_1482786
Level 3
Level 3
First like received

First of all, thank you so much for all of your support for the PSoC community, Bob.  I am in awe of your impact.

   

I have tried encapsulating all of the snprintf's in the code.  Lets see if that works.  If that doesn't work, I'll do the extra coding to separate the integer from the decimal.  snprintf seems to function just fine in terms of printing out the correct values.  No problems there in PSoC5LP.

   

BTW- I assume that encapsulating code that uses a PSoC component that utilizes interrupts (e.g., the ADC) will render it non-functional, correct?  Would it block the Wdt as well?

   

 

   

Thanks so much!!!

   

jk

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Jason,

   

WDT, NMI and hardware fault interrupt cannot be stopped with a critical section. A  component API might not use an interrupt, so it would probably work correctly. Let me construct an example.

   

Even a putstring() equivalent to a communication interface might work: When there is room in the buffer the call will return after copying. When there is no room, the API will stall while waiting for the buffer to become free (which will not happen with disabled interrupts.

   

 

   

Bob

0 Likes
jakac_1482786
Level 3
Level 3
First like received

I think the encapsulation worked.  I encapsulated all of the sprintf's.  I think malloc() certainly can have challenges in embedded systems with RTOS or interrupt-driven events.  The heap always scared me a little bit.  I can still remember common Lisp constantly garbage collecting back in the eighties when I was learning programming techniques!

   

I've had three instruments running 24 hours/day for a week, and no failures.  Hope I didn't jinx it.  

   

Bob- thank you so much.

   

 

   

Jason

Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are always welcome, Jason!

   

There is no garbage collection needed when using free(). The memory manager can combine immediately a freed block to the previous or next ram block when they are not used.

   

 

   

Bob

0 Likes