Hi everyone,
================
Summary / TL;DR :
I have an OpenMV M7 Board. Memory allocation error. Unsure on how to produce frozen code.
Questions :
- Can I follow methods 1 and 2 listed below for my OpenMV M7 or do I lack the correct files ?
- If so, can I do anything about it, or is it impossible for an OpenMV M7 ?
- Is there an option 3 ? Ideally I’d like to cross-compile my frozen code and then load it onto the board.
Answers so far :
- => apparently it’s possible to build a frozen code-capable firmware. OpenMV M7 uses the OPENMV3 firmware version
- => if I understand correctly, there is no way to simply load code that’s been frozen on Ubuntu on the OpenMV
- => threading is not supported so far ; this seems to be the root cause of the memory problem
============
THE PROBLEM
I use Ubuntu 4.15.0-51-generic x86_64.
I have an OpenMV M7 Board with default firmware.
It’s barely used, mostly for running a few examples in OpenMV IDE and testing a UART-based GPS logger through minicom.
I’ve written what seems to be a pretty memory-thrifty code (see at end of post) compared to some of the imaging sample applications that seem to run fine, but when testing it, it get this error :
MemoryError: memory allocation failed, allocating 4096 bytes
I don’t know exactly why, I’ve only been working with this board for a few days. But one fix coming to mind would be to run frozen code. Even if I could use another method now, the bigger programs that will follow will require frozen code.
So far, I’ve read about 2 methods of going about it :
- Building and loading a new firmware : https://forums.openmv.io/viewtopic.php?p=3401#p3401
- Building (and loading?) a purpose-build mpy-cross binary for the STM32F765VI : GitHub - openmv/micropython: The Micro Python project
But I have a few problems :
- Problem with method #1 : in the github firmware folder, I don’t see an OPENMV7 folder. It stops at OPENMV4. Although I don’t know if the “M7” in “OpenMV M7” means that I have to have an “OPENMV7” firmware version. Is it the case ?
- Problem with method #2 : same thing, really. In the github board folder, I can see a few STM32F7 supported, but not the STM32F765VI. Do I need an exact match, or can I use another STM32F7 version to produce a working mpy-cross?*
- Problem with #1 and #2 : If I understand correctly, these 2 options require flashing a new firmware onto the board, but I’m uneasy about it. I would feel much more comfortable if I could cross-compile on Ubuntu and then upload frozen code files onto the OpenMV. Is that feasible ?
========
MY CODE (nothing else after this section)
The micropyGPS.py file can be found at micropyGPS/micropyGPS.py at master · inmcm/micropyGPS · GitHub
And here is my code (could be faulty, I haven’t had the chance to really test it).
The memory exception happens when calling gpst.start() :
from micropyGPS import MicropyGPS
#import micropyGPS
from machine import UART
import _thread
#from time import time
class JwGPSThread(MicropyGPS):
UPDATE_PERIOD_SEC = 1
TIMEOUT_SEC = 1
def __init__(self, uart):
# using GMT +1 as time offset
MicropyGPS.__init__(self, 1)
self._running = False
self._thread_joined = False
self._uart = uart
def start(self, period_sec=None):
if period_sec is None:
period_sec = self.UPDATE_PERIOD_SEC
_thread.start_new_thread(self.update_loop, ())
def stop(wait_for_join=False):
self._running = False
if wait_for_join:
return self.join()
else:
return True
def join(self, timeout_sec=None):
if timeout_sec is None:
timeout_sec = self.TIMEOUT_SEC
start_time = time.time()
while True:
if time.time() > start_time + timeout_sec:
return False
if self._thread_joined:
return True
def update_loop(self, period_sec=None):
if period_sec is None:
period_sec = self.UPDATE_PERIOD_SEC
self._running = True
self._thread_joined = False
line = ""
while self._running:
start_time = time.time()
end_time = start_time + period_sec
line = self._uart.readline().decode()
for c in line:
self.update(c)
print(".", end="")
time.sleep(end_time - time())
self._thread_joined = True
if __name__ == "__main__":
uart = UART(3, 9600, timeout_char=10)
uart.init(9600, bits=8, parity=None, stop=1)
print("jw_gps_thread main")
gpst = JwGPSThread(uart)
printout = False
gpst.start()
s = ""
while(True):
s = input("> ")
if s == "q":
break
elif s == "h" or s == "help":
print("q, h/help, u, p, s, tstart, tstop, tjoin, tshow")
elif s == "p":
printout = not printout
elif s == "tstart":
gpst.start()
elif s == "tstop":
gpst.stop()
elif s == "tjoin":
print("Joining... ", gpst.join())
elif s == "tshow":
print("LAT=",gpst.latitude)
print("LON=",gpst.longitude)
print("TIM=",gpst.timestamp)
else:
print("Unknown command")
# end while
gpst.stop()
print("Joining... ", gpst.join())