Looking for help using MP in Windows with QT

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

Re: Looking for help using MP in Windows with QT

Post by cduran » Tue Sep 26, 2017 6:26 pm

dhylands wrote:Using extern C just satisfies the linker.

You need to make sure that once you're in MicroPython land, if you call ANY C++ code that it does not throw an exception, or it will totally mess up the MicroPython exception stack. As long as MicroPython doesn't call any C++ functions which may throw an exception you'll be fine.

As to your hang, then it sounds like perhaps your Python to C bindings are not quite setup properly.

Did you try something that's known to work, like the c_sample from here:
viewtopic.php?f=16&t=2861&p=19206#p19206

So here is what I have for setting up the Python to C binding. I don't see anything wrong with it.

Code: Select all

static mp_obj_t c_sample_set_callback(mp_obj_t callback_obj)
{
	MP_STATE_PORT(c_sample_callback_obj) = callback_obj;
	return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(c_sample_set_callback_obj, c_sample_set_callback);
static mp_obj_t c_sample_call_callback(mp_obj_t mp_arg0, mp_obj_t mp_arg1, mp_obj_t mp_arg2);
static MP_DEFINE_CONST_FUN_OBJ_3(c_sample_call_callback_obj, c_sample_call_callback);
static const mp_map_elem_t c_sample_globals_table[] = 
{
	{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_c_sample) },
	{ MP_OBJ_NEW_QSTR(MP_QSTR_set_callback), (mp_obj_t)&c_sample_set_callback_obj },
	{ MP_OBJ_NEW_QSTR(MP_QSTR_call_callback), (mp_obj_t)&c_sample_call_callback_obj },
};
static MP_DEFINE_CONST_DICT(mp_module_c_sample_globals, c_sample_globals_table);
const mp_obj_module_t mp_module_c_sample = 
{
	.base = { &mp_type_module },
	.name = MP_QSTR_c_sample,
	.globals = (mp_obj_dict_t*)&mp_module_c_sample_globals,
};
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);

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

Re: Looking for help using MP in Windows with QT

Post by dhylands » Tue Sep 26, 2017 8:33 pm

The next thing to check is that your port does all of the appropriate micropython initializations. i.e. calls gc_init and mp_init

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

Re: Looking for help using MP in Windows with QT

Post by stijn » Wed Sep 27, 2017 8:15 am

The debugger isn't working inside the C code.
How is that possible? I assume you build using gcc so gdb should work out of the box for debug builds? If you already know how to use the debugger, figuring out how to fix that might be the most efficient solution in the long run: for cases like this it's likely the fastest way to figure out the exact problem. So time 'lost' now on getting the debugger to work will pay off in the long run since for future problem you;l already have a nice tool ready to debug it.

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

Re: Looking for help using MP in Windows with QT

Post by cduran » Mon Oct 02, 2017 7:03 pm

dhylands wrote:The next thing to check is that your port does all of the appropriate micropython initializations. i.e. calls gc_init and mp_init
I'm using the following to initialize:

Code: Select all

#define BYTES_IN_KB			1024
#define KB_IN_PYTHON_HEAP		32
#define PYTHON_HEAP_SIZE		(KB_IN_PYTHON_HEAP * BYTES_IN_KB)

...

static char *stack_top;
static char heap[PYTHON_HEAP_SIZE];

...

mp_stack_set_top(stack_top);
gc_init(heap, heap + sizeof(heap));
mp_init();
Same code I used in the embedded build.

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

Re: Looking for help using MP in Windows with QT

Post by dhylands » Mon Oct 02, 2017 7:25 pm

What are you initializing stack_top to?

It looks like you're passing in an uninitialized global which will be NULL.

For a desktop port (windows, unix, etc) I would expect that you'd pass in the address of a variable located on the stack. Or use mp_stack_ctrl_init which does that (takes the address of a stack variable).

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

Re: Looking for help using MP in Windows with QT

Post by cduran » Thu Oct 05, 2017 3:45 pm

dhylands wrote:What are you initializing stack_top to?

It looks like you're passing in an uninitialized global which will be NULL.

For a desktop port (windows, unix, etc) I would expect that you'd pass in the address of a variable located on the stack. Or use mp_stack_ctrl_init which does that (takes the address of a stack variable).
I tried using mp_stack_ctrl_init and still having the same problem.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: Looking for help using MP in Windows with QT

Post by jickster » Thu Oct 05, 2017 3:46 pm

Using QT I developed a sort of debugger for python code running on my firmware. For this I used the same build of micropython just so that I have a dublicate of mp that will behave just like the one on my firmware.
Hi cduran. Please let us know how you implemented this debugger here viewtopic.php?f=3&t=3886

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

Re: Looking for help using MP in Windows with QT

Post by cduran » Fri Oct 06, 2017 3:05 pm

jickster wrote:
Using QT I developed a sort of debugger for python code running on my firmware. For this I used the same build of micropython just so that I have a dublicate of mp that will behave just like the one on my firmware.
Hi cduran. Please let us know how you implemented this debugger here viewtopic.php?f=3&t=3886
It might not be much help to anyone else. The debugger is very specific to my application. I'm using it to debug the interaction between python scripts and my firmware so I know what to expect when a script is sent and executed by the firmware.

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

