Introduction to developing MicroPython #5 — MicroPython API design and methods


MicroPython is a script language whereas C is not, so there are a lot of rules we have to follow to make Python compiler understand our C code.

We have discussed how to create a new module from scratch previously, so in today’s article, the common MicroPython API design will be discussed. note this is for advanced users who intend to write their own C module for MicroPython RTL8722 port.

API Design

Let’s take ADC module as an example,

MicroPython ADC api reference

STATIC mp_obj_t adc_read(mp_obj_t self_in) {
    adc_obj_t *self = self_in;
    uint16_t value = analogin_read_u16(&(self->obj));
    return mp_obj_new_int(value);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);

There are a few things we need to take note:

1. Almost all MicroPython API has to be declared as “STATIC mp_obj_t” return type

This is so to make sure the return type is a void pointer and thus can be easily utilized by MicroPython core and casted to other data type if needed

2. Always return using built-in return function

In the 4th line of the code above, we see the unsigned integer 16-bit variable value was returned using “mp_obj_new_int” API, this API can be found in “obj.h” file, and over there there are alot more other APIs at your disposal.

Since the return type is void pointer, so we have to use these API found in obj.h to type cast it to the correct format and then pass back to user.

3. This API adc_read takes in an mp_obj_t parameter — self_in

This step is not compulsory and is essential if you want a stable structure, as self_in was previsouly pointed to an instance of a structure whose first element is of type of mp_obj_base_t, this is an essential element while MicroPython’s compiler is working.

However, the API’s parameter can take many different forms to cater to various situation, this is a huge topic and will be discussed in the future.

4. The API was linked to its dedicated object using MP_DEFINE_CONST_FUN_OBJ_1

In the last line of the above code, we can see adc_read was linked to adc_read_obj using MP_DEFINE_CONST_FUN_OBJ_1( ) API, this MicroPython built-in API not only do the linking but also tell the compiler that this API only takes in 1 parameter, thus if your API needs 2 paramenter, you need to use MP_DEFINE_CONST_FUN_OBJ_2 instead, so on and so forth.

5. The body of the API follows the same rules as normal C function

Step 3 and Step 4 is a huge topic

As Python can handle same API with different types, numbers and names of parameter, handling this in MicroPython is also required. As there are too many cases to be discussed, this topic will be saved to the next article

Hope you enjoy and happy coding ! :sunglasses: