The PYNQ Microblaze infrastructure is built on top of a remote procedure call (RPC) layer which is responsible for forwarding function calls from the Python environment to the Microblaze and handling all data transfer.
Supported Function Signatures¶
The RPC layer supports a subset of the C programming language for interface functions, although any functions may be used internally within the Microblaze program. Any function which does not conform to these requirements will be ignored. The limitations are:
unionfor either parameters or return types.
- No returning of pointer types
- No pointers to pointers
All return values are passed back to Python through copying. The transfer of function arguments depends on the type used. For a given non-void primitive the following semantics:
- Non-pointer types are copied from PYNQ to the microblaze
- Const pointer types are copied from Python to the Microblaze
- Non-const pointer types are copied from Python to the Microblaze and then copied back after completion of the function.
The timeline of the execution of the function can be seen below:
struct module is used to convert the Python type passed
to the function into the appropriately sized integer or floating point
value for the Microblaze. Out of range values will result in an
exception being raised and the Microblaze function not running. Arrays
of types are treated similarly with the
struct module used to
perform the conversion from an array of Python types to the C array. For
non-const arrays, the array is updated in place so that the return
values are available to the caller. The only exception to these
conversion rules are
const char pointers which are
optimised for Python
bytes types. Note that
calling a function with a non-const
char* argument with a
object will result in an error because
bytes objects are read-only.
This will caught prior to the Microblaze function being called.
For non-void return functions, the Python functions are synchronous and
will wait for the C function to finish prior to returning to the caller.
For functions that return void then the function is called
asynchronously and the Python function will return immediately. This
entails long-running, independent functions to run on the Microblaze
without blocking the Python thread. While the function is running, no
other functions can be called unless the long-running process frequently
yield.h) to allow the RPC runtime to service
requests. Please note - there is no multi-threading available inside the
Microblaze so attempting to run two long-running processes
simultaneously will result in only one executing regardless of the use
The RPC engine fully supports typedefs and provides an additional
mechanism to allow for C functions to appear more like Python classes.
The RPC layer recognises the idiom where the name of a typedef is used
as the prefix for a set of function names. Taking an example from the
PYNQ Microblaze library, the
i2c typedef has corresponding functions
i2c_write which take an
i2c type as the first
parameter. With this idiom the RPC creates a new class called
write methods. Any C functions returning an
i2c typedef now return an instance of this class. For this
conversion to be done, the following three properties must hold:
- The typedef is of a primitive type
- There is at least one function returning the typedef
- There is at least one function named according to the pattern