ESP32 Calling MicroPython from C module

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Damianvv
Posts: 5
Joined: Mon Feb 17, 2020 12:52 pm

ESP32 Calling MicroPython from C module

Post by Damianvv » Thu Mar 05, 2020 12:43 pm

Hello,

From MicroPython i can call C functions off of a C module, with the help of this tutorial:
https://docs.micropython.org/en/latest/ ... dules.html

Now, i'm trying to call a MicroPython function from this C module. With regular Python and C this can be done by importing Python.h on the C module and then following some steps to call the Python function. With this method functions can also be inserted into Python from C.

In MicroPython however, i cannot import Python.h from Python3.7 because i am met with hierarchical errors (Which makes sense because isn't ment for the ESP32), and i am unable to find a Python.h (Or anything that represents it) in the MicroPython repository.

Therefore my question; does anyone know how i can achieve calling a MicroPython function from C? Or maybe what steps i could follow in order to create my own Python.h in MicroPython

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: ESP32 Calling MicroPython from C module

Post by stijn » Thu Mar 05, 2020 4:48 pm

i am unable to find a Python.h (Or anything that represents it) in the MicroPython repository
Look at runtime.h, functions like mp_call_function_n_kw are what's used to call micropython functions.

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

Re: ESP32 Calling MicroPython from C module

Post by jimmo » Thu Mar 05, 2020 11:42 pm

The user C modules (other than the way they're built) are completely identical in operation to the built-in modules. So any file named mod*.c in the MicroPython code base will likely provide a useful reference to how to do things.

For this particular case, yeah as stjin says, look for uses of functions like mp_call_function_n_kw...etc.

Damianvv
Posts: 5
Joined: Mon Feb 17, 2020 12:52 pm

Re: ESP32 Calling MicroPython from C module

Post by Damianvv » Fri Mar 06, 2020 12:54 pm

Thanks for the feedback, i got it to work! This is what i did:

Code: Select all

module.py:
    def hello():
         print('Hello')

module.c:
    qstr qst = qstr_from_str("hello");
    mp_obj_t found = mp_load_global(qst);
    mp_call_function_n_kw(found, 0, 0, NULL);
Once executed:

Code: Select all

Hello
MicroPython v1.11-611-g7f24c2977-dirty on 2020-03-06; ESP32 module with ESP32
I am not out of the clear completely just yet though, i'm trying to call a function from MicroPython in C whilst using multiprocessing, so after i called xTaskCreatePinnedToCore, but this panic's my core.
So taking the above example:

Code: Select all

def c_process() 
{
    qstr qst = qstr_from_str("hello");
    mp_obj_t found = mp_load_global(qst);
    mp_call_function_n_kw(found, 0, 0, NULL);
}
and then calling:

Code: Select all

xTaskCreatePinnedToCore(c_process, "Task1", 10000, NULL, 1, NULL,  1);
This produces

Code: Select all

'Core 1 panic'd (LoadProhibition)'
I am aware the function called by xTaskCreatePinnedToCore should not return, however it would give a different error.
The LoadProhibition error occurs when the application tries to read or write to invalid memory.
Specifically the 'mp_obj_t found = mp_load_global(qst);' line causes the error, where qst == "hello"

Error code:

Code: Select all

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x400df4f4  PS      : 0x00060030  A0      : 0x800f4510  A1      : 0x3ffe2aa0
A2      : 0x00000429  A3      : 0x00000002  A4      : 0x00060023  A5      : 0x0000abab
A6      : 0x00000020  A7      : 0x00000020  A8      : 0x000010a4  A9      : 0x3ffe2a80
A10     : 0x00000000  A11     : 0x00000005  A12     : 0x000000ff  A13     : 0x0000ff00
A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x00000000  EXCCAUSE: 0x0000001c
EXCVADDR: 0x0000000c  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffe

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x400df4f4:0x3ffe2aa0 0x400f450d:0x3ffe2ac0 0x4008a319:0x3ffe2ae0

Rebooting...
Anyone got a clue as to why this might be? I'm having a hard time finding a good answer.

EDIT: The proces created by xTaskCreatePinnedToCore has a seperate memory and RAM, which has no knowledge of the memory the pointer is pointing at. Hence why i can't call the function from the new process. I will try to find a way to solve this.

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

Re: ESP32 Calling MicroPython from C module

Post by jimmo » Sun Mar 15, 2020 11:54 pm

Damianvv wrote:
Fri Mar 06, 2020 12:54 pm
EDIT: The proces created by xTaskCreatePinnedToCore has a seperate memory and RAM, which has no knowledge of the memory the pointer is pointing at. Hence why i can't call the function from the new process. I will try to find a way to solve this.
I'm not quite sure what you mean by this -- I wasn't aware that the ESP32 had this sort of MMU-like functionality.

The more likely explanation is that MicroPython relies on a certain amount of thread-local state, so you can't just call in and out of the MicroPython VM from other threads -- they must also be MicroPython threads. Have a look at ports/esp32/mpthreadport.c to get an idea of the sort of stuff you need to look at.

Post Reply