从班级传递一个void(*fn)

发布于 2025-02-10 23:45:39 字数 1063 浏览 1 评论 0原文

我正在使用PIO在Arduino Framework上使用ESP32编写自动显示关闭功能。 我有一个用于处理所有屏幕功能的屏幕类。

void Screen::turn_off_screen(){

  digitalWrite(SCREEN_ENABLE, LOW);

}

void turn_off_screen_wrapper()
{
  Serial.println("turn_off_screen_wrapper called");
    if (c_screen_Instance != nullptr)
    {
      c_screen_Instance->turn_off_screen();
    }
}

void Screen::auto_display_power_off(int timeout){
  Serial.println("auto_display_power_off called");
  c_screen_Instance = this;
  auto_off_timer = timerBegin(0, 80, true);
  Serial.println("auto_off_timer ran");
  timerAttachInterrupt(auto_off_timer, &turn_off_screen_wrapper, true);
  Serial.println("timerAttachInterrupt ran");
  //Converts given seconds from us to seconds
  timerAlarmWrite(auto_off_timer,timeout*1000000,false);
  timerAlarmEnable(auto_off_timer);

}

但是,当我在板上运行时,我会得到代码。

auto_display_power_off called
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400811F8 arg=3FFBDC54
auto_off_timer ran

屏幕当然永远不会关闭,因为回调从未运行。有什么想法,为什么会发生这种情况?

I'm writing an auto display turn-off function with ESP32 on Arduino framework with PIO.
I have a Screen class for handling all of the screen functions.

void Screen::turn_off_screen(){

  digitalWrite(SCREEN_ENABLE, LOW);

}

void turn_off_screen_wrapper()
{
  Serial.println("turn_off_screen_wrapper called");
    if (c_screen_Instance != nullptr)
    {
      c_screen_Instance->turn_off_screen();
    }
}

void Screen::auto_display_power_off(int timeout){
  Serial.println("auto_display_power_off called");
  c_screen_Instance = this;
  auto_off_timer = timerBegin(0, 80, true);
  Serial.println("auto_off_timer ran");
  timerAttachInterrupt(auto_off_timer, &turn_off_screen_wrapper, true);
  Serial.println("timerAttachInterrupt ran");
  //Converts given seconds from us to seconds
  timerAlarmWrite(auto_off_timer,timeout*1000000,false);
  timerAlarmEnable(auto_off_timer);

}

The code compiles however I get this when I run it on the board.

auto_display_power_off called
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400811F8 arg=3FFBDC54
auto_off_timer ran

The screen never gets turned off of course since the callback never runs. Any ideas why this is happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故事和酒 2025-02-17 23:45:39

c_screen_instance全局吗?
auto_off_timer全局吗?

考虑提供更多代码。

但是无论如何。

bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
    initApbChangeCallback();
    apb_change_t * c = (apb_change_t*)malloc(sizeof(apb_change_t));
    if(!c){
        log_e("Callback Object Malloc Failed");
        return false;
    }
    c->next = NULL;
    c->prev = NULL;
    c->arg = arg;
    c->cb = cb;
    xSemaphoreTake(apb_change_lock, portMAX_DELAY);
    if(apb_change_callbacks == NULL){
        apb_change_callbacks = c;
    } else {
        apb_change_t * r = apb_change_callbacks;
        // look for duplicate callbacks
        while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
        if (r) {
            log_e("duplicate func=%8p arg=%8p",c->cb,c->arg);
            free(c);
            xSemaphoreGive(apb_change_lock);
            return false;
        }
        else {
            c->next = apb_change_callbacks;
            apb_change_callbacks-> prev = c;
            apb_change_callbacks = c;
        }
    }
    xSemaphoreGive(apb_change_lock);
    return true;
}

这是addapbChangeCallback的声明。

您的错误来自此行:

while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;

其中r是一个结构,可以保留所有回调。
此错误确实表明此回调函数已在您的代码中的某个地方分配。 r是全局,因此您的代码正在两次重新分配同一回调。

尝试仅分配一次,或者在使用removeapBchangeCallback(void * arg,apb_change_cb_t cb)timerDetachIrstrupt

我也找到了一个报告的报告与timerattach在当前版本上有关的问题: https:/ /Github.com/espressif/arduino-esp32/issues/6730

尝试将平台PIO的版本滚动到更稳定的版本中:

# instead of espressif32
platform = https://github.com/platformio/platform-espressif32.git#<tag-version>

查看可用的可用标签的git链接。

is c_screen_Instance global?
is auto_off_timer global?

Consider providing a bit more of your code.

But anyway.

bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
    initApbChangeCallback();
    apb_change_t * c = (apb_change_t*)malloc(sizeof(apb_change_t));
    if(!c){
        log_e("Callback Object Malloc Failed");
        return false;
    }
    c->next = NULL;
    c->prev = NULL;
    c->arg = arg;
    c->cb = cb;
    xSemaphoreTake(apb_change_lock, portMAX_DELAY);
    if(apb_change_callbacks == NULL){
        apb_change_callbacks = c;
    } else {
        apb_change_t * r = apb_change_callbacks;
        // look for duplicate callbacks
        while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
        if (r) {
            log_e("duplicate func=%8p arg=%8p",c->cb,c->arg);
            free(c);
            xSemaphoreGive(apb_change_lock);
            return false;
        }
        else {
            c->next = apb_change_callbacks;
            apb_change_callbacks-> prev = c;
            apb_change_callbacks = c;
        }
    }
    xSemaphoreGive(apb_change_lock);
    return true;
}

This is addApbChangeCallback's declaration.

Your error comes from this line :

while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;

Where r it's a struct to hold all the callbacks.
This error indeed indicates this callback function was already assigned somewhere in your code. r is global, so your code is re-assigning the same callback twice.

Try to either only assign it once, or to unassign the function before assigning it again with removeApbChangeCallback(void * arg, apb_change_cb_t cb) or timerDetachInterrupt

I've also found a reported issue related to timerAttach on the current version here: https://github.com/espressif/arduino-esp32/issues/6730

Try to roll back the Platform PIO's version to a more stable one:

# instead of espressif32
platform = https://github.com/platformio/platform-espressif32.git#<tag-version>

Check on the git link for the available tags you can use.

掀纱窥君容 2025-02-17 23:45:39

问题是我将中断连接在void loop()中。它的运行速度比实际计时器快。将其移至设置(设置为占位符)之后,我计划将其放在硬件中断上,它按预期工作。

Problem was that I was attaching the interrupt in the void loop(). Which would run way faster than the actual timer. After moving it to setup (Setup being a placeholder) I plan on having it on a Hardware interrupt it worked as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文