CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Recursion is not permitted?? why is it so??

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
farizluqman
Guest







Recursion is not permitted?? why is it so??
PostPosted: Mon Sep 22, 2008 2:11 am     Reply with quote

Hi everybody,

I am such a beginner to use 16F877A uC. I am doing a project called simple calculator and using PICC compiler. I am intent to make a Decimal to Hexadecimal converter in this calculator. but I found something weird error in my programming when I compile, the function DectoHex programming is such like this:
Code:

void DectoHex(int dec)
{      int r;
       if(dec>0)
       {
        r=dec%16;   //get remainder
        dec=dec/16;   //get  division number
        DectoHex(dec);
       }
       else
      //doing something

and I to call the function such like ->>
Code:
       
DectoHex(dec);

The error says: Recursion not permitted. [DectoHex]

Why is it so? plz help me on solve this problem. TQ.
Ttelmah
Guest







PostPosted: Mon Sep 22, 2008 2:22 am     Reply with quote

It is to do basically, with the PIC hardware.
Chips like the 8080, 6502 etc., have a large stack, in the RAM, which can be used both to hold return addresses for functions, and data values. Hence when a subroutine is called, both the return address, _and_ the local variables, can be 'pushed' onto the stack, and then 'popped' when the function returns. This allows a function to call itself (recursion), since the local variable copy, can be different for each call. The PIC doesn't have this ability. It's stack _only_ holds return addresses. Hence if a function calls itself, the second copy, will see the same RAM variables, and corrupt the values in the first copy.
So, 'DecToHex', cannot call itself. For your simple application, just have two copies of the function.

Best Wishes
cortesj
Guest







How come the microchip compiler can do recursion?!
PostPosted: Wed Mar 18, 2009 5:38 pm     Reply with quote

How come the microchip compilers can do recursion?!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 18, 2009 6:44 pm     Reply with quote

Because the PIC processor hardware is lacking a stack pointer register the Microchip C18 compiler creates a software based stack pointer using the registers FSR1 (stack pointer) and FSR2 (frame pointer)

Advantages of this so called 'automatic' approach are:
- support for re-entrant code (recursion)
- Claims to have more efficient data memory usage (compared to what?).
Disadvantages are:
- Uses more code memory.
- Slower execution.

Around the year 2002 the C18 compiler introduced a new feature called 'Static Parameters' in which the function parameters are stored at fixed addresses instead of on the stack.
Advantages:
- Improved code size
- faster to execute
Disadvantages:
- Recursion not possible.

Additional data space (RAM) can be saved by re-using the memory of local function variables for functions that can never execute at the same time. Microchip calls this feature 'overlay'.

More info in the MPLAB CXX USER’S AND REFERENCE GUIDE ADDENDUM
, chapter 'Static Parameters' on page 2.

The CCS compilers use a technique which is more or less a combination of Static Parameters and Overlay. Resulting in very efficient generated code with a small memory footprint. And no, you can't use recursion but to my experience this is no big loss. In my 20 years as an embedded programmer I never had to use recursion or there were alternative methods to solve the problem without recursion.


In short:
- On the PIC processor with limited hardware the Static Parameters are way more efficient (memory and speed) than a stack based implementation.
- The Microchip compiler allows the user to choose from different memory models.
- The CCS compiler only supports one memory model, similar to the efficient Microchip 'Static Parameters' + 'variable overlay'.
- Microchip only added the option for Static Parameters around 2002.
- Memory efficient CCS has been around much longer.
- Microchip's C18 is more flexible than the CCS compiler.
- A commercial license for C18 costs $495 (aside from free academic versions and a restricted fee evaluation version).
- A licence to CCS PCH costs $200.

Depending on where you are standing the above might convince you that either the CCS or Microchip compiler better suits your needs.
potato



Joined: 23 Mar 2014
Posts: 16

View user's profile Send private message

PostPosted: Tue Apr 29, 2014 4:11 am     Reply with quote

Hi all of you!

I know this thread has ages, but I find myself with the same recursion problem, despite it isn't as clear as in the farizluqman code.

In short:

Code:
void select_game (void)
{
if (input(pin_b0)==0)
 game1();
if (input(pin_b1)==0)
 game2();
}


Then, in game 1:
Code:
void game1 (void)
{
while (input(pin_c1)==1)
 { ... }
select_game();
}


I understand that this is a loop (select game --> game 1 --> select game), but how to solve it? Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Tue Apr 29, 2014 5:09 am     Reply with quote

Just return....

Your original code is inside 'select_game', and then calls 'game1'. If you return from game1, you are back in select_game. Classic way to force it to execute again, would be to have a flag:
Code:

int1 rescan=FALSE;

void game1 (void)
{
while (input(pin_c1)==1)
 { ... }
   rescan=TRUE;
}   

void select_game (void)
{
  do
  {
      rescan=FALSE;
      if (input(pin_b0)==0)
          game1();
      if (input(pin_b1)==0)
          game2();
  }
  while (rescan);
}   

When you return from the game, if 'rescan' is set, the code loops back to the start of 'select_game', and scans again.

Best Wishes
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Apr 29, 2014 5:21 am     Reply with quote

Why can you not do something this?
Code:
while (1)
{
   if (input(pin_b0)==0) { game1(); }
   if (input(pin_b1)==0) { game2(); }
}


void game1 (void)
{
   while (input(pin_c1)==1)
   { ... }
}

void game2 (void)
{
   while (input(pin_c2)==1)
   { ... }
}

Mike
potato



Joined: 23 Mar 2014
Posts: 16

View user's profile Send private message

PostPosted: Mon May 19, 2014 3:11 am     Reply with quote

Ttelmah wrote:
Just return....

Your original code is inside 'select_game', and then calls 'game1'. If you return from game1, you are back in select_game. Classic way to force it to execute again, would be to have a flag:
Code:

int1 rescan=FALSE;

void game1 (void)
{
while (input(pin_c1)==1)
 { ... }
   rescan=TRUE;
}   

void select_game (void)
{
  do
  {
      rescan=FALSE;
      if (input(pin_b0)==0)
          game1();
      if (input(pin_b1)==0)
          game2();
  }
  while (rescan);
}   

When you return from the game, if 'rescan' is set, the code loops back to the start of 'select_game', and scans again.

Best Wishes


that's fantastic! I haven't answered for a while 'cause I had some other problems and the main code wasn't working... let alone the recursion! Now that everything's working I could finally try it out and it works perfectly, many thanks!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group