We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
How can I install a list in a ARM controller?
typedef struct { volatile unsigned int *p_NextHdr; volatile unsigned int *p_PrevHdr; volatile unsigned int *p_data; }*Hdr;
*p_NextHdr: ptr to the next list element *p_PrevHdr: ptr to the previous list element *p_data: ptr to the buffer (for this list element)
Hdr HdrPtr;
// ptr to the struct
At the beginning:
*p_NextHdr = *p_PrevHdr = *p_data = NULL;
But how can I install a few list elements? Could you tell me the next steps I have to do? How can I allocate storage for the struct?
best regards Ingo
Your best bet is to just google for a double-linked list. It tells you how to insert, remove and traverse.
You did post your code with the correct tags - how could it end up so badly, with all three pointers on the same line?
thanks for your reply...
you're right - the correct version is
HdrPtr->p_data = NULL;
// and so on;
When I take a look into double-linked lists (in c) so you have to allocate storage
struct <name of struct> Hdr = malloc (sizeof(struct <name>));
Is that the right way to allocate storage for one struct?
At the end I'll install 10 list elements of this struct.
Embedded systems seldom use dynamic memory.
Normally you allocate your entries statically using an array, and then insert the entries in the list in the required order.
You also often inline the actual data fields directly together with the link pointers.
struct my_entry { struct my_entry *next; struct my_entry *prev; int my_field1; int my_field2; ... }; struct my_entry my_entries[100]; struct my_entry *first; struct my_entry *last;
But it is often not needed to be able to traverse a list foward and backward. Often it is enough to be able to traverse in one direction, but to be able to diretly find the first and last entries.
This can be done by using a single-linked list, but making it a circular chain, where the last entry points to the first entry.
Then you only have:
struct my_entry { struct my_entry *next; int my_field1; int my_field2; ... }; struct my_entry my_array[100]; struct my_entry *last; struct my_entry* get_first(void) { return last ? last->next : NULL; } struct my_entry* get_last(void) { return last; }
ok that means I use the list as a array and allocate the storage for e.g. 100 structs
struct my_entry my_array[100];
and then I'm able to say
my_array[5].field = 5;
But it is often not needed to be able to traverse a list foward and backward.
My list includes some header information for the incoming data over the ethernet. So the list includes the number of refernces to the buffer, the pointer to the buffer as well as some flags... So the list is only the header of the buffer.
I don't know if it is the best way to install a list - or if there's another better way to do that.
number of list elements with the struct data:
struct data *Header[NB_ETH_RX_PACKETS];
ptr to the tail and the start of the list
struct data *HdrEnd; struct RxData *HdrBegin;
struct data
typedef struct data { volatile unsigned int Data; struct RxData *p_NextHdr; struct RxData *p_PrevHdr; } *Hdr;
Hdr p_HdrLisPtr;
init pointers at the beginning:
HdrBegin->p_PrevHdr = HdrEnd->p_PrevHdr = HdrBegin; /* */ HdrBegin->p_NextHdr = HdrEnd->p_NextHdr = HdrBufEnd; /* */ p_HdrLisPtr = HdrBegin;
so now I should be able to install some list elements in a for-loop (for i=0; i<8; i++)
Header[i]->Data = i; // element in liste eintragen Header[i]->p_PrevHdr = p_HdrLisPtr; /* */ Header[i]->p_NextHdr = p_HdrLisPtr->p_NextHdr; /* */ p_HdrLisPtr->p_NextHdr->p_PrevHdr = Header[i]; /* */ p_HdrLisPtr->p_NextHdr = Header[i];
Are there any mistakes?
Ingo