-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OSError exception [Errno 4] EINTR when running motors in EV3 #727
Comments
If you are using MicroPython instead of regular Python, it does not implement PEP 475 |
If I understand correctly, with micropython, if a system call fails, the underlying code will not retry to make the call and instead it will throw an OS exception. Therefore the only work around is to handle the exception the best you can? |
Yeah, as it is now, that is correct: you have to handle it manually. I'm somewhat surprised it happens that often for you. |
It does happen to me very often, every 6 to 7 cicles I get an exception. For now I am hyandling it by reissuing the exact same command when the exception is handled but I am very supprised that with somethingas simple I need to be worring about exceptions. Just to give you an idea, here is my code that runs on a thread:
With this code I get the exception but the motor still does what is supposed to. |
Sorry for the delay on this! I don't have a good immediate answer here -- this definitely isn't a great experience, but I think the only real solution would be to add our own wrapper here and I'm somewhat concerned about perf. Is it possible this is specifically due to the threading? If you only use one thread does this still happen? |
Hi. |
In MicroPython, threads use a signal to trigger the garbage collector, so this makes sense. Without threads, there are no signals to cause the EINTR. |
So, do you see a solution for this. It is anoying not being able to use the motors from within threads without continuosly getting exceptions. |
@orioldelos see if the patch in #704 helps? |
I wouldn't expect it to (?). I think David is exactly right — the reason there are so many |
I am willing to try it but I have never made any modifications to micropython libraries. As I can see what I have installed are .mpy files wich i can't edit with a text editor. |
FYI, I have been working on fixing this in upstream MicroPython. micropython/micropython#5723. However, I don't expect this fix to be backported to ev3dev-stretch. |
So the way it is looking, if I wish to use threads with ev3dev2 I better switch to Python instead of working with micropython. |
The simple answer here is "yes". The more nuanced answer: I opened #732 last night, which will let us compare timing benchmarks before/after code changes. Pending some discussion over there, my next step will be to add a try/catch around the access code and see if it degrades performance. If not, I'll check that in, and your problem will be solved for micropython too in the next release. If it does affect performance, we'll have to discuss what might make the most sense. Below I included a way you can make this change specifically for your program and test it out. For your case: if you switch to plain Python, this issue will indeed be avoided. Normal CPython will be slower than Micropython when starting up and somewhat slower at executing code, depending on what exactly you're doing. Another option for you is to manually monkey-patch in the retry code from your own program; cursory testing shows this at least functions for reading properties (not including writing properties or commands): import errno
from ev3dev2 import Device
def _get_attribute(self, attribute, name):
"""Device attribute getter"""
for _ in range(5): #added
try:
if attribute is None:
attribute = self._attribute_file_open(name)
else:
attribute.seek(0)
return attribute, attribute.read().strip().decode()
except OSError as ex: #added
if ex.errno == errno.EINTR:
continue
else:
self._raise_friendly_access_error(ex, name, None)
except Exception as ex:
self._raise_friendly_access_error(ex, name, None)
Device._get_attribute = _get_attribute
from ev3dev2.motor import Motor
m = Motor()
print(m.speed) You would put this code (except for the last three lines) at the top of your own program. This is a modified version of this: ev3dev-lang-python/ev3dev2/__init__.py Lines 253 to 262 in af12545
You could do a similar thing with |
uname -r
HERE4.14.117-ev3dev-2.3.4-ev3
dpkg-query -l {python3,micropython}-ev3dev*
HEREI have the following code runing on a thread in micropython with the only intention of moving the motor back and forth:
I was forced to handle the exception to avoid the aplication from aborting each time an OSError exception [Errno 4] EINTR was thrown.
I believe this might be a bug. Am I running the latest versions of Ev3dev2?
The text was updated successfully, but these errors were encountered: