hello; i want to know that where we use link list, function pointer, generic pointer in embedded programming
Wherever they provide a solution that most effectively meets the requirements!
However, note that there are major restrictions on the use of function pointers in Keil C51: http://www.keil.com/support/docs/210.htm http://www.keil.com/appnotes/docs/apnt_129.asp
Do you actually understand what a Generic Pointer is?
Keil C51 uses the term in a specific sense: http://www.keil.com/support/man/docs/c51/c51_le_genptrs.htm
You should be able to see that this has both advantages and costs...
ANSI 'C' uses the term "generic pointer" in a somewhat different sense - so, which one did you actually mean?
Linked Lists are not generally a great idea on an 8051, at it doesn't cope that well with indirection.
In general, Linked Lists are often associated with dynamic memory allocation, but this is not necessary - see: " href= "http://www.8052.com/forum/read.phtml?id=70144">www.8052.com/.../read.phtml Whether it's likely to be particularly relevant to a system appropriate to an 8051 is debatable - you might just do something simpler like this: www.8052.com/.../read.phtml
where we use link list,
Usually, not at all on small embedded systems (e.g. an 8051). The programmer should know how much memory is available and how much is needed in various parts of the application. Linked lists are intended for applications where neither the available memory nor the number of data items to be stored is known beforehand.
function pointer,
Should be avoided on '51s, since this architecture is particularly unsuited for using them. Otherwise, function pointers can speed up state machines (though a switch/case and explicit function calls do the same job and keep the program easier to read and to maintain).
"Linked lists are intended for applications where neither the available memory nor the number of data items to be stored is known beforehand."
Although this is their most common application, it is by no means their only use - linked-lists can be perfectly valid without any necessity for dynamic memort allocation. See my earlier post.
"function pointers can speed up state machines"
They can speed up the development of state machine code, but they don't necessarily speed up its execution.
"a switch/case and explicit function calls ... keep the program easier to read and to maintain"
That is highly debatable!
Personally, I would say that using tables of function pointers is certainly easier to maintain - as opposed to having to directly edit huge nested switch statements.
I would also suggest that nested switch statements soon become unweildy - thus also making the code hard to read
Compared to a switch/case plus an explicit function call, I'd say they do. Especially if there's very little to do in each state and the overhead for the function call takes up a significant part of the execution time.
I wouldn't recommend nesting switch statements. That sounds messy and goes against my personal guideline of trying to have three or less levels of indentation per function, as well as trying to have each function fit on one page on the screen.
If the state machine has too many states, I'd consider trying to simplify it, or then use function pointers for readability. Fortunately, I haven't had to deal with such a huge beast yet.
"I wouldn't recommend nesting switch statements"
So how can you implement a State Machine without nesting switch statements?!
In each state, you need to consider each possible event - so that's inherently a "switch-within-a-switch", isn't it?
I think Christoph means to avoid directly nesting switch statements, particularly with a lot of inline code in the cases:
switch (a) { case a1 : switch (b) { case b1 : statement b1; switch (c) { ... } break; ...
If each case just calls a function, those functions might happen to have switch statement inside, but won't cause readability and indentation problems. In fact, if every case in the switch calls a function, it's quite likely that it will compile into a jump table to those function calls, which is essentially the same code as a table of function pointers.
My faviourite (not!) is state machines where the states has not been given names. Each case just has a number, and within it the code may have a line:
state = 17;
Almost impossible to know what state 17 means, and almost impossible to insert a new state without missing to renumber all state changes.
My faviourite (not!) is state machines where the states has not been given names.
Ohhh, I think you forgot that for complete "enjoyment", all of the states are actually "documented" in a separate document, which is "slightly" out of date with the actual code. :)
(It's somewhere in the Writing-Unmaintainable-Code Howto: "Lie in the comments/documentation. It doesn't need to be obvious, just fail to keep the comments/documentation up to date with the code.")
If each case just calls a function, those functions might happen to have switch statement inside, but won't cause readability and indentation problems.
Exactly, thanks for guessing my thoughts.
#define STATE_INIT 0 #define STATE_WORK 1 void state_machine() { static int current_state = STATE_INIT; switch(current_state) { case STATE_INIT: current_state = state_init(); break; case STATE_WORK: current_state = state_work(); break; default: current_state = STATE_INIT; break; } } int state_init() { return(STATE_WORK); } int state_work() { return(STATE_WORK); }
Something along those lines.