• AVR Freaks

AnsweredRecursion PIC18F26K20

Author
MicPic
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2019/05/28 03:53:55
  • Location: 0
  • Status: offline
2019/07/11 04:21:54 (permalink)
0

Recursion PIC18F26K20

Hey guys,
i run
MPLAB X IDE v5.20
MPLAB ICD 3
XC8 1.34
I use free compiler mode
and so i receive warning ":: warning: (1273) Omniscient Code Generation not available in Free mode"
but on top of that i receive:
"(1089) recursive function call to "__I2CAsync_ContinueRxd"
(908) exit status = 1
when i click on the error it brings me to the declaration of the "__I2CAsync_ContinueRxd" Method which i present you in the following
 
void _I2CAsync_ContinueRxd(void) 
{
    if (_i2c_rx_buffer == NULL)
    {
        return;
    }
    if (_i2c_rx_buf_size <= 0)
    {
        return;
    }
    
    if ((_i2c_rx_buf_size-1) == 0)
    {
        _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(0);
    }
    else
    {
        _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(1);
    }
    
    _i2c_rx_buf_size--;
    if (_i2c_rx_buf_size == 0)
    {
        _i2c_rx_buffer = NULL;
    }
    
    // fireEvent(EV_I2CAsync_Rx_Event);
    if (_i2c_rx_buf_size == 0)
            {
                _i2c_rx_buffer = NULL;
                _I2C_stop();
                _i2c_state = I2C_ASYNC_IDLE;
                //fireEvent(EV_I2CAsync_Rx_Done_Event);
            }
            else
            {
                //fakeMethod();
                _I2CAsync_ContinueRxd();
        
            }
}

Do you have any ideas what the recursion problem is here?
 
Yes i found this in the datasheet:
"All the MPLAB XC compilers conform to the ANS X3.159-1989 Standard for program-ming languages (with the exception of the MPLAB XC8 compiler’s inability to allow recursion, as mentioned in the footnote)"
BUT:
As i found this code from another project for the PIC i assume recursion should not be a/the general problem here !? Please let me know where i go wrong here
 
here is the whole error output:
:: warning: (1273) Omniscient Code Generation not available in Free mode
main.c:312: error: (1089) recursive function call to "__I2CAsync_ContinueRxd"
make[2]: *** [dist/default/production/HelloAgain.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
(908) exit status = 1
nbproject/Makefile-default.mk:131: recipe for target 'dist/default/production/HelloAgain.X.production.hex' failed
make[2]: Leaving directory 'C:/Users/bressler-be/MPLABXProjects/HelloAgain.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/bressler-be/MPLABXProjects/HelloAgain.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed

BUILD FAILED (exit value 2, total time: 356ms)
post edited by MicPic - 2019/07/11 04:52:11
#1
MicPic
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2019/05/28 03:53:55
  • Location: 0
  • Status: offline
Re: Recursion PIC18F26K20 2019/07/11 04:29:56 (permalink)
0
https://www.microchip.com/forums/m807636.aspx
 
found my answer here, the compiler does not allow recursion.
well then... thank you ric grin: grin
 
#2
ric
Super Member
  • Total Posts : 22654
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Recursion PIC18F26K20 2019/07/11 04:38:24 (permalink)
+2 (2)
As you will have seen mentioned in that topic, you CAN enable recursion if you switch to the software stack mode, but I would NOT recommend it.
That code in post#1 looks like sloppy programming, and not terribly efficient.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#3
pcbbc
Super Member
  • Total Posts : 1090
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: online
Re: Recursion PIC18F26K20 2019/07/11 08:08:15 (permalink) ☼ Best Answerby MicPic 2019/07/11 23:30:55
+2 (2)
Unless I'm mistaken, isn't it just simple tail recursion? So same as...
void _I2CAsync_ContinueRxd(void) 
{
    while (1)
    {
        if (_i2c_rx_buffer == NULL)
        {
            return;
        }
        if (_i2c_rx_buf_size <= 0)
        {
            return;
        }

        if ((_i2c_rx_buf_size-1) == 0)
        {
            _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(0);
        }
        else
        {
            _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(1);
        }

        _i2c_rx_buf_size--;
        if (_i2c_rx_buf_size == 0)
        {
            _i2c_rx_buffer = NULL;
        }

        // fireEvent(EV_I2CAsync_Rx_Event);
        if (_i2c_rx_buf_size == 0)
        {
            _i2c_rx_buffer = NULL;
            _I2C_stop();
            _i2c_state = I2C_ASYNC_IDLE;
            //fireEvent(EV_I2CAsync_Rx_Done_Event);
            return;
        }
        //fakeMethod();
    }
}

It's still looks like a complete dogs dinner though. pink: pink
#4
MicPic
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2019/05/28 03:53:55
  • Location: 0
  • Status: offline
Re: Recursion PIC18F26K20 2019/07/11 23:38:59 (permalink)
0
Haha well, everything that compiles and does what it is supposed to is what i find to be a nice banquet table full of wine and treatsLoL: LoL
Nevertheless, i decided to edit the code yesterday and it turned out pretty similar to what you gave me here @pcbbc except for i used a "do while" to be sure that the code is beeing executed at least once
 

void _I2CAsync_ContinueRxd(void)                                        
{
   do
   {
         
    if (_i2c_rx_buffer == NULL)                                               
    {
        return;
    }
    if (_i2c_rx_buf_size <= 0)                                               
    {
        return;
    }
    
    if ((_i2c_rx_buf_size-1) == 0)                                             
    {
        _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(0);                            
    }
    else
    {
        _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(1);                        
    }
    
    _i2c_rx_buf_size--;                                                      
    
    if (_i2c_rx_buf_size == 0)                                               
    {
        _i2c_rx_buffer = NULL;                                                 
        _I2C_stop();
        _i2c_state = I2C_ASYNC_IDLE;
    }
   
   } while (_i2c_rx_buf_size != 0);
}

#5
pcbbc
Super Member
  • Total Posts : 1090
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: online
Re: Recursion PIC18F26K20 2019/07/12 02:56:43 (permalink) ☄ Helpfulby MicPic 2019/07/12 06:31:40
+2 (2)
MicPicexcept for i used a "do while" to be sure that the code is being executed at least once

while(1) also executes at least once as it must enter the while condition.  My objective was to make the minimum changes to your presented code so it was clear what I had changed to remove the recursion.
 
But your method is equally valid.  Although it does involve an unnecessary extra test of "_i2c_rx_buf_size != 0".  There was already one of them in the original as well - I see you removed it.
 
Why not...
void _I2CAsync_ContinueRxd(void)                                         
{
    do
    {         
        if (_i2c_rx_buffer == NULL)                                                
        {
            return;
        }
        if (_i2c_rx_buf_size <= 0)                                                
        {
            return;
        }
        
        if ((_i2c_rx_buf_size-1) == 0)                                              
        {
            _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(0);                             
        }
        else
        {
            _i2c_rx_buffer[_i2c_rx_buf_size] = _I2C_rxd(1);                         
        }
        
        _i2c_rx_buf_size--;                                                       

   } while (_i2c_rx_buf_size != 0);
        
    _i2c_rx_buffer = NULL;                                                  
    _I2C_stop();
    _i2c_state = I2C_ASYNC_IDLE;
}

post edited by pcbbc - 2019/07/12 03:06:18
#6
Jump to:
© 2019 APG vNext Commercial Version 4.5