Strange Behavior On the atmega2560

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have some code written to initialize and fill a 2D buffer of unsigned 8 bit integers over the serial interface  on the atmega2560.  When initializing a small buffer say 10 by 10 the code executes exactly as planned but when i initialize a buffer to contain say 657 by 8 for loops tend to misbehave and i get unsigned 32bit integers turning up negative when i print them on the serial console. i have written a python script to upload the array data to the micro-controller with pyserial i will attach it with the c code so anyone can try to recreate the issue. I assume i am not running out of memory cause the malloc calls would simply fail correct? Anyway been stuck on this for a while would even pay someone to figure out the solution so please any help would be appreciated and potentially compensated. Even if someone were to simply point me in thee right direction or suggest someone i should contact that would be appreciated.

 

regards

 

Lee 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lebrown9 wrote:
Anyway been stuck on this for a while would even pay someone to figure out the solution so please any help would be appreciated and potentially compensated.
Some good linters are zero price and an excellent value (low cost)

Some software development processes have one operate a linter before presenting code for a review (that's two of the best practices)

 

Did unzip c_uart_cli though was daunted by the size of the source code to be reviewed and by a cohesion issue (not portable)

If can isolate the likely range of the defect then a code snippet to review here (<> means "Add code" on the comment toolbar)

Unit tests aid in isolation (test fails and cannot detect the defect)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you *sure* you're not clobbering memory?  I think the Mega2560 has only 8KB.

 

From your example: 657 * 2 (pointers) + 657 * 8 (values array) = 6570 bytes.

 

There's not much room left for globals, call stack, AND the additional 2K you have in 'cmd_str' and 'cmd_val' buffers inside the routine.

 

I hope someone will suggest ways of finding the start/end of stack and free-memory...

Mike

When you're used to privilege, equality feels like oppression. / Malena Ernman

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to the Forum.

 

The likelihood of you running out of memory was my first thought.

 

The simplest test, of course, would be to try an array 1/2 that size, and then slowing increase it, looking at the results as you do so.

 

Clearly there are more exact and academic methods for evaluating the programs memory usage, but the above will be faster and easier, at least to get started!

 

JC

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

thanks everyone definitely an issue with the amount of memory i'm using just surprised  the malloc call still works when i am likely exceeding the max memory

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lebrown9 wrote:
i'm using just surprised  the malloc call still works
How do you know that it "works"?? In your code I see:

				masterTxBuffer = frameBuffer[fdx];
				masterRxBuffer = malloc(frameLen * sizeof(uint8_t));
				transaction.count = frameLen;
				transaction.txBuf = (void *) masterTxBuffer;
				transaction.rxBuf = (void *) masterRxBuffer;

also

			frameBuffer = (uint8_t **)malloc(frameBufferLen * sizeof(uint8_t *));
			for(i= 0; i < frameBufferLen; i++)
			{
				frameBuffer[i] = (uint8_t *)malloc(frameLen * sizeof(uint8_t));
			}

You are never checking the assigned pointer for 0 (malloc's way to tell you that the allocation failed).

 

To be honest it is VERY unwise to use malloc() on an embedded micro with just 8K SRAM in the first place. Even if the malloc() demands can be met at first a heap that small is likely to fragment over time to the point where allocations can no longer be satisfied. It is VITAL in such a resource limited environment that all malloc() calls be checked for 0 return and appropriate emergency reset strategy be invoked when it inevitably returns 0.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I took a brief look at your c_uart_cli and couldn't believe what I was seeing. I'm sorry to be so blunt but it's abysmal really. Your code breaks just abut every rule in the book.

 

  • You receive some Comms command, parse it and malloc some memory depending on the parsed value without any bounds check.
  • You then use the pointer returned from malloc without any NULL check, possibly overwriting the pointer from a previous call.
  • There are 7 malloc calls from all over the place, how can you keep track of all this memory ?
  • I don't see a single call to free().

 

In managed languages like Java & C#, Python etc. You CAN allocate memory and not give it a second thought because on the typical platforms where those run there is colossal amount of memory and you also have a Garbage Collector to free it up. On AVR none of this applies.

 

My recommendation is to scrap this entire code and start again. Either malloc all your memory once during an init or use fixed buffer sizes.

 

BTW: You have a function named itoa with no comment as to why you didn't use the C library version. What does yours do that's different ?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

N.Winterbottom wrote:
In managed languages like Java & C#, Python etc.

...

On AVR none of this applies.

There's an AVR issue in MicroPython otherwise there's PIC24; some PIC24 have EPMP for up to 16 MB of data SRAM.

Python and C can mix.

C# means mostly Arm.

N.Winterbottom wrote:
... or use fixed buffer sizes.
Some computer languages have memory pools; likewise for a relative few RTOS.

 


Python for the 8bit AVR mocrocontroller · Issue #3699 · micropython/micropython · GitHub

micropython-avr8/README.md at master · slavaza/micropython-avr8 · GitHub

micropython/ports/pic16bit at master · micropython/micropython · GitHub

Reference target boards | nanoFramework Documentation

Running .NET on Raspberry Pi Pico 🤯 – MicroHobby

 

std::pmr::pool_options - cppreference.com

Larger than it looks (storage pools) | The AdaCore Blog

 

"Dare to be naïve." - Buckminster Fuller