乐鑫技术交流
直播中

李颜

7年用户 1379经验值
私信 关注
[问答]

RTOS SDK无法从中断处理程序启动计时器怎么解决?

我正在尝试在用户单击按钮时实现去抖动。

我需要从 gpio 中断内部启动去抖动计时器。但是,这会导致崩溃。

我的代码如下。

#include "gpio.h"
#include "esp_common.h"
#include "esp_timer.h"

静态os_timer_t some_timer;

静态 void timer_handler(void* args) {
   
    printf("timer");
}

静态空隙 intr_handler() {
   
    portENTER_CRITICAL();

    os_timer_disarm(&some_timer);
    os_timer_setfn(&some_timer, (os_timer_func_t *)timer_handler, NULL);
    os_timer_arm(&some_timer, 3, 1);

    portEXIT_CRITICAL();
}

void user_init(void)
{
    GPIO_ConfigTypeDef gpio_in_cfg12;
    gpio_in_cfg12.GPIO_Pin  = GPIO_Pin_12;
    gpio_in_cfg12.GPIO_IntrType = GPIO_PIN_INTR_NEGEDGE;
    gpio_in_cfg12.GPIO_Mode = GPIO_Mode_Input;
    gpio_in_cfg12.GPIO_Pullup = GPIO_PullUp_EN;
    gpio_config(&gpio_in_cfg12);

    gpio_intr_handler_register(intr_handler, NULL);
    _xt_isr_unmask(1 << ETS_GPIO_INUM);
}



回帖(1)

张华

2024-7-18 18:04:45
在许多实时操作系统(RTOS)中,从中断处理程序中启动计时器可能会导致问题,因为中断处理程序通常在不同的上下文中运行,可能不允许执行某些操作。在这种情况下,您可以尝试以下方法来解决这个问题:

1. **使用信号量或事件标志**:在中断处理程序中,您可以设置一个信号量或事件标志,然后在任务上下文中检查这个信号量或事件标志,并在适当的时候启动计时器。

2. **使用任务通知**:某些RTOS允许在中断处理程序中发送任务通知。您可以在中断处理程序中发送通知,然后在任务上下文中处理这个通知,并启动计时器。

3. **使用中断安全的队列**:您可以创建一个中断安全的队列,将需要处理的事件放入队列中,然后在任务上下文中处理这些事件。

以下是使用信号量的方法的示例代码:

```c
#include "gpio.h"
#include "esp_common.h"
#include "esp_timer.h"
#include "os.h"

static os_timer_t some_timer;
static os_semaphore_t debounce_sem;

static void timer_handler(void* args) {
    printf("timern");
}

static void intr_handler() {
    // 在中断处理程序中设置信号量
    os_semaphore_release(debounce_sem);
}

void app_main() {
    // 初始化信号量
    os_semaphore_create(&debounce_sem, 1);

    // 初始化计时器
    os_timer_create(&some_timer, "debounce_timer", timer_handler, NULL, 50, OS_TIMER_ONCE);

    // 设置GPIO中断
    gpio_init();
    gpio_intr_handler_register(intr_handler);

    while (1) {
        // 等待信号量
        os_semaphore_wait(debounce_sem, OS_WAIT_FOREVER);

        // 重新启动计时器
        os_timer_disarm(&some_timer);
        os_timer_arm(&some_timer, 50, OS_TIMER_ONCE);

        // 进入低功耗模式,等待中断
        os_delay(1000);
    }
}
```

在这个示例中,我们使用了一个信号量来在中断处理程序和任务之间传递消息。当按钮被按下时,中断处理程序会释放信号量。在任务上下文中,我们等待信号量,然后重新启动计时器。这样可以确保计时器的启动在任务上下文中进行,而不是在中断处理程序中。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分