i am using an 89v51rd2 controller with out external RAM, i use the following reentrant function for one of the functionalities, i cant avoid it because this function can be recursively called any no of times,
void reentrantfunction(unsigned char data1, unsigned char data2) compact reentrant { unsigned char local1, local2 = 0;
if(data2) statements;
switch(data2) { case 0: ……. break; ………… case 5: ….. break; } Function2();
for(local1=0; (local1<25); local1++) { Function3();
if(global1) { Global2[local2] = local1; local2++; } Global3 = xx; Function4(); } If (Local2) { Global4 +=1;
for(data2=0;data2<local2;data2++) { Rentrantfuncion (global2 [data2],global4); } Global4 -=1; } }
this is how my startup file stack initialization looks like..
IBPSTACK EQU 0 IBPSTACKTOP EQU 0FFH+1
XBPSTACK EQU 0 XBPSTACKTOP EQU 0FFFFH+1
PBPSTACK EQU 1 PBPSTACKTOP EQU 02FFH+1
i am having problems with this function, the speed for now is not a concern but the functionality itself goes wrong somewhere.. does the code ring bells to anyone ??
You must post your code correctly. It is not readable
"this function can be recursively called any no of times"
No it can not. You have limited RAM. If you use it up you program dies.
Just follow the simple instructions, clearly stated:
www.danlhenry.com/.../keil_code.png
Note that TABs don't work (well) - use spaces instead,
and don't forget to check it in the 'Preview'...
Of course you can!
Any recursive algorithm can be re-written as a non-recursive one!
void reentrantfunc(unsigned char data1, unsigned char data2) compact reentrant { unsigned char local1, local2 = 0,j; switch(data2) { case 0: statements break; case 5: statements break; } Function1(); for(local1=0; (local1<16); local1++) { Function2(); if(global1) { Globalarray1[local2] = local1; Local1++; } Global3=0; Global4=yy; Function3(); function4(); } if(local1) { Global3 += 1; for(data2=0;data2<local2;data2++) { reentrantfunc(globalarray1[data2],global3); } Global3 -=1; } }
the recursive calls can actually be limited to 8 and I dont want to write 8 different function for almost the same job.
So why not just make it iterative instead of recursive?
How about describing what you're actually trying to achieve? Why do you think it needs to be recursive?
Ok.
1. Did you religiously follow all the instructions on reentrant functions in the manual (including such details as proper prototyping and including the reentrant and memory model keyword in the prototype) ?
2. Did you make sure that you are using pdata correctly (there are more settings than just the stack setting, and some in the linker configuration, too).
3. Is there enough space on the pdata stack so that stack overflows do not occur ?
3. What exactly have you done to debug the function ? How exactly does it "go wrong" ?
hie all,
this is actually the base code of a card reader.
a set of commands are sent to a bunch of cards to read their unique ids. this is an anticollision mechanism prescribed for the cards by ISO.
basically only one card replies at a time dependin on its unique iD. when we send a set of commands to the cards, only cards with matching numbers reply. if two cards reply at the same time, their LSB nibbles are the same and we ought to send the command again masking the LSB nibble to identify from the next nibble. this can go on for 8 nibbles at the most.
we need to keep calling the function again and again till there are no unread cards.
pray my english is okay so you understand atleast the jist of it or you could google a document numbered '17n1692t' for more details.
I guess I have, the code is for you to see.
I am not sure of the linker configuration, could you help me on that ??
yes, there is enought space on the stack, because i havent used a lot of local variables.
4. What exactly have you done to debug the function ? How exactly does it "go wrong" ?
I simulate to debug, which is not much of a help. "the going wrong" part is related to the cards i have mentioned before, not all cards are being read even 'almost all' is not hapenning.
But why do you need to do that recursively?
Why can't you just do it iteratively - ie, in a loop?
The code shows the body of the function. It does not show any function declarations.
The linker configuration only needs to be modified if your device supports several pages of pdata, instead of just one (the default for a '51).
http://www.keil.com/support/docs/1848.htm
Where did the 02FFH + 1 for the top of the stack come from - was that a default value or did you intentionally set it to 0x300 ? pdata is usually the first 256 bytes of xdata memory, and trying to set the top of the stack of 0300h might mess things up a bit.
Is there also enough room for the stack to grow ? Judging from value for PBPSTACKTOP, the stack may not be located in memory where you think it is, and overwrite other variables in xdata.
Then again, Andys suggestion is probably worth investigating. Why not turn the recursive algorithm into an iterative one and skip all the messy reentrant stuff ?
and, in pseudocode it looks like this
while collision if state 1 rightshift mask, set state 2 else (state 2) to change LSB ih match, set state 1 read. masb by mask, check match
nothing recursive
Erik
while collision if state 1 rightshift maskfield, set state 2 else (state 2) change LSB in matchfield, set state 1 read. mask by maskfield, check match to matchfield
Jasche K, Just don't use recurrence. It is asking for truble!
unsigned char local1, local2 = 0,j;
Are you sure you want this statement? It's syntactically legal, but ut does not initialize local1 to 0 and local2 to j. Local1 is uninitialized and local2 is initialized to the results of the comma operator, which in this case is j. Evaluating "0" is a waste of time. You probably want
unsigned char local1 = 0; unsigned char local2 = j;
As a matter of style, I recommend declaring each variable individually even if you're going to leave them uninitialized.
This function takes two parameters, each one byte. Per the C51 calling conventions, these parameters will be passed in registers. You'll need stack space for locals and temporaries. Return addresses always go on the hardware stack, so also be sure your SP points to a valid space with enough room to hold the expected depth of recursion.