2 years, 10 months ago.

MBED Ticker doesn't attach interrupt

I have a class:

#ifndef _BUTTON_LISTENER_H_
#define _BUTTON_LISTENER_H_

#include <iostream>
#include <vector>
#include "mbed.h"
#include "Buttons/MenuButton.h"
#include "MenuNavigator.h"

class MenuNavigator;

class ButtonListener
{
    public: 
        ButtonListener(MenuNavigator* navigator, unsigned int samplePeriod_us,
            MenuButton* select, MenuButton* down, 
            MenuButton* up, MenuButton* cancel);
        vector<MenuButton*> getButtons();
        MenuNavigator* getNavigator();
    protected:
        void init();
        void isr();
        vector<MenuButton*> buttons;
        MenuNavigator* navigator;
        unsigned int samplePeriod_us;
        Ticker ticker;
};

#endif

And its implementation:

#include "ButtonListener.h"
#include "Buttons/MenuButton.h"

ButtonListener::ButtonListener(MenuNavigator* navigator, 
    unsigned int samplePeriod, MenuButton* s, MenuButton* d, 
    MenuButton* u, MenuButton* c) : 
    navigator(navigator), 
    samplePeriod_us(samplePeriod_us)
{
    buttons.push_back(s);
    buttons.push_back(d);
    buttons.push_back(u);
    buttons.push_back(c);
    init();
}

void ButtonListener::init()
{
    ticker.attach_us(callback(this, &ButtonListener::isr), 500000);
}

void ButtonListener::isr()
{
    printf("in isr\n");
}

I'm attaching isr() method to create an interrupt so that it sends the text to the terminal window. But for some reason, it doesn't work.

If I put printf() statement before or after the init() method in the constructor, the text of printf() gets printed in the terminal, but the text in the isr() doesn't.

Any help?

1 Answer

2 years, 10 months ago.

Hi Dima,

As far as I know you cannot call printf() or any other blocking functions from interrupt context. Have you tried something 'simpler' such as toggling an LED in your ISR?

I reckon once you remove the printf in your callback call the ticker will work as intended.

Hi Russel, thanks for your help. You actually can, and it works perfectly. I accidentally found the solution to my problem, but I can't post the answer here. The solution is that in the class where I instantiated ButtonListener, I declared it as ButtonListener* bListener, but in the .cpp file, I called it like this ButtonListener* bListener = new ButtonListener();. Once I change the last to bListener = new ButtonListener(args) things started to work as expected.

posted by Dima Dzibrou 24 Jun 2018

Russel, is it actually possible to call a blocking function from the interrupt context? I'm having another issue with printing the lines on the textual LCD and now writing on the LCD doesn't happen after Ticker::attach_us().

posted by Dima Dzibrou 24 Jun 2018

Hi Dima,

I'm still pretty sure you cannot call blocking functions from interrupt context. However if this is not the case anymore there's still other things you could look at. You said about using a LCD display, is this where you are expecting the calls to printf to write to? If that's the case you need to redirect stdout from the USB connection to your LCD display. I don't know whether there is driver support for this.

posted by Russell Bateman 25 Jun 2018

Hi Russel,

It seems now you can call the blocking functions. I send the printf() data to the terminal on PC, I'm using Tera Term terminal. This printf() works just fine.

I'm using the functions to output data on the LCD from the menbed library, thought I modified them a bit. I'm just sending the data bits to the LCD pins, not through the USB.

posted by Dima Dzibrou 25 Jun 2018