我想编写一个 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){}
}
尽管如此,在这种情况下,所有类实例都共享该实例的相同静态值,这使得无法使用此解决方案来处理多个计时器。有什么想法如何将其用于并行的多个中断处理程序吗?
感谢@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){}
}