如何使用 C++ 类作为 RP2040 (RPPico) 上定时器中断的包装器

问题描述 投票:0回答:1

我想编写一个 C++ 包装类,可用于并行处理多个计时器中断。

对于一次一个中断,我有一个与此类似的工作解决方案:使用 lambda 函数作为微控制器中断处理程序

我的包装类如下所示:

class Rp2040RepeatingTimer {
private:
    struct repeating_timer _repeating_timer;  /* Config for repeating timer*/
    std::function<void()> _callback;
    static Rp2040RepeatingTimer* _instance;

    static bool timerHandler(struct repeating_timer *t){
        if (_instance){
            _instance->_callback();
        }
        return true;
    }

public:
    Rp2040RepeatingTimer(std::function<void()> _callback) : _callback(_callback) {
        _instance = this;
    }

    bool start(const int32_t intervall);
    bool stop();
};

我的测试程序如下所示:

Rp2040RepeatingTimer* Rp2040RepeatingTimer::_instance = nullptr;
    
int main(){
    stdio_init_all();

    // Handle interrupt
    // This lambda function is never called when timer1 occurs
    Rp2040RepeatingTimer timer1([]() {
        printf("GOTCHA 1");
    });

    Rp2040RepeatingTimer timer2([]() {
        printf("GOTCHA 2");
    });

    timer1.start(500);
    timer2.start(1000);

    while(1){}
}

尽管如此,在这种情况下,所有类实例都共享该实例的相同静态值,这使得无法使用此解决方案来处理多个计时器。有什么想法如何将其用于并行的多个中断处理程序吗?

c++ microcontroller wrapper interrupt
1个回答
0
投票

感谢@TerenceSimpson,我能够为我的问题找到一个可行的解决方案。这个想法是使用中断处理程序的 user_data 指针来传递相应的计时器对象(作为回报,它将函数指针存储到用户回调)。

我的用于类声明的timer.hpp文件:

class Rp2040RepeatingTimer {
private:
    struct repeating_timer _repeating_timer;    /* Config for repeating timer*/ 
    std::function<void()> _callback;            /* function pointer to user callback */
    static bool timerHandler(struct repeating_timer *t); /* Timer ISR */

public:
    Rp2040RepeatingTimer(){
        /* Set pointer to current timer object as user data to pass to the timer ISR */
        _repeating_timer.user_data = this; 
    }

    bool start(const int32_t intervall, const std::function<void()> &callback); 
    bool stop();
};

我的timer.cpp文件用于函数定义:

/* Timer ISR - Call stored user callback gathered from user_data */
bool Rp2040RepeatingTimer::timerHandler(struct repeating_timer *t){
    static_cast<Rp2040RepeatingTimer*>(t->user_data)->_callback();
    return true;
}

bool Rp2040RepeatingTimer::start(const int32_t intervall, const std::function<void()> &callback){
    _callback = callback;
    return add_repeating_timer_ms(intervall, timerHandler, this, &_repeating_timer);
}   

bool Rp2040RepeatingTimer::stop(){
    return cancel_repeating_timer(&_repeating_timer);
}

我的main.cpp用于测试:

void callback1(){
    printf("\nGOTCHA 1");
}

void callback2(){
    printf("\nGOTCHA 2");
}


int main(){
    stdio_init_all();

    Rp2040RepeatingTimer timer1;
    Rp2040RepeatingTimer timer2;

    if(timer1.start(500, callback1)){
        printf("\nTimer 1 started");
    }  
    if(timer2.start(1000, callback2)){
        printf("\nTimer 2 started");
    }    

    while(1){}
}
© www.soinside.com 2019 - 2024. All rights reserved.