Writing new C API into micropython firmware

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Firas_Baccouri
Posts: 19
Joined: Wed Apr 27, 2022 7:22 am

Re: Writing new C API into micropython firmware

Post by Firas_Baccouri » Wed Jun 22, 2022 2:38 pm

Thank you Jimmo for that https://github.com/micropython/micropython/pull/8089 , I have implemented it and it works and now I can use my Handmade SPI .
But the question still is there any possibility to use some array in a C module so you can than use it by the python code ?

User avatar
jimmo
Posts: 2459
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Writing new C API into micropython firmware

Post by jimmo » Thu Jun 23, 2022 4:01 am

Firas_Baccouri wrote:
Wed Jun 22, 2022 2:38 pm
But the question still is there any possibility to use some array in a C module so you can than use it by the python code ?
Yes you can construct any Python object (e.g. array, or bytearray, or bytes) and return that from your C module.

Firas_Baccouri
Posts: 19
Joined: Wed Apr 27, 2022 7:22 am

Re: Writing new C API into micropython firmware

Post by Firas_Baccouri » Thu Jun 23, 2022 6:47 am

jimmo wrote:
Thu Jun 23, 2022 4:01 am
Firas_Baccouri wrote:
Wed Jun 22, 2022 2:38 pm
But the question still is there any possibility to use some array in a C module so you can than use it by the python code ?
Yes you can construct any Python object (e.g. array, or bytearray, or bytes) and return that from your C module.
No I didn´t meant that , I mean is there any possibility to create a C module and that module contain some functionality that takes arrays as input and than use this functionality from the python code , actually I have tried to do that and I have passed mp_obj_list_t or mp_obj_array_t but it didn´t work and the " MP_DEFINE_CONST_FUN_OBJ_X( ) " function doesn´t accept that so I won´t be able to implement a functionality that takes array for example as a parameter .

User avatar
jimmo
Posts: 2459
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Writing new C API into micropython firmware

Post by jimmo » Thu Jun 23, 2022 10:16 am

Firas_Baccouri wrote:
Thu Jun 23, 2022 6:47 am
actually I have tried to do that and I have passed mp_obj_list_t or mp_obj_array_t
Functions must take mp_obj_t as arguments, but the thing to remember is that these are any Python objects.

If the object supports the buffer protocol (e.g. bytearray, bytes, str) then you can get the bytes from it via mp_get_buffer. If it's a list or array then you can use mp_getiter. Otherwise you have to check its type and then use MP_OBJ_TO_PTR and cast to the relevant struct.

Firas_Baccouri
Posts: 19
Joined: Wed Apr 27, 2022 7:22 am

Re: Writing new C API into micropython firmware

Post by Firas_Baccouri » Thu Jun 23, 2022 1:00 pm

jimmo wrote:
Thu Jun 23, 2022 10:16 am
Firas_Baccouri wrote:
Thu Jun 23, 2022 6:47 am
actually I have tried to do that and I have passed mp_obj_list_t or mp_obj_array_t
Functions must take mp_obj_t as arguments, but the thing to remember is that these are any Python objects.

If the object supports the buffer protocol (e.g. bytearray, bytes, str) then you can get the bytes from it via mp_get_buffer. If it's a list or array then you can use mp_getiter. Otherwise you have to check its type and then use MP_OBJ_TO_PTR and cast to the relevant struct.
ah , ok , so I went to check into the micropython firmware about : mp_get_buffer() and mp_getiter() :
1 :it might be there are some documentation missed because I didn´t understand all the parameters of both of that two functions .
2 :This two functions returns a mp_obj_t , so I want to know how my list , bytearray ,str ... is stored into a variable of mp_obj_t so I can Know how I can itterate it to use each element of it .

Thank you Jimmo for all the informations , I really appreciat it .

User avatar
jimmo
Posts: 2459
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Writing new C API into micropython firmware

Post by jimmo » Thu Jun 23, 2022 2:02 pm

Firas_Baccouri wrote:
Thu Jun 23, 2022 1:00 pm
ah , ok , so I went to check into the micropython firmware about : mp_get_buffer() and mp_getiter() :
1 :it might be there are some documentation missed because I didn´t understand all the parameters of both of that two functions .
2 :This two functions returns a mp_obj_t , so I want to know how my list , bytearray ,str ... is stored into a variable of mp_obj_t so I can Know how I can itterate it to use each element of it .
Yes, this is an area of the documentation that is very lacking. Mostly you have to learn this by looking at existing code. Generally what I recommend is thinking of a Python standard library function that behaves similarly to what you want, and then go and look at the code that implements that.

The key thing is that an mp_obj_t is just a number that can either represent a small integer, an interned string, or a pointer to a Python object (i.e. a pointer to a struct that has `mp_obj_base_t base;` as its first member). For the details of how mp_obj_t works, see https://github.com/micropython/micropyt ... nfig.h#L93

So a function that is exposed to Python must take all its arguments as mp_obj_t and return an mp_obj_t. You can construct an mp_obj_t using methods like mp_obj_new_int or mp_obj_new_str or MP_OBJ_FROM_PTR. You can convert an mp_obj_t into whatever you need using methods like mp_get_buffer, mp_getiter, mp_obj_get_type, MP_OBJ_TO_PTR, etc.

So for example, if you have a argument that is a list (or tuple, or anything that is iterable, i.e. you could use with a `for` loop in Python), and you just want to iterate it, then you use mp_getiter.

Unfortunately I don't quite understand what your function does or what the arguments are, otherwise I could give you more specific hints about which methods you need to use.

Firas_Baccouri
Posts: 19
Joined: Wed Apr 27, 2022 7:22 am

Re: Writing new C API into micropython firmware

Post by Firas_Baccouri » Thu Jun 23, 2022 2:14 pm

Actually my function will take a list or a bytearray and than in the C part I want to itterate this variable and use each element of it to send it through my Handmade SPI .

User avatar
jimmo
Posts: 2459
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Writing new C API into micropython firmware

Post by jimmo » Fri Jun 24, 2022 12:34 am

Firas_Baccouri wrote:
Thu Jun 23, 2022 2:14 pm
Actually my function will take a list or a bytearray and than in the C part I want to itterate this variable and use each element of it to send it through my Handmade SPI .
if it's a list, then use mp_getiter. If it's a bytearray, then mp_get_buffer. If it can be either, then first try mp_get_buffer (this will return false if it isn't a buffer), then try mp_getiter (which will raise if it isn't iterable).

Firas_Baccouri
Posts: 19
Joined: Wed Apr 27, 2022 7:22 am

Re: Writing new C API into micropython firmware

Post by Firas_Baccouri » Fri Jun 24, 2022 6:48 am

jimmo wrote:
Fri Jun 24, 2022 12:34 am


if it's a list, then use mp_getiter. If it's a bytearray, then mp_get_buffer. If it can be either, then first try mp_get_buffer (this will return false if it isn't a buffer), then try mp_getiter (which will raise if it isn't iterable).
Yes I figured out that I am going to use mp_getiter() , but I didn´t know what is its first parameter , the second one it is obvious that it will be the list but the first one it is not pretty clear .

And then this function will return a mp_obj_t so could I iterate each element of my list (input) by iternext() function and then I will get each element and change its type to integer by mp_get_int() and send it through my SPI .

Firas_Baccouri
Posts: 19
Joined: Wed Apr 27, 2022 7:22 am

Re: Writing new C API into micropython firmware

Post by Firas_Baccouri » Fri Jun 24, 2022 9:18 am

Hey Jimmo ,
Thank you for your help , I get it done and it works correctly now.

Post Reply