Large buffer makes AVR crash

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

Hello all,

 

I'm using Attiny 1634 as light HTTP server with ESP8666 as TCP server.

 

I develloped my own uart lib and I'm able to generate valid HTTP response from standard browser query. 

 

When the ESP receive data from TCP I get this keyword from uart: "+IPD,x,yyy:" followed by the http header "GET / HTTP/1.1\r\n"

 

I analyse this header to answer back the good page.

 

Everything is okay for short query when my rotaty rx buffer is set at 200 bytes, this works for a long time and a lot of query, fo I thinks it's not a memory overflow.

 

Now I need to read post field and my query is 550 byte long, If I increase my buffer size above around 280 byte my AVR crash or become very slow (life led stop blinking every 250ms).

 

These is my memory usage wit 200 byte buffer size:

 

"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-size.exe" "CONTROLE_VOLETS_MCU.elf"

   text    data     bss     dec     hex filename

   5718     172     223    6113    17e1 CONTROLE_VOLETS_MCU.elf

Done executing task "RunCompilerTask".

Task "RunOutputFileVerifyTask"

Program Memory Usage : 5890 bytes   35,9 % Full

Data Memory Usage : 395 bytes   38,6 % Full

Done executing task "RunOutputFileVerifyTask".

 

This is my memory usage with 550 byte buffer size:

 

   text    data     bss     dec     hex filename

   5694     172     573    6439    1927 CONTROLE_VOLETS_MCU.elf

Done executing task "RunCompilerTask".

Task "RunOutputFileVerifyTask"

Program Memory Usage : 5866 bytes   35,8 % Full

Data Memory Usage : 745 bytes   72,8 % Full

Done executing task "RunOutputFileVerifyTask".

 

But in these case my AVR doesn't even starts !

 

Do you have an idear of what my problem is ?

 

You can find attached my uartlib with rotary buffer system.

 

Thank you for help.

 

Eliott.

 

Attachment(s): 

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

1. You haven't posted the complete code.

2. My guess is stack overflow.

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

Eliott wrote:
I'm using Attiny 1634 as light HTTP server

An ATtiny1634 has only 1K RAM - so it would have to be a very light HTTP server indeed!

 

But the ATtiny1634 does have on-chip debug - use it!

 

Eliott wrote:
If I increase my buffer size above around 280 byte my AVR crash

Is you buffer automatic - ie, on the Stack ... ?

 

Eliott wrote:
Data Memory Usage : 745 bytes   72,8 % Full

That is static data usage - so you only have 270 bytes left for Stack

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

thank you for the answers.

 

I can give you all the code but can this be really usefull ?

 

My guess is stack overflow: so I use more Data Memory that I have ?

 

I suppose that every local variables declared will use the 270 remaining bytes and it's no enought ?

 

I use the "My Smart USB light" programmer who emulate an stk 500 board but I dont have debug feature I think.

 

When I use "const char down[4] PROGMEM = {"down"};" I don't see anything change on memory occupation, but if the "Program Memory Usage" is 5848 bytes full my PROGMEM will increase the flash occupation to 5852 bytes ?

 

Thank you for help.

 

Eliott.

Attachment(s): 

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

Moving const data such as strings from RAM to flash should always help. Also analyze your use of stack frame automatics - you could easily be eating loads of RAM without realising it.

.

EDIT: I haven't read all your code but I just downloaded the rar and looked at main() and the first thing I see is data[128] as a stack auto. If there's a lot like this it will eat your RAM very quickly.

 

To be honest I think you've picked the wrong micro for the job. 

Last Edited: Sun. Oct 8, 2017 - 12:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I reduced the data to 15 bytes by moving a large string to Flash.

 

I'm right if I say that it's not a good idea to use flash as buffer beacause the flash has a limited write operations ?

 

For now I solved my problem by reading my http query and I noted that my buffer parsing function is faster than the UART speed at 250kbyte/s; so I eleminate every char that I don't need and even in a 512 bytes long string I can treat the first ten bytes as much as the ten last bytes with a 200 bytes buffer.

 

Thank you for help.

 

Eliott.

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

Eliott wrote:
My guess is stack overflow: so I use more Data Memory that I have ?

Yes. If you have 270 bytes free, you can store 270 bytes on stack. If you store more data, the stack grows so much so other data (extern and static variables) are overwritten.

Note, that:

  1. Automatic (i.e. stored on stack) variables in main() take 188 bytes of stack, so instead of 270 bytes, you have only 82 bytes available.
  2. There are two ISR functions and they can be executed at any time, fortunately only one at a time. You need additional 13 bytes of stack reserved for ISR(USART0_RX_vect), the second ISR needs less stack space. Now you have only 82-13=69 bytes available.
  3. Not only automatic variables are stored on stack. When you call a function, return address is stored on stack and more or less additional data can be stored on stack.
  4. You use sprint function. This function needs some stack space for its data.

 

My suggestion is:

  • Set rx buffer size to the smallest value that will make your code working incorrectly
  • Verify that the code works incorrectly
  • Remove all sprintf function calls
  • If the code works correctly without sprintf calls, the issue is most likely stack overflow. But see one more idea below.

 

One more idea:

You use sprintf with quite small buffer to write, only 4 bytes long. Are you sure that there is no overflow of this buffer, i.e. number to write by sprintf is always no more than 999?