feat(config): 优化NimBLE配置以节省内存并提升OTA性能
- 启用BLE连接事件长度优化,允许单CE内传输多包,提升OTA吞吐 - 缩减NimBLE mbuf池配置,单连接OTA场景节省约7KB内存 - 禁用未使用的标准GATT服务,仅保留自定义OTA service,节省8-15KB - 缩减NimBLE传输缓冲区配置以优化内存使用 refactor(debug_log): 重构环形日志缓冲区API以支持逐条弹出 - 新增ringPopOldest方法,支持弹出最旧日志并从缓冲区移除 - 重构ringDrainJson实现,基于新的逐条弹出机制 - 改进日志转义处理逻辑,支持更多特殊字符转义 perf(tasks): 优化各任务栈大小配置以节省内存 - 将ota_relay任务栈从12288字节缩减至6144字节 - 将ble_ota任务栈从8192字节缩减至4096字节 - 将ble_ota数据工作线程栈从8192字节缩减至4096字节 - 通过栈高水位监控验证实际使用情况,确保安全余量 feat(monitor): 添加任务句柄获取接口以支持系统状态监控 - 为HealthMonitor、OtaRelay、BleOta和WifiOta类添加任务句柄获取方法 - 在任务入口处记录当前任务句柄 - 便于系统状态监控和调试信息收集 feat(status): 扩展系统状态API以提供更详细的内存和任务信息 - 增加内部堆和默认堆的详细统计信息 - 添加各关键任务的栈使用情况监控 - 扩展/system/status端点返回更全面的系统资源使用情况 - 包含最大空闲块、最小空闲内存等关键指标
This commit is contained in:
+212
@@ -116,6 +116,12 @@ body::before {
|
||||
text-transform: uppercase; letter-spacing: .06em;
|
||||
}
|
||||
.card-head .ico { font-size: 15px; }
|
||||
.card-head-btn {
|
||||
margin-left: auto;
|
||||
padding: 4px 10px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.card-body { padding: 16px 18px; }
|
||||
.card.collapsed .card-body { display: none; }
|
||||
.card-head { cursor: pointer; }
|
||||
@@ -326,6 +332,211 @@ select option { background: var(--bg-panel); color: var(--text); }
|
||||
}
|
||||
.metric .v.highlight { color: var(--accent); }
|
||||
|
||||
.status-kv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
.status-kv {
|
||||
background: var(--bg-elevated);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.status-kv .k {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: var(--text-label);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .08em;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.status-kv b {
|
||||
display: block;
|
||||
color: var(--text);
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
word-break: break-word;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
.status-section-title { margin-top: 14px; margin-bottom: 8px; font-size: 11px; color: var(--text-label); text-transform: uppercase; letter-spacing: .08em; }
|
||||
|
||||
/* ===== 堆概况 ===== */
|
||||
.heap-group {
|
||||
background: rgba(255,255,255,0.02);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.heap-group:last-child { margin-bottom: 0; }
|
||||
|
||||
.heap-group-title {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--text-label);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.heap-bar-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.heap-bar-text {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
min-width: 165px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.heap-bar-track {
|
||||
flex: 1;
|
||||
height: 14px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-radius: 7px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.heap-bar-fill {
|
||||
display: block;
|
||||
height: 100%;
|
||||
border-radius: 7px;
|
||||
background: linear-gradient(90deg, var(--accent), #5eead4);
|
||||
transition: width .4s ease;
|
||||
.heap-bar-fill.warn {
|
||||
background: linear-gradient(90deg, #f59e0b, #d97706);
|
||||
}
|
||||
.heap-bar-fill.danger {
|
||||
background: linear-gradient(90deg, #ef4444, #dc2626);
|
||||
}
|
||||
}
|
||||
|
||||
.heap-bar-pct {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
min-width: 42px;
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--text-dim);
|
||||
}
|
||||
|
||||
.heap-detail-row {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
font-size: 11px;
|
||||
color: var(--text-dim);
|
||||
margin-top: 6px;
|
||||
padding-top: 6px;
|
||||
border-top: 1px solid rgba(255,255,255,0.04);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.heap-detail-row span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.heap-detail-row b {
|
||||
color: var(--text);
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.status-task-list {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
.status-task {
|
||||
background: var(--bg-elevated);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.status-task-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.status-task-name {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
.status-task-ratio {
|
||||
font-size: 11px;
|
||||
color: var(--text-dim);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
.status-task-bar {
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--bg-input);
|
||||
overflow: hidden;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.status-task-bar-fill {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #22d3ee, #06b6d4);
|
||||
}
|
||||
.status-task-bar-fill.warn {
|
||||
background: linear-gradient(90deg, #f59e0b, #d97706);
|
||||
}
|
||||
.status-task-bar-fill.err {
|
||||
background: linear-gradient(90deg, #ef4444, #dc2626);
|
||||
}
|
||||
.status-task-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.status-task-meta span {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: var(--text-label);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .06em;
|
||||
}
|
||||
.status-task-meta b {
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
color: var(--text);
|
||||
font-size: 11px;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
.status-json {
|
||||
margin-top: 0;
|
||||
padding: 12px;
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-elevated);
|
||||
color: var(--text-dim);
|
||||
font-size: 11px;
|
||||
line-height: 1.6;
|
||||
max-height: 280px;
|
||||
overflow: auto;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
.status-empty {
|
||||
padding: 12px;
|
||||
border: 1px dashed var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--text-dim);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* === PRIMARY STATUS BADGES (large) === */
|
||||
.badge-grid {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px;
|
||||
@@ -662,6 +873,7 @@ code { color: #d3f9ff; font-family: var(--font-mono); }
|
||||
.container { padding: 16px; }
|
||||
.header-bar { flex-direction: column; align-items: flex-start; }
|
||||
.badge-grid, .metric-grid { grid-template-columns: 1fr; }
|
||||
.status-kv-grid, .status-task-meta { grid-template-columns: 1fr; }
|
||||
.can-grid { grid-template-columns: 1fr 1fr; }
|
||||
.btn-row { flex-direction: column; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user