创建静态Timer对象导致Teensy 4.0崩溃,求技术排查方案
问题分析与解决方案
问题根源
函数内的静态Timer对象虽然能保留消抖所需的状态,但在Teensy 4.0的运行环境中,函数静态对象的初始化时机可能与硬件初始化流程存在冲突,引发内存访问异常或未定义行为,最终导致崩溃。而非静态对象每次调用函数都会重新实例化,状态无法持续保存,因此无法实现消抖功能。
解决方案
将Timer对象改为ReadGPIOExpanderBase类的成员变量,这样既能保留消抖所需的持续状态,又能避开函数静态对象的初始化问题。
具体修改步骤
在类中添加Timer成员
在ReadGPIOExpanderBase的头文件中,添加私有成员变量:class ReadGPIOExpanderBase { // 原有成员... private: Timer m_debounceTimer; // 用于按键消抖的Timer实例 // 原有私有成员... };修改debounceButtons函数
移除函数内的静态Timer声明,直接使用类成员变量:void ReadGPIOExpanderBase::debounceButtons(const uint8_t firstButton) { // 去掉原有的 static Timer timer; 行 for (uint8_t button = firstButton; button <= 15; ++button) { if (m_debounceTimer.limitReached(button)) { if (m_debounceTimer.running(button)) { m_debounceTimer.stop(button); } else { if (bitRead(m_inputStates, button) < bitRead(m_portReading, button)) { bitSet(m_inputStates, button); m_debounceTimer.setTimeLimit(m_risingDebounceTime, button); } else if (bitRead(m_inputStates, button) > bitRead(m_portReading, button)) { bitClear(m_inputStates, button); m_debounceTimer.setTimeLimit(m_fallingDebounceTime, button); } } } } }
额外优化建议
- 添加边界检查:在
Timer类的数组操作成员函数中,添加button参数的合法性检查,避免数组越界访问:void Timer::setTimeLimit(const uint8_t debounceTime, const uint8_t button) { if (button >= 16) return; // 或者使用断言 assert(button < 16); m_timeStamp[button] = millis(); m_debounceTime[button] = debounceTime; bitSet(m_running, button); } - 简化状态管理:将
m_running从uint16_t位字段改为bool m_running[16]数组,比位操作更直观,降低后续维护出错的概率。
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

