迸击的皮卡鼠 2026-05-23 12:14 采纳率: 66.7%
浏览 3

关于#单片机#的问题:mac系统下,单片机启动cdc模式连接,对其睡眠时的USB挂起信号检测出现步差下位机相关代码(TinyUSB):(操作系统-macos)

mac系统下,单片机启动cdc模式连接,对其睡眠时的USB挂起信号检测出现步差
下位机相关代码(TinyUSB):

static bool s_host_suspended = false;   
void home_tabview_set_host_suspend_state(bool suspended) {
  if (suspended) {
    if (!s_host_suspended) {
      s_host_suspended = true;
      ESP_LOGI(TAG_HOME, "Host suspended");

      if (!s_screen_off) {
        s_screen_saved_brightness = bsp_get_lcd_backlight_brightness();
        if (s_screen_saved_brightness < 5)
          s_screen_saved_brightness = 80;
        bsp_lcd_backlight_force_off();
        s_screen_off = true;
      }
    }
  } else {
    if (s_host_suspended) {
      s_host_suspended = false;
      ESP_LOGI(TAG_HOME, "Host resumed");
      // 重启
      esp_restart();
    }
  }
}

此代码在windows系统下能够正常运行:windows睡眠->屏幕熄灭,windows恢复->单片机重启,但在mac系统下运行时出现如下情况:mac进入睡眠->屏幕无反应,mac恢复显示->屏幕熄灭,mac再次进入睡眠->屏幕无反应,mac再次恢复显示->单片机重启
有没有什么好的解决办法啊

  • 写回答

1条回答 默认 最新

  • 檀越@新空间 2026-05-23 12:15
    关注

    中午好🌞🌞🌞
    本答案参考通义千问

    你遇到的问题是 在 macOS 系统下,单片机通过 CDC 模式连接时,对 USB 挂起(Suspend)信号的检测出现了不一致的行为。具体表现为:

    • 在 Windows 下,当系统进入睡眠时,USB 设备会触发挂起事件,单片机会正确关闭屏幕;
    • 但在 macOS 下,这种行为不一致:
      • 第一次进入睡眠后,屏幕无反应;
      • 恢复显示后,屏幕熄灭;
      • 再次进入睡眠时,又无反应;
      • 最终恢复时,触发重启。

    ✅ 问题分析

    1. USB 挂起事件的触发机制不同

    Windows 和 macOS 对 USB 设备的挂起/恢复事件处理方式存在差异。

    • Windows 会在系统进入睡眠时主动发送 USB suspend 信号给设备;
    • macOS 可能不会像 Windows 那样“强制”发送挂起信号,尤其是在某些情况下(如使用 USB-C 或 Thunderbolt 接口),导致设备无法正确感知挂起事件。

    2. TinyUSB 库的实现细节

    你使用的 TinyUSB 库可能没有完全适配 macOS 的 USB 挂起/恢复逻辑。尤其是 cdc 模式下的设备,其状态变化可能被 macOS 跳过或延迟处理。

    3. 代码中缺乏对 macOS 特定行为的兼容性处理

    当前代码只关注 s_host_suspended 状态的变化,但未考虑 macOS 中 USB 挂起事件的延迟、重复或丢失情况。


    ✅ 解决方案

    以下是针对该问题的详细解决方案,包括代码修改建议和优化方向:

    一、增加对 macOS 的特殊处理

    // 增加一个 flag,用于记录 macOS 是否已经处理过挂起事件
    static bool s_macos_suspend_processed = false;
    
    void home_tabview_set_host_suspend_state(bool suspended) {
        if (suspended) {
            if (!s_host_suspended) {
                s_host_suspended = true;
                ESP_LOGI(TAG_HOME, "Host suspended");
    
                // macOS 特殊处理:防止重复触发
                if (!s_macos_suspend_processed) {
                    s_macos_suspend_processed = true;
    
                    if (!s_screen_off) {
                        s_screen_saved_brightness = bsp_get_lcd_backlight_brightness();
                        if (s_screen_saved_brightness < 5)
                            s_screen_saved_brightness = 80;
                        bsp_lcd_backlight_force_off();
                        s_screen_off = true;
                    }
                }
            }
        } else {
            if (s_host_suspended) {
                s_host_suspended = false;
                ESP_LOGI(TAG_HOME, "Host resumed");
    
                // 重置 macOS 挂起标志
                s_macos_suspend_processed = false;
    
                // 重启
                esp_restart();
            }
        }
    }
    

    说明: 通过添加 s_macos_suspend_processed 标志,可以防止 macOS 多次触发挂起事件时重复执行熄屏操作。


    二、优化 USB 事件监听逻辑

    确保你的 USB 事件监听函数能够更稳定地捕获挂起/恢复事件。

    // 在 TinyUSB 初始化之后注册 USB 事件回调
    tusb_init();
    
    // 注册 USB 事件回调
    tusb_event_callback_t event_cb = {
        .on_usb_suspend = on_usb_suspend,
        .on_usb_resume = on_usb_resume,
    };
    
    tusb_register_event_callback(&event_cb);
    
    // 定义 USB 挂起回调函数
    void on_usb_suspend() {
        home_tabview_set_host_suspend_state(true);
    }
    
    // 定义 USB 恢复回调函数
    void on_usb_resume() {
        home_tabview_set_host_suspend_state(false);
    }
    

    说明: 使用 TinyUSB 提供的事件回调机制,确保挂起/恢复事件被正确捕获。


    三、增加日志调试功能

    为了进一步排查问题,建议增加日志输出,查看挂起/恢复事件是否真的被触发。

    ESP_LOGI(TAG_HOME, "USB Event: %s", suspended ? "Suspended" : "Resumed");
    

    四、测试与验证

    • 在 macOS 上多次进行睡眠/唤醒操作,观察日志输出;
    • 如果发现 on_usb_suspend() 未被调用,可能是 macOS 不支持或未正确识别 USB 设备;
    • 尝试在 macOS 上使用其他 USB 设备(如 U 盘)测试 USB 挂起事件是否正常。

    ✅ 总结

    | 问题 | 原因 | 解决方法 | |------|------|----------| | macOS 下 USB 挂起事件未被正确触发 | macOS 与 Windows 对 USB 事件的处理机制不同 | 添加 macOS 特殊处理逻辑,使用 TinyUSB 事件回调 | | 重复触发挂起事件 | 没有判断事件是否已处理 | 增加 s_macos_suspend_processed 标志 | | 日志不清晰 | 无法定位问题 | 增加日志输出,验证事件是否真正触发 |


    ✅ 建议

    如果你的项目需要跨平台兼容性,建议使用 libusblibuvc 等更底层的 USB 库,以获得更稳定的 USB 事件控制能力。


    如有更多关于 TinyUSB 的配置或驱动问题,欢迎继续提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 5月23日