/* PPP中断消息队列配置 */
#define PPP_IRQ_MSG_QUEUE_SIZE 16 // 队列深度(乒乓模式下无需太大)
-#define PPP_IRQ_PROCESS_TASK_PRIO 28 // 处理线程优先级
+#define PPP_IRQ_PROCESS_TASK_PRIO 24 // 处理线程优先级
#define PPP_IRQ_PROCESS_STACK_SIZE 4096 // 处理线程栈大小
/* 乒乓缓冲区状态 */
static ppp_uart_error_stats_t g_uart_error_stats = {0};
+/* PPP数据传输状态检测(用于安全执行+++/ATO命令) */
+typedef struct {
+ uint32_t last_rx_time_ms; // 最后接收数据时间
+ uint32_t rx_bytes_this_second; // 本秒接收的字节数
+ uint32_t rx_rate_bps; // 接收速率(bytes/sec)
+} ppp_data_state_t;
+
+static ppp_data_state_t g_ppp_data_state = {0};
+
+/* 配置参数 */
+#define PPP_SAFE_SWITCH_IDLE_MS 5000 // 5秒空闲才安全切换
+#define PPP_LIGHT_THRESHOLD_BPS 100 // 100 bps以下为轻量传输
+
/* 外部函数声明(在ppp_lwip.c中实现) */
extern ppp_pcb* ppp_lwip_get_pcb(void);
extern bool ppp_lwip_is_initialized(void);
// ⚠️ 更新全局时间戳(供ISR使用,ISR中不能调用时间函数)
g_timer_timestamp_ms = current_time;
+ // ✅ 每秒更新一次接收速率(用于安全执行+++/ATO命令)
+ static uint32_t last_rate_update_time = 0;
+ if (last_rate_update_time == 0) {
+ last_rate_update_time = current_time;
+ }
+
+ uint32_t elapsed = current_time - last_rate_update_time;
+ if (elapsed >= 1000) { // 每秒更新
+ g_ppp_data_state.rx_rate_bps =
+ (g_ppp_data_state.rx_bytes_this_second * 1000) / elapsed;
+ g_ppp_data_state.rx_bytes_this_second = 0;
+ last_rate_update_time = current_time;
+ }
+
uint8_t current_idx = g_current_buffer_index; // 读取一次,避免重复读取
// ⚠️ 检查内存是否已分配
g_ppp_interrupt_stats.total_interrupts++;
g_ppp_interrupt_stats.total_bytes_received += length;
+ // ✅ 更新状态检测(用于安全执行+++/ATO命令)
+ g_ppp_data_state.last_rx_time_ms = g_timer_timestamp_ms;
+ g_ppp_data_state.rx_bytes_this_second += length;
+
// 获取当前buffer
uint8_t current_idx = g_current_buffer_index;
ppp_ping_pong_buffer_t *current_buffer = &g_ping_pong_buffers[current_idx];
app_task_definition_t irq_task_cfg = {0};
irq_task_cfg.attr.name = "ppp_irq_proc";
- irq_task_cfg.attr.priority = osPriorityNormal; // 优先级24(对应原MIDDLE)
+ irq_task_cfg.attr.priority = PPP_IRQ_PROCESS_TASK_PRIO; // 优先级24(对应原MIDDLE)
irq_task_cfg.attr.stack_size = PPP_IRQ_PROCESS_STACK_SIZE;
irq_task_cfg.func = (osThreadFunc_t)ppp_irq_process_thread;
irq_task_cfg.task_handle = &g_ppp_irq_process_task;
// 性能总结(已经在上面各部分显示过了,这里不再重复)
PPP_DEBUG_WARN("=================================================");
+}
+
+/**
+ * @brief 检查是否可以安全执行+++命令切换到命令模式
+ * @return true 安全,false 不安全
+ *
+ * 判断标准:
+ * 1. PPP已连接
+ * 2. 接收空闲时间 >= 5秒
+ * 3. 接收速率 < 100 bps
+ * 4. 所有buffer都是EMPTY状态
+ */
+bool ppp_interrupt_is_safe_for_command_switch(void)
+{
+ // 1. 检查PPP是否已连接
+ if (!ppp_lwip_is_connected()) {
+ PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: PPP not connected");
+ return false;
+ }
+
+ uint32_t current_time = g_timer_timestamp_ms;
+
+ // 2. 检查接收空闲时间
+ if (g_ppp_data_state.last_rx_time_ms == 0) {
+ // 从未接收过数据,认为是空闲
+ PPP_DEBUG_DEBUG("[SAFE_CHECK] No RX data yet, considered idle");
+ } else {
+ uint32_t idle_ms = current_time - g_ppp_data_state.last_rx_time_ms;
+ if (idle_ms < PPP_SAFE_SWITCH_IDLE_MS) {
+ PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: RX idle=%ums < threshold=%ums",
+ idle_ms, PPP_SAFE_SWITCH_IDLE_MS);
+ return false;
+ }
+ }
+
+ // 3. 检查接收速率
+ if (g_ppp_data_state.rx_rate_bps > PPP_LIGHT_THRESHOLD_BPS) {
+ PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: RX rate=%u bps > threshold=%u bps",
+ g_ppp_data_state.rx_rate_bps, PPP_LIGHT_THRESHOLD_BPS);
+ return false;
+ }
+
+ // 4. 检查所有buffer是否空闲
+ if (g_ping_pong_buffers != NULL) {
+ uint32_t non_empty_count = 0;
+ for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+ if (g_ping_pong_buffers[i].state != PPP_BUFFER_STATE_EMPTY) {
+ non_empty_count++;
+ PPP_DEBUG_DEBUG("[SAFE_CHECK] Buffer[%u] not empty (state=%d)",
+ i, g_ping_pong_buffers[i].state);
+ }
+ }
+ if (non_empty_count > 0) {
+ PPP_DEBUG_DEBUG("[SAFE_CHECK] Not safe: %u buffers not empty", non_empty_count);
+ return false;
+ }
+ }
+
+ // 全部检查通过
+ uint32_t idle_ms = (g_ppp_data_state.last_rx_time_ms > 0) ?
+ (current_time - g_ppp_data_state.last_rx_time_ms) : 0xFFFFFFFF;
+ PPP_DEBUG_INFO("[SAFE_CHECK] ✓ Safe for command switch (idle=%ums, rate=%u bps)",
+ idle_ms, g_ppp_data_state.rx_rate_bps);
+ return true;
+}
+
+/**
+ * @brief 等待安全切换窗口
+ * @param timeout_ms 超时时间(毫秒)
+ * @return true 找到安全窗口,false 超时
+ */
+bool ppp_interrupt_wait_for_safe_switch(uint32_t timeout_ms)
+{
+ uint32_t start_time = ppp_get_current_time_ms();
+ uint32_t elapsed = 0;
+
+ PPP_DEBUG_INFO("[SAFE_WAIT] Waiting for safe switch window (timeout=%ums)...", timeout_ms);
+
+ while (elapsed < timeout_ms) {
+ if (ppp_interrupt_is_safe_for_command_switch()) {
+ PPP_DEBUG_INFO("[SAFE_WAIT] ✓ Safe window found (waited %ums)", elapsed);
+ return true;
+ }
+
+ // 短暂休眠,避免占用过多CPU
+ osal_msleep(100);
+
+ elapsed = ppp_get_current_time_ms() - start_time;
+ }
+
+ PPP_DEBUG_WARN("[SAFE_WAIT] Timeout after %ums, no safe window found", elapsed);
+ return false;
+}
+
+/**
+ * @brief 打印数据传输状态信息(调试用)
+ */
+void ppp_interrupt_print_data_state(void)
+{
+ uint32_t current_time = g_timer_timestamp_ms;
+ uint32_t idle_ms = (g_ppp_data_state.last_rx_time_ms > 0) ?
+ (current_time - g_ppp_data_state.last_rx_time_ms) : 0xFFFFFFFF;
+
+ PPP_DEBUG_WARN("╔═══════════════════════════════════════╗");
+ PPP_DEBUG_WARN("║ PPP Data Transfer State ║");
+ PPP_DEBUG_WARN("╠═══════════════════════════════════════╣");
+ PPP_DEBUG_WARN("║ PPP Connected: %s ║",
+ ppp_lwip_is_connected() ? "YES" : "NO ");
+ PPP_DEBUG_WARN("║ RX Idle Time: %u ms ║", idle_ms);
+ PPP_DEBUG_WARN("║ RX Rate: %u bytes/sec ║", g_ppp_data_state.rx_rate_bps);
+ PPP_DEBUG_WARN("║ Safe for +++: %s ║",
+ ppp_interrupt_is_safe_for_command_switch() ? "YES ✓" : "NO ✗");
+ PPP_DEBUG_WARN("╠═══════════════════════════════════════╣");
+
+ // Buffer状态
+ if (g_ping_pong_buffers != NULL) {
+ PPP_DEBUG_WARN("║ Buffer Status: ║");
+ for (uint8_t i = 0; i < PPP_PING_PONG_BUFFER_COUNT; i++) {
+ const char *state_str = "?";
+ switch (g_ping_pong_buffers[i].state) {
+ case PPP_BUFFER_STATE_EMPTY: state_str = "EMPTY "; break;
+ case PPP_BUFFER_STATE_FILLING: state_str = "FILLING "; break;
+ case PPP_BUFFER_STATE_FULL: state_str = "FULL "; break;
+ case PPP_BUFFER_STATE_PROCESSING: state_str = "PROCESSING"; break;
+ }
+ PPP_DEBUG_WARN("║ Buffer[%u]: %s ║", i, state_str);
+ }
+ } else {
+ PPP_DEBUG_WARN("║ Buffers: Not allocated ║");
+ }
+
+ PPP_DEBUG_WARN("╚═══════════════════════════════════════╝");
}
\ No newline at end of file