我做了三轮测试
系统中只有按键功能,且无其他循环定时器。
1.在按键中断的下降沿开定时器,上升沿关定时器(此定时器用于消抖及长按等判断,测试时候定时器回调没做处理),上升沿我就认为是按键按下,发送事件复位一个10秒定时器。这种情况下偶尔会出现10S定时器会超时。
2.在按键中断的下降沿不开定时器,上升沿不关定时器(定时器完全没使用),上升沿我就认为是按键按下,发送事件复位一个10秒定时器。这种情况下10S定时器不会超时。
3.开启一个定时器,定时时间是20MS-1000MS的随机值,每次超时的时候发送一个事件去复位10S定时器同时用随机值再次开启定时器。这种情况下10S定时器不会超时。
经过我大致的测试,大概是在GPIO中断回调中操作定时器导致的我复位定时器有问题。但是没找到最终的一个合理解释。想请教下,在GPIO中断回调中去操作定时器,会对整个定时器(timer_list)可能产生异常吗?我也看了sw timer的代码,关键操作都是有进临界的。
代码如下
Code: Select all
static key_check_t g_key_check;
STATIC TIMER_ID key_timer_id = NULL;
STATIC TIMER_ID reset_timer_id = NULL;
//发送事件
void event_test_msg_send(event_data_t *msg)
{
tuya_ble_custom_evt_send_with_data(APP_EVT_0, msg, sizeof(event_data_t));
}
//10超时回调
static void reset_timeout_handlercb(TIMER_ID timer_id, VOID_T *arg)
{
TAL_PR_INFO("##################reset timer timeout####################");
}
//按键事件处理 最终会在tuya_ble_app_data_process调用
void event_test_handle(void *rxdata)
{
event_data_t *rxmsg = (event_data_t *)rxdata;
switch(rxmsg->num)
{
case KEY_NUM_ADD:
{
TAL_PR_INFO("reset timer start 333");
tal_sw_timer_start(reset_timer_id,10000,TAL_TIMER_ONCE);
}
break;
case KEY_NUM_SUB:
{
TAL_PR_INFO("reset timer start 444");
tal_sw_timer_start(reset_timer_id,10000,TAL_TIMER_ONCE);
}
break;
default:
break;
}
}
//按键处理定时器
static void oled_key_check_timeout_handlercb(TIMER_ID timer_id, VOID_T *arg)
{
}
// 边沿沿中断处理回调
STATIC VOID_T oled_key_edge_handleCb(gpio_pin_e pin,gpio_polarity_e type)
{
event_data_t data;
/*当前没有按键按下检测*/
if(g_key_check.state == KEY_UP)
{
//下降沿 按键按下
if(type == POL_FALLING)
{
g_key_check.state = KEY_DOWN;
g_key_check.num = pin;
g_key_check.long_time = 0;
tal_sw_timer_start(key_timer_id,KEY_CHECK_TIMER_PERIOD,TAL_TIMER_CYCLE);//开启此处 偶尔出现10S超时
}
}
if(type == POL_RISING && pin == g_key_check.num)
{
tal_sw_timer_stop(key_timer_id);//开启此处 偶尔出现10S超时
data.num = g_key_check.num;
data.action = KEY_ACTION_SHORT_PRESS;
event_test_msg_send(&data);
g_key_check.state = KEY_UP;
g_key_check.num = KEY_NUM_DUMMY;
g_key_check.long_time = 0;
g_key_check.decode_time=0;
}
}
//key_test_init 按键初始化
void key_test_init()
{
/* POWER LOCK CHECK*/
hal_gpio_pull_set(OLED_ADD_KEY_PIN, GPIO_PULL_UP_S);
hal_gpioin_register(OLED_ADD_KEY_PIN, oled_key_edge_handleCb, oled_key_edge_handleCb);
hal_gpio_pull_set(OLED_SUB_KEY_PIN, GPIO_PULL_UP_S);
hal_gpioin_register(OLED_SUB_KEY_PIN, oled_key_edge_handleCb, oled_key_edge_handleCb);
//创建检测定时器
g_key_check.state = KEY_UP;
g_key_check.num = KEY_NUM_DUMMY;
g_key_check.long_time = 0;
tal_sw_timer_create(oled_key_check_timeout_handlercb, NULL, &key_timer_id);
tal_sw_timer_create(reset_timeout_handlercb, NULL, &reset_timer_id);
tal_sw_timer_start(reset_timer_id,10000,TAL_TIMER_ONCE);
}