Apologies in advance if this is rambling text, I'm not 100% sure of what I know I know at this point.
I am working with the Portenta X8, which is a great little board, but as it's fairly new, I haven't seen much by way of documentation/examples/tutorials beyond the morsels given by Arduino.
I have the STM32H7, hereon M4, core doing some real-time tasks such as operating a display and writing data out to some SD cards in series. I am trying to send the data to be written out from the IMX8, hereon X8, core to the M4 core using honestly anything that works. I feel like I am so close to understanding how to make this work, but I'm hoping someone who knows more can help me get there.
I was able to run this tutorial here that involves both sending Serial messages to the X8 core from the M4 core, as well as calling M4's functions from the X8. I also was able to successfully send parameters to the M4's functions such as an integer. However, I can't seem to figure out how I would send an array. Particularly, I want to send a string, and figured a c string was my best bet. However, pointers do not behave well with the RPC in that I can't .bind a function on the M4 that takes a pointer, probably due to how the RPC was implemented.
Instead, I think trying to send devices via Serial would be my best bet. I found these example Arduino sketches for the M4 to act as a "Serial Passthrough" or an echo server. However, the accompanying code for the Linux side is not present in the files. I see one python file that seems to not do anything involving Serial. The Go files seem to be the code for the m4-proxy that lives on the Linux side of things and is what the programs that want to talk to the M4 board actually talk to. I also see in the example I specifically linked that there is reference to both RPC as a print stream device as well as Serial. I'm not sure which one actually goes where though. I'm trying to read through the examples and reference the diagram I attached to trace my way through.
My best guess is that I need to, on the Linux side, use the RPC client as in the example code, to .call a specific function on the m4 proxy or some other method of the RPC client.
So I haven't found the answer to calling an M4 function and giving a string, array, or double, but I imagine that the trick is understanding the implementation of both msgpack-rpc-python and Arduino's RPC library on the M4 core and using struct or ctypes or something to pass something digestible to the Arduino sketch (although msgpack seems to allegedly take care of this already?).
I posted the following comment on another thread with a similar question that shows how to at least send to the Arduino core's Serial object:
When you want to read the bytes from the Serial object on the M4, you can use the msgpack-rpc-python library and docker as shown in this tutorial (the suggested debug method/code for the actual tutorial is what I'm referring to) to let the m4-proxy/RPC/etc. know you want to be bound (?) to "tty" in this line:
result = client.call('register', 5005, ['tty'])
If you follow the regular tutorial at that link, you will will be sending calls to invoke functions on the M4 core. You can modify the code given to generate the docker image/container by changing the call to refer to "tty" also. You may call it and provide a string argument by doing rpc_client.call("tty", "abcdefg") and this will be available on the M4 as usual with the Serial object. So my modified python code for the container is now:
from msgpackrpc import Address as RpcAddress, Client as RpcClient, error as RpcError
# Fixed configuration parameters
port = 8884
# The M4 Proxy address needs to be mapped via Docker's extra hosts
m4_proxy_address = 'm4-proxy'
m4_proxy_port = 5001
rpc_address = RpcAddress(m4_proxy_address, m4_proxy_port)
rpc_client = RpcClient(rpc_address)
rpc_client.call('tty', 'abcdefg')
Also, the Dockerfile given in the tutorial uses a lower version of python, which seemed to cause some import errors with msgpack-rpc-python, something about the module "backports" not being found. I was using python:3.11-slim-bookworm as an image instead of what they had for other things on the Portenta, so I switched to that image which by my luck avoids that error.
It's also worth noting that I had to switch the docker-compose.yaml file's entry for the extra-hosts to be (found on some forum):
extra_hosts:
- "m4-proxy:host-gateway"
The trick for me was that although there is no real typical UART Serial between the M4 and IMX8 core, the code for the M4 core seems to just wrap up RPC calls and listens to the "tty" service (?) with a Serial/PrintStream object.
For me strings were confusing so i replaced them with int values. That way the rpc has no issue. I also had the problem with array's or vectors or structs. Found out that by standard rpc transfers a tuple. so if you make sure it's a tuple on the arduino side and a tuple on the python side there shouldn't be a problem.
1 Like