Search code examples
multithreadingmicropythonlora

Micropython RuntimeError: maximum recursion depth exceeded


I'm not using recursion but I think some third party code I'm using has to many nested function calls.

This is the code I used as an example to create my project https://github.com/ehong-tl/micropySX126X

I could create a cut down example but I don't really see the point as you guys would need two of the Pico-Lora-SX126X hardware to execute it. (These are cool little gadgets, they can send text messages to each over very large distances)

The main difference in my code from the example is I'm running this code in a second thread. If run in the primary thread it works so I'm assuming there are less levels deep of function call available to the thread run on the second core.

Basically the second thread is waiting for an incoming Lora message while the main thread is interacting with the user. When a Lora message comes in it triggers the error below.

Here is my hardware and micropython version

MicroPython v1.19.1-746-gf2de289ef on 2022-12-13; Raspberry Pi Pico W with RP2040

Here is the error message

Traceback (most recent call last):
  File "sx1262.py", line 275, in _onIRQ
  File "subprocess.py", line 73, in cb
  File "sx1262.py", line 187, in recv
  File "sx1262.py", line 251, in _readData
  File "sx126x.py", line 483, in startReceive
  File "sx126x.py", line 540, in startReceiveCommon
  File "sx126x.py", line 1133, in setPacketParams
  File "sx126x.py", line 1228, in fixInvertedIQ
  File "sx126x.py", line 1034, in writeRegister
  File "sx126x.py", line 1274, in SPIwriteCommand
  File "sx126x.py", line 1291, in SPItransfer
RuntimeError: maximum recursion depth exceeded

The function SPItransfer appears to be at or around the 10th level. I have not modified any of these functions. I have tried adding a garbage collection here and there but I was just guessing and it didn't make any difference.

Any ideas how I can increase the this depth to allow for more nested functions? Thanks David

Update I found a little script that calls itself to test the possible recursion depth. When run in the primary thread it allows for 39 function calls and 17 function calls when run in the second thread. So this doesn't explain why my project is receiving this error after what appears like 10 levels of function calls.

# Based on an example found here
# https://forum.micropython.org/viewtopic.php?t=3091
import _thread 
a = 0
fail = False

def recursionTest():
    global a, fail
    a += 1
    print("loop count="+str(a))
    if not fail:
        try:
            recursionTest()
        except Exception as errorMsg:
            print(errorMsg)
            fail = True

# Runs in the primary thread
#print("Main thread")
#recursionTest()

# Runs in the second thread
print("Sub thread")
_thread.start_new_thread(recursionTest,())

Output

Sub thread
>loop count=1
loop count=2
loop count=3
loop count=4
loop count=5
loop count=6
loop count=7
loop count=8
loop count=9
loop count=10
loop count=11
loop count=12
loop count=13
loop count=14
loop count=15
loop count=16
loop count=17
maximum recursion depth exceeded

Solution

  • I'm not sure why but I needed to put my change to the stack size immediately before the call to start the second thread or it seemed to make no difference.

    Like this

    _thread.stack_size(5*1024)    
    _thread.start_new_thread(recursionTest,())
    

    I only needed to increase by 1kb from the default 4kb for the second thread for my program to succeed. Hope this helps someone else.