ENOMEM Error when using UDP Broadcast

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
__deets__
Posts: 23
Joined: Sun Aug 20, 2017 4:50 pm

Re: ENOMEM Error when using UDP Broadcast

Post by __deets__ » Fri Aug 17, 2018 8:27 pm

I remebered incorrectly, I thought I could pass them as flags. But I ended up changing my mpconfigport.h or something like that.

The result of this (after having to enable DEBUG_printf also) was as mentioned in the issue: an endless cycle of restarting with a hex-address stacktrace I couldn't decipher further.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: ENOMEM Error when using UDP Broadcast

Post by pythoncoder » Sat Aug 18, 2018 7:40 am

@__deets__ Have you tried putting a time.sleep() in the loop? I can envisage two possibilities. Firstly the vendor code might allocate a resource each time you call sendto(), returning immediately but only releasing the resource when the send is complete.

A second possibility is this. When I last worked with ESP32 I found it necessary to interpose sleep_ms(20) at various points in the code and raised issue 167 - I suggest you read the entire (short) thread. You might want to try machine.idle() as mentioned in that PR.
Peter Hinch
Index to my micropython libraries.

__deets__
Posts: 23
Joined: Sun Aug 20, 2017 4:50 pm

Re: ENOMEM Error when using UDP Broadcast

Post by __deets__ » Sat Aug 18, 2018 11:31 am

Thank you Peter for the suggestion and the enlightening thread.

Adding a sleep_ms(20) as you suggested seems to alleviate the problem. I so far worked around things using TCP instead of UDP which seems to fix it. Might be due to other code changes at well, but so far the system runs stable for longer periods.

But with this new knowledge might roll back to UDP given the nature of my project.

Of course it would be great if this was not a thing a uPy programmer needs to concern themselves with, but I guess that'll get sorted out eventually.

misan
Posts: 3
Joined: Wed May 05, 2021 6:01 am

Re: ENOMEM Error when using UDP Broadcast

Post by misan » Fri May 21, 2021 8:40 am

I have set my ESP32 running MicroPyton v1.15 wifi to AP_IF (access point).

I have the following code that broadcasts a UDP datagram:

Code: Select all

from socket import *
from time import sleep


so = socket(AF_INET, SOCK_DGRAM)

while True:
    sleep(0.5)
    print(gc.mem_free())
    so.sendto(b'misan1', ('255.255.255.255',8888))
And after a few iterations it gives an error (in sendto line):

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
OSError: [Errno 12] ENOMEM
I am puzzled. Using another wifi as STA_IF leads to a similar result.

Any ideas?

misan
Posts: 3
Joined: Wed May 05, 2021 6:01 am

Re: ENOMEM Error when using UDP Broadcast

Post by misan » Fri May 21, 2021 6:52 pm

I am failing trying to replicate that later. I noticed I did not import gc but it was used, so I guess Thonny might have added something else behind the curtains (or I am missing something else).

The point is that after a reset, just using a serial connection I am unable to reproduce the same error. Whatever the cause was, a lack of memory to allocate was not the case and masking the exception caused sendto allowed the program to proceed only occasionally dropping a few sendto.

thewifimaster
Posts: 9
Joined: Fri Oct 08, 2021 5:37 pm

Re: ENOMEM Error when using UDP Broadcast

Post by thewifimaster » Sun Dec 05, 2021 1:04 am

I am running into similar problems on a esp32-s2. As soon as I start to send UDP packets within short intervals, I get OSError 12 and random drop-outs.

The routine I am using (within a much larger context) with uasyncio:

Code: Select all

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(data, ('192.168.1.255', '1234'))
I have not been able to debug the problem, e.g. I get the same results on different firmwares (both v1.16 and v1.17) and different code structures I am using.

Any hints on where to dig deeper?
What does OSError 12 really mean in this context?

Update: I was looking into memory issues of both micropython and the RTOS, which I can't see as the problem. See the output of these commands. I get a reliable fail after the 3rd UDP package sent within a very short period of time, independent of what I try.

Code: Select all

print(esp32.idf_heap_info(esp32.HEAP_DATA))
print(gc.mem_free())
.. try to send UDP package ..

Code: Select all

[(8148, 96, 0, 96), (179144, 58056, 32768, 56360), (14864, 208, 0, 208)]
1996176
S88 event with UDP package sent for: address 1 on Pin(2): False
[(8148, 96, 0, 96), (179144, 57756, 32768, 56184), (14864, 208, 0, 208)]
1995792
S88 event with UDP package sent for: address 2 on Pin(3): False
[(8148, 96, 0, 96), (179144, 57856, 32768, 56184), (14864, 208, 0, 208)]
1995408
S88 event with UDP package sent for: address 3 on Pin(4): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1995024
ERROR - S88 event with UDP package sent for: address 4 on Pin(5): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1994576
ERROR - S88 event with UDP package sent for: address 5 on Pin(6): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1994128
ERROR - S88 event with UDP package sent for: address 6 on Pin(7): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1993680
ERROR - S88 event with UDP package sent for: address 7 on Pin(8): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1993232
ERROR - S88 event with UDP package sent for: address 8 on Pin(9): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1992784
ERROR - S88 event with UDP package sent for: address 99 on Pin(10): False
[(8148, 96, 0, 96), (179144, 57904, 32768, 56184), (14864, 208, 0, 208)]
1992336
ERROR - S88 event with UDP package sent for: address 999 on Pin(11): False

Post Reply