The example below presents a simple FIFO queue implementation which uses the memory management module to allocate and free memory blocks within a specified memory buffer.
#include <stdio.h>
#include "ST_API.h"
/* Data structure */
struct TQueueData
{
/* Any type of data */
int Index;
};
/* Queue item */
struct TQueueItem
{
PVOID Next;
struct TQueueData Data;
};
/* Queue buffer (16 KB) */
UINT8 QueueBuffer[16 * 1024];
/* Queue head and tail pointers */
struct TQueueItem *FirstMessage;
struct TQueueItem *LastMessage;
/* Initialize queue */
BOOL InitQueue(void)
{
/* Initialize memory buffer */
if(!stMemoryInit(QueueBuffer, sizeof(QueueBuffer)))
return FALSE;
/* Initialize queue head and tail pointers */
FirstMessage = NULL;
LastMessage = NULL;
/* Return success */
return TRUE;
}
/* Store message in the queue */
BOOL Push(struct TQueueData FAR *Message)
{
struct TQueueItem FAR *NewItem;
/* Allocate buffer for new data */
NewItem = (struct TQueueItem FAR *) stMemoryAlloc(QueueBuffer,
sizeof(*NewItem));
/* Not enough memory in the buffer (queue is full) */
if(!NewItem)
return FALSE;
/* Copy item data */
stMemCpy(&NewItem->Data, Message, sizeof(*Message));
/* Update pointers (this section should be protected by a critical section
in a multitasking system) */
NewItem->Next = NULL;
if(!FirstMessage)
FirstMessage = NewItem;
else
LastMessage->Next = NewItem;
LastMessage = NewItem;
/* Return success */
return TRUE;
}
/* Read and remove message from the queue */
BOOL Pop(struct TQueueData FAR *Message)
{
struct TQueueItem FAR *Item;
/* Return failure if queue is empty */
if(!FirstMessage)
return FALSE;
Item = FirstMessage;
/* Update pointers. LastMessage pointer can be ignored. (this section
should be protected by a critical section in a multitasking
system) */
FirstMessage = FirstMessage->Next;
/* Copy item data */
stMemCpy(Message, &Item->Data, sizeof(*Message));
/* Release memory block */
stMemoryFree(QueueBuffer, Item);
/* Return success */
return TRUE;
}
int main(void)
{
int i;
struct TQueueData Message;
/* Initialization */
arInit();
stInit();
/* Initialize queue */
if(!InitQueue())
{
printf("Failure during InitQueue() function call.\n");
return 0;
}
/* Store 10 messages in the queue */
for(i = 0; i < 10; i++)
{
/* Prepare message (may be a local variable because it will be copied) */
Message.Index = i;
/* Store message */
if(Push(&Message))
printf("Message %i stored in the queue.\n", i);
/* Stop on failure (queue is full) */
else
{
printf("Failed to store new message.\n");
break;
}
}
/* Read all messages from the queue */
while(1)
{
/* Read next message */
if(Pop(&Message))
printf("Message %i has been read.\n", Message.Index);
/* Stop on failure (queue is empty) */
else
{
printf("All messages have been read.\n");
break;
}
}
/* Deinitialization */
arDeinit();
return 0;
}
Would you like me to proceed with the sections on "Using multiple memory regions" or "Defining reserved memory areas"?