avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] problem with malloc() in avr-libc 1.6.1


From: David Brown
Subject: Re: [avr-gcc-list] problem with malloc() in avr-libc 1.6.1
Date: Tue, 29 Jan 2008 15:08:55 +0100
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Javier Almansa Sobrino wrote:
<snip>

Hi, this is the struct I use on my project:

typedef struct {
  /* Buffer */

  uint8_t *data; /* Data */
  uint16_t pStart; /* Start pointer */
  uint16_t pEnd; /* End pointer */
  uint16_t size; /* data size */
} bufferC_t;

In the main function, I do this:

int main (void) {
  bufferC_t *buffer;
  uint8_t count;
  volatile uint16_t c1, c2;
  __malloc_heap_start = (void *)0x808000;
  __malloc_heap_end = (void *)0x80ffff;
  wdt_disable();

  sysInit();
  rs485Init();
buffer = (bufferC_t *)malloc(sizeof(bufferC_t));
  buffer -> data = (uint8_t *)malloc(DATA_LEN);

  .....................
  ......................

}


Later, I've got a function that do something like this:

void rs485Write (uint8_t addr, uint8_t len, bufferC_t *buffer) {
uint8_t head[2];
  uint8_t c;
  uint8_t *bufferOut = (uint8_t *)malloc(sizeof(uint8_t)*(len+2));
if (len > 0) {
    /*
      Si hay datos para transmitir, se crea la cabecera del mensaje
      (Direccion:Longitud)
    */
bufferOut[0] = addr;
    __write(bufferOut[0]);
    bufferOut[1] = len;
for (c = 0; c < len; c++) {
      pop(&bufferOut[c+2], buffer);
    }
sendData (bufferOut, len+2);
  }
  free(bufferOut);
}

All works fine, but when this last function is called for a number of
times, malloc never returns.

I've changed the call of malloc for alloca and all runs fine. But I
wish to know the reason of this failure.

I whis to know if is possible to change the memory cheap where alloca
assigns memory.

Thanks


alloca() always allocates memory on the stack - that's what makes it fast and cheap, and means that it is deallocated at the end of the function.

But looking at your code above, I can't see any reason why you would want to use dynamic memory and pass things around with pointers. Obviously I don't know about the rest of your code, but I have seldom come across programs on 8-bit micros where malloc() is actually a sensible way to structure your data. You should seriously consider making your buffers static data structures (which could well be placed in your external RAM if they are big). Anything allocated in main() is an obvious candidate for a static structure, but your rs485Write() function would almost certainly be better off with a static bufferOut[] array - simply define it to be large enough for your largest "len". If you have other calls to malloc() in the program, consider pre-allocating static arrays for them too. For complex situations, a specially-written allocation routine often a better choice, since it gives you control over your allocation sizes, fragmentation, timing, and error handling.

The only times when malloc() and free() are a good choice for small embedded systems are when porting existing code which you don't have time to re-write in a better way, and if you have a very unpredictable pattern of allocations and releases. In this later case, you should expect your malloc() to fail eventually from lack of memory or fragmentation issues, and check the results so that your program doesn't crash.

mvh.,

David




reply via email to

[Prev in Thread] Current Thread [Next in Thread]