Page 1 of 1

Failed to execute callback function in timer's handler

Posted: Wed Sep 30, 2020 6:33 am
by xidameng
Hi I am currently working on porting MicroPython to Realtek’s RTL8722 WiFi+ BLE dev. board, and it has been mostly done except the Timer module which takes in a callback function but never returns.

here is the C code I wrote for Timer:

Code: Select all

STATIC mp_obj_t timer_start(mp_uint_t n_args, const mp_obj_t *args) {
    enum { ARG_self, ARG_duration, ARG_callback, ARG_type };
    timer_obj_t *self = args[ARG_self];
    uint32_t duration = mp_obj_get_int(args[ARG_duration]);

    if (!MP_OBJ_IS_FUN(args[ARG_callback]) && (args[ARG_callback] != mp_const_none))
        mp_raise_ValueError("Error function type");

    uint8_t type = mp_obj_get_int(args[ARG_type]);

    if (type == TIMER_PERIODICAL)
        gtimer_start_periodical(&(self->obj), duration, mp_obj_timer_irq_handler,
                self);  // MBED api that controls timer 
    else if (type == TIMER_ONESHOT)
        gtimer_start_one_shout(&(self->obj), duration, mp_obj_timer_irq_handler,
                self);  // MBED api that controls timer
    else
        mp_raise_ValueError("Invalid TIMER type");
    
    self->callback = args[ARG_callback];

    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(timer_start_obj, 4, 4,  timer_start);
Because it takes in a callback function which executes whenever timer triggers, I pass the callback function to my timer object using,
self->callback = args[ARG_callback];
And write a timer handler called “mp_obj_timer_irq_handler” as such,

Code: Select all

void mp_obj_timer_irq_handler(timer_obj_t *self) {

    if (self->callback != mp_const_none) {
        gc_lock();
        nlr_buf_t nlr;
        if (nlr_push(&nlr) == 0) {
            mp_call_function_0(self->callback);
            nlr_pop();
        } else {
            self->callback = mp_const_none;
            mp_printf(&mp_plat_print, "Uncaught exception in callback handler");
            if (nlr.ret_val != MP_OBJ_NULL)
                mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
        }
        gc_unlock();
    }
}
And here is my python script:

Code: Select all

>>> from machine import Timer
>>> t = Timer(0) # Create a timer obj on timer 0
>>> t.init() # init it
>>> t.start(2000000, lambda x: print(”test”), t.PERIODICAL)  # period at 2s, callback only print, trigger periodically

It looks and works all good until the last line of the script where I started the timer and then it gets stuck and cannot exit until I manually reset the hardware.

After some trial and error, it appears to me that my C handler never even gets trigger when I pass the python lambda function into the API as an argument

It will mean tremendously to me if someone can give me some suggestions on what is going wrong with my code and how to correctly trigger another handler inside a handler, thanks!

Re: Failed to execute callback function in timer's handler

Posted: Thu Nov 05, 2020 7:13 am
by miltmobley
Try replacing the lambda with an actual function. Most examples of lambda compute expressions and return some value.
They are not supposed to contain statements, which your print probably is.

Re: Failed to execute callback function in timer's handler

Posted: Fri Nov 06, 2020 7:54 am
by pythoncoder
The lambda looks OK to me:

Code: Select all

>>> a = lambda : print('rats')
>>> a()
rats
>>>