Allocating buffer memory
Buffer memory can be allocated in one of two generic ways: statically at build time by allocating memory through the linker and dynamically during run time by calling an operating system to allocate/program memory access.
Static allocation requires the memory needs to be defined before building the application and allocating memory either through special directives at the assembler level or through the definition of global, static or local variables within the various tasks within an application. This essentially declares variables which in turn allocate storage space for the task to use. The amount of storage that is allocated depends on the variable type and definition. Strings and character arrays are commonly used.
malloc() and its counterpart unmalloc() are system calls that were originally used within UNIX environments to dynamically allocate memory and return it. Their popularity has meant that these calls are supported in many real-time operating systems. The call works by passing parameters such as memory size and type, starting address and access parameters for itself and other tasks that need to access the buffer or memory that will be returned. This is a common programming error. In reply, the calling task receives a pointer that points at the start of the memory if the call was successful, or an error code if it was not. Very often, the call is extended to support partial allocation where the system will still return a pointer to the start of the memory along with an error/status message stating that not all the memory is available and that the x bytes were allocated. Some other systems would class this partial allocation as an error and return an error message indicating failure.
Memory that was allocated via malloc() calls can be returned to the memory pool by using the unmalloc() call along with the appropriate pointer. This allows the memory to be recycled and used/allocated to other tasks. This recycling allows memory to be conserved but at the expense of processing the malloc() and unmalloc() calls. Some software finds this over-head unacceptable and allocates memory statically at build time. It should be noted that in many cases, the required memory may require a different design strategy. For memory efficient designs, requesting and recycling memory may be the best option. For speed, where the recycling overhead cannot be tolerated, static allocation may be the best policy.