Re: Looking for help using MP in Windows with QT

Post by cduran » Mon Oct 09, 2017 6:13 pm

So this is the content of my mpconfigport.h is there something I'm missing or needs to be different?

Code: Select all

#include <stdint.h>

// options to control how Micro Python is built

#define MICROPY_QSTR_BYTES_IN_HASH  (1)
#define MICROPY_ALLOC_PATH_MAX      (256)
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16)
#define MICROPY_EMIT_X64            (0)
#define MICROPY_EMIT_THUMB          (0)
#define MICROPY_EMIT_INLINE_THUMB   (0)
#define MICROPY_COMP_MODULE_CONST   (0)
#define MICROPY_COMP_CONST          (0)
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
#define MICROPY_MEM_STATS           (0)
#define MICROPY_DEBUG_PRINTERS      (0)
#define MICROPY_ENABLE_GC           (1)
#define MICROPY_REPL_EVENT_DRIVEN   (0)
#define MICROPY_HELPER_REPL         (1)
#define MICROPY_HELPER_LEXER_UNIX   (0)
#define MICROPY_ENABLE_SOURCE_LINE  (0)
#define MICROPY_ENABLE_DOC_STRING   (0)
#define MICROPY_ERROR_REPORTING     (MICROPY_ERROR_REPORTING_TERSE)
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
#define MICROPY_PY_BUILTINS_FILTER  (0)
#define MICROPY_PY_BUILTINS_FROZENSET (0)
#define MICROPY_PY_BUILTINS_REVERSED (0)
#define MICROPY_PY_BUILTINS_SET     (0)
#define MICROPY_PY_BUILTINS_SLICE   (0)
#define MICROPY_PY_BUILTINS_PROPERTY (0)
#define MICROPY_PY_BUILTINS_MIN_MAX (0)
#define MICROPY_PY___FILE__         (0)
#define MICROPY_PY_GC               (0)
#define MICROPY_PY_ARRAY            (0)
#define MICROPY_PY_ATTRTUPLE        (0)
#define MICROPY_PY_COLLECTIONS      (0)
#define MICROPY_PY_MATH             (0)
#define MICROPY_PY_CMATH            (0)
#define MICROPY_PY_IO               (0)
#define MICROPY_PY_STRUCT           (0)
#define MICROPY_PY_SYS              (0)
#define MICROPY_MODULE_FROZEN       (0)
#define MICROPY_MODULE_FROZEN_MPY	(0)
#define MICROPY_CPYTHON_COMPAT      (0)
#define MICROPY_LONGINT_IMPL        (MICROPY_LONGINT_IMPL_NONE)
#define MICROPY_FLOAT_IMPL          (MICROPY_FLOAT_IMPL_NONE)


extern const struct _mp_obj_module_t mp_module_c_sample;

// type definitions for the specific machine

#define BYTES_PER_WORD (4)

#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))

// This port is intended to be 32-bit, but unfortunately, int32_t for
// different targets may be defined in different ways - either as int
// or as long. This requires different printf formatting specifiers
// to print such value. So, we avoid int32_t and use int directly.
#define UINT_FMT "%u"
#define INT_FMT "%d"

#include <stdint.h>
typedef __int64 mp_int_t;
typedef unsigned __int64 mp_uint_t;


//typedef int mp_int_t; // must be pointer size
//typedef unsigned int mp_uint_t; // must be pointer size

typedef void *machine_ptr_t; // must be of pointer size
typedef const void *machine_const_ptr_t; // must be of pointer size
typedef long mp_off_t;

#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)

// extra built in names to add to the global namespace
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
#define MICROPY_PORT_BUILTINS \
    { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },

#define MICROPY_PORT_BUILTIN_MODULES \
	{ MP_OBJ_NEW_QSTR(MP_QSTR_c_sample), (mp_obj_t)&mp_module_c_sample },

// We need to provide a declaration/definition of alloca()
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <malloc.h>     // alloca
#else
#include <alloca.h>     // alloca
#endif

#define MICROPY_HW_BOARD_NAME "minimal"
#define MICROPY_HW_MCU_NAME "unknown-cpu"

#ifdef __linux__
#define MICROPY_MIN_USE_STDOUT (1)
#endif

#ifdef __thumb__
#define MICROPY_MIN_USE_CORTEX_CPU (0)
#define MICROPY_MIN_USE_STM32_MCU (0)
#endif

// Just assume Windows is little-endian - mingw32 gcc doesn't
// define standard endianness macros.
#define MP_ENDIANNESS_LITTLE (1)

#define MP_STATE_PORT MP_STATE_VM

#define MICROPY_PORT_ROOT_POINTERS \
    const char *readline_hist[8]; \
	mp_obj_t c_sample_callback_obj;




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

Re: Looking for help using MP in Windows with QT

Post by cduran » Wed Oct 11, 2017 3:55 pm

dhylands wrote:What are you initializing stack_top to?

It looks like you're passing in an uninitialized global which will be NULL.

For a desktop port (windows, unix, etc) I would expect that you'd pass in the address of a variable located on the stack. Or use mp_stack_ctrl_init which does that (takes the address of a stack variable).

I'm going to try a different approach. I'm going to build the windows version, but I need it to have the same limitations as the minimal build. Would it be enough to just change the mpconfig?

Post Reply