How to trigger callback function in timer handler

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
User avatar
Posts: 9
Joined: Fri Jul 24, 2020 2:08 pm

How to trigger callback function in timer handler

Post by xidameng » Wed Sep 30, 2020 6:31 am

Hi I am currently 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
        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) {
        nlr_buf_t nlr;
        if (nlr_push(&nlr) == 0) {
        } 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);
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!

Post Reply