Passing variables between C and Python

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Passing variables between C and Python

Post by cduran » Wed May 04, 2016 7:09 pm

I am very new to MP and to Python in general. Let me start by saying that I want to use MP to execute byte code that comes precompiled using the cross platform MP compiler. I want to be able to pass a C variable into and out of that byte code. Basically all my hardware will be handled in C, mostly because of the complexity of it, and I will be using MP to handle logic only. This logic will be updatable on the fly without recompiling my firmware. For me to be able to do this I have to have a way to provide the byte code input from the C code and provide output to the C code.

Does this mechanism exist in MP?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Passing variables between C and Python

Post by dhylands » Wed May 04, 2016 10:29 pm

There are several options available depending on what exactly you want to put into the variables and whether they need to be touched by the python code or not.

You should probably look at the ctypes and struct modules in CPython. In MP, you'll find uctypes and ustruct:
http://docs.micropython.org/en/latest/p ... types.html
http://docs.micropython.org/en/latest/p ... truct.html

You can call C functions from MP by registering the C functions as part of a module. All of the peripheral libraries are done this way, for example i2c:
https://github.com/micropython/micropyt ... mhal/i2c.c

I'd start at the end of the file and work backwards. The last part creates a type, and has a bunch of methods (init, deinit, is_ready, etc). The function objects have the pointer to the actual function, and the arguments essentially wind up beint mp_obj_t's (which is MP's object representation).

You can find the various function declaration macros here:
https://github.com/micropython/micropyt ... #L270-L295

An examples of C code calling python can be found here:
https://github.com/micropython/micropyt ... er.c#L1355

miltmobley
Posts: 30
Joined: Mon Mar 07, 2016 11:44 pm

Re: Passing variables between C and Python

Post by miltmobley » Mon May 09, 2016 8:28 pm

I see from timer.c how callbacks are called from irq.c, and how Python calls to methods of builtin classes implemented in c are handled,
but I have a different requirement:

I would like to use Python to call "module global functions" of c modules. In standard Python, a module (file) containing a class
definition may also contain ordinary function definitions outside any class, for example a class factory. These are sometimes
called module global functions or module level functions. If I have implemented a network device in Python, I might want it
to call this function in modnetwork.c:

void mod_network_register_nic(mp_obj_t nic)

Is there an existing mechanism to do this, or do I have to figure out how the interpreter would do so, and emulate that?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Passing variables between C and Python

Post by dhylands » Mon May 09, 2016 11:43 pm

The modmachine module is basically a collection of global functions:
https://github.com/micropython/micropyt ... dmachine.c

One quirk to be aware of is that ALL python functions return something. So the C prototype will always return an mp_obj_t. If the function doesn't logically return anything, then it should return mp_const_none.

Code: Select all

>>> def foo():
...   print('abc')
... 
>>> x = foo()
abc
>>> print(x)
None

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Passing variables between C and Python

Post by cduran » Tue May 10, 2016 6:04 pm

I think the uctypes are what I need. I just need to pass an array that the python code will operate on. The part I don't quite understand is how do I actually define that array in C. The documentation doesn't talk about the C side of things, unless I'm completely misunderstanding something.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Passing variables between C and Python

Post by dhylands » Tue May 10, 2016 6:38 pm

I guess the details depend on who allocates the array (C or python).

What type of data will live in the array?

Python has some specialized types of arrays, like bytearray, and a more generic array of same sized items.

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Passing variables between C and Python

Post by cduran » Tue May 10, 2016 6:49 pm

dhylands wrote:I guess the details depend on who allocates the array (C or python).

What type of data will live in the array?

Python has some specialized types of arrays, like bytearray, and a more generic array of same sized items.
The array will be allocated in C. It will be an array of same sized items, but a byte array would work well.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Passing variables between C and Python

Post by dhylands » Tue May 10, 2016 7:48 pm

The function mp_obj_new_bytearray https://github.com/micropython/micropyt ... obj.h#L605 will allocate a bytearray and populate it with the data passed in.

The mp_obj_new_bytearray_by_ref will allocate a bytearray object, but it will point to the data passed in. You can see the implementations here: https://github.com/micropython/micropyt ... #L583-L598

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Passing variables between C and Python

Post by cduran » Wed May 11, 2016 2:50 pm

dhylands wrote:The function mp_obj_new_bytearray https://github.com/micropython/micropyt ... obj.h#L605 will allocate a bytearray and populate it with the data passed in.

The mp_obj_new_bytearray_by_ref will allocate a bytearray object, but it will point to the data passed in. You can see the implementations here: https://github.com/micropython/micropyt ... #L583-L598
Am I right to assume that only one data structure can be shared between python and C? I don't see a way in Python to access the C variable by name.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Passing variables between C and Python

Post by dhylands » Wed May 11, 2016 3:17 pm

What you can share between python and C is rather arbitrary.

No - you can't access C variables by their C name. However you can call a C function to return the address of arbitrary things. Once you've got that pointer, you can then use uctypes or ustruct to access that data in an arbitrary fashion.

Post Reply