Keil Logo

reentrant

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Jasche K
Posted
21-Feb-2008 05:58 GMT
Toolset
C51
New! reentrant

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 ??

Read-Only
Author
Neil Kurzman
Posted
21-Feb-2008 06:45 GMT
Toolset
C51
New! RE: reentrant

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.

Read-Only
Author
Andy Neil
Posted
21-Feb-2008 06:51 GMT
Toolset
C51
New! RE: You must post your code correctly. It is not readable

Just follow the simple instructions, clearly stated:

http://www.danlhenry.com/caps/keil_code.png

Note that TABs don't work (well) - use spaces instead,

and don't forget to check it in the 'Preview'...

Read-Only
Author
Andy Neil
Posted
21-Feb-2008 06:52 GMT
Toolset
C51
New! RE: i cant avoid it

Of course you can!

Any recursive algorithm can be re-written as a non-recursive one!

Read-Only
Author
jasche k
Posted
21-Feb-2008 07:03 GMT
Toolset
C51
New! this is the code, i am sorry
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;
        }
}
Read-Only
Author
jasche k
Posted
21-Feb-2008 07:06 GMT
Toolset
C51
New! RE: this is the code, i am sorry

the recursive calls can actually be limited to 8 and I dont want to write 8 different function for almost the same job.

Read-Only
Author
Andy Neil
Posted
21-Feb-2008 07:16 GMT
Toolset
C51
New! RE: this is the code, i am sorry

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?

Read-Only
Author
Christoph Franck
Posted
21-Feb-2008 08:34 GMT
Toolset
C51
New! RE: this is the code, i am sorry

the recursive calls can actually be limited to 8 and I dont want to write 8 different function for almost the same job.

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" ?

Read-Only
Author
jasche k
Posted
21-Feb-2008 08:56 GMT
Toolset
C51
New! RE: this is the code, i am sorry

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.

Read-Only
Author
Andy Neil
Posted
21-Feb-2008 09:14 GMT
Toolset
C51
New! RE: we need to keep calling the function again and again

But why do you need to do that recursively?

Why can't you just do it iteratively - ie, in a loop?

Read-Only
Author
jasche k
Posted
21-Feb-2008 09:05 GMT
Toolset
C51
New! RE: this is the code, i am sorry

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) ?

I guess I have, the code is for you to see.

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).

I am not sure of the linker configuration, could you help me on that ??

3. Is there enough space on the pdata stack so that stack overflows do not occur ?

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.

Read-Only
Author
Christoph Franck
Posted
21-Feb-2008 09:32 GMT
Toolset
C51
New! RE: this is the code, i am sorry

I guess I have, the code is for you to see.

The code shows the body of the function. It does not show any function declarations.

I am not sure of the linker configuration, could you help me on that ??

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

PBPSTACK EQU 1
PBPSTACKTOP EQU 02FFH+1

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.

yes, there is enought space on the stack, because i havent used a lot of local variables.

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 ?

Read-Only
Author
erik malund
Posted
21-Feb-2008 13:41 GMT
Toolset
C51
New! I am doing somehing similar

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

Read-Only
Author
erik malund
Posted
21-Feb-2008 14:10 GMT
Toolset
C51
New! was too fast, here it is probably a bit clearer

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

Read-Only
Author
Tamir Michael
Posted
21-Feb-2008 14:39 GMT
Toolset
C51
New! RE: reentrant

Jasche K,
Just don't use recurrence. It is asking for truble!

Read-Only
Author
Drew Davis
Posted
21-Feb-2008 18:30 GMT
Toolset
C51
New! RE: reentrant
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.

Read-Only
Author
jasche k
Posted
21-Feb-2008 18:53 GMT
Toolset
C51
New! RE: reentrant

thanks all,
i guess the solution is to write without recursion, i will try that and get back to the post.

this forum is awesome, i am havin numerous answers in 24 hours.

thanks guys

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.