refactor(编号): 自愈层号与 timeSync 挂起、CubeMX 三层、采集链层名清号(代码面)
批次六余账之二(代码与脚本面)。四族都是「批次一 / 三c 改了文档、漏了代码」的半改 状态。 - 日志自愈:「L1 文件级自愈」→「文件级自愈」、「L2 错误去重」→「错误去重」(正文 本来就这么叫,层号纯属多余):App/log/soe_store.c、sys_log_mcu.c 三处、 test/host/sys_log_mcu 的测试与假件头共 10 处。 - timeSync:「L3 pending 化」→ 挂起请求 / pending 化——这条口径早写在记忆里, 今天才算全仓一致。App/sync/time_sync.c 3 处。 - CubeMX 防丢失三层优先级:scripts/check_cubemx_survival.py 6 处「由 L3 升级为 L2」「L2 受保护」「L3 兜底」→ 写进 .ioc / 搬进 USER CODE 区 / 审计兜底;变迁史 句子按「换号留事实」改写、日期原样保留。 - 采集链旧层名:App/README.md「采集与算法层(L1/L2/L3)」→「采集与算法层」; protect_task.c/.h「(L3 板端接线,B5)」→「(板端接线,B5)」。 - phasor 断言文案 19 处:改为 ASCII 的 phasor-in ring(C 字面量必须纯 ASCII)。 改前先证明这些串无耦合——全仓只有本文件含它们、harness 只看 returncode 与汇总 标记;改后 phasor 57/57 与基线同数。 - 零行为:剥注释 + 套登记表后与 HEAD 逐字节 / AST 相同;sys_log_mcu 141/141、 phasor 57/57、watchdog 47/47、freq 46/46 均与动手前基线同数。 - 同一四族的文档面(CubeMX 30、采集链 5、菜单层级 2、双写 14)由下一笔收。
This commit is contained in:
+1
-1
@@ -16,7 +16,7 @@ FreeRTOS/CMSIS-RTOS API**(见 `AGENTS.md`「平台约束」)。
|
||||
| `app/` | **应用入口与全局**:`app_main.c/h`(初始化入口)、`app_cfg.h`(裁剪决策占位说明,当前无宏)、`sys_events.h`(就绪事件) | [`app/README.md`](app/README.md) |
|
||||
| `cfg/` | **配置引擎**:`/config.ini` 解析 + 原子持久化(旧二进制档已废弃,2026-10-10) | [`cfg/README.md`](cfg/README.md) |
|
||||
| `sync/` | **时间同步任务**:`time_sync.c/h` | [`sync/README.md`](sync/README.md) |
|
||||
| `algo/` | **采集与算法层(L1/L2/L3)**:语义取数 + 有效性判定 + 采样环/相量/测频 + 定值模型 + 保护元件框架 | [`algo/README.md`](algo/README.md)(索引);设计 → `docs/算法/采集与算法层设计说明.md` |
|
||||
| `algo/` | **采集与算法层**:语义取数 + 有效性判定 + 采样环/相量/测频 + 定值模型 + 保护元件框架 | [`algo/README.md`](algo/README.md)(索引);设计 → `docs/算法/采集与算法层设计说明.md` |
|
||||
| `log/` | **日志子系统**:syslog(NAND)+ 控制台单写者日志 | [`log/README.md`](log/README.md) |
|
||||
| `task/` | **FreeRTOS 任务实现**(6 个任务) | [`task/README.md`](task/README.md) |
|
||||
| `util/` | **通用工具**:CRC / 环形缓冲 / 墙钟时间 | [`util/README.md`](util/README.md) |
|
||||
|
||||
+1
-1
@@ -185,7 +185,7 @@ static int s_soe_append(const uint8_t *rec) {
|
||||
fr = f_write(&f, rec, SOE_REC_SIZE, &bw);
|
||||
(void)f_close(&f);
|
||||
if ((fr != FR_OK) || (bw != SOE_REC_SIZE)) {
|
||||
/* L1 文件级自愈:**只有写失败**才删除重建、重试一次(打开失败走下面
|
||||
/* 文件级自愈:**只有写失败**才删除重建、重试一次(打开失败走下面
|
||||
* 的 else,不删——见函数头 ④)。unlink 返回值刻意不检查:失败也只是
|
||||
* 重试失败 → 留痕计数,绝不升级成卷操作。 */
|
||||
(void)f_unlink(SOE_PATH);
|
||||
|
||||
@@ -279,7 +279,7 @@ static volatile int8_t s_clear_st[SYSLOG_COUNT]; /* SYSLOG_CLEAR_NONE / OK /
|
||||
*/
|
||||
/*
|
||||
* 函数功能:判定一个 f_open 返回码是否属于"把自己的日志文件删掉重建一次"能修好
|
||||
* 的那一类,即 L1 文件级自愈的触发集(D 项整改,逐码依据见上方资料块)
|
||||
* 的那一类,即文件级自愈的触发集(D 项整改,逐码依据见上方资料块)
|
||||
* 入口参数:fr - f_open 的返回码 FRESULT
|
||||
* 返回值:1 - 属触发集,可 unlink 后重开一次;0 - 不属,一律立即失败、不 unlink、
|
||||
* 不计卷损坏 int
|
||||
@@ -362,8 +362,8 @@ static int s_append_rec(syslog_id_t id, const uint8_t *p_rec) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* L1 文件级自愈:陈旧/损坏条目 → 丢弃重建、重试一次(与上方容量满重建
|
||||
* 同一机制);L2 错误去重:持续故障只报第一次,恢复前静默(消除"每次
|
||||
/* 文件级自愈:陈旧/损坏条目 → 丢弃重建、重试一次(与上方容量满重建
|
||||
* 同一机制);错误去重:持续故障只报第一次,恢复前静默(消除"每次
|
||||
* 开机同一错误刷屏")。打开模式必须带 FA_WRITE 位:本 FatFs 移植的
|
||||
* FA_OPEN_APPEND(0x30) 不含 FA_WRITE(0x02),不带写位打开的文件 f_write
|
||||
* 恒返回 FR_DENIED(7)——2026-09-20 台架实测 /log 写失败 ×5/开机 真根因 */
|
||||
|
||||
@@ -39,11 +39,11 @@
|
||||
#define TIME_SYNC_PORT 8888
|
||||
|
||||
/*
|
||||
* 头阻塞修复 + L3 pending 化(timeSync 侧;lftpd 侧见 lftpd_inet.c):
|
||||
* 头阻塞修复 + 挂起请求(pending)化(timeSync 侧;lftpd 侧见 lftpd_inet.c):
|
||||
* 旧实现用单次 30s 阻塞 net_recv(默认 NET_RECV_TIMEOUT_MS)等时间包——等待期间
|
||||
* netTask(全部 socket 操作的唯一执行者)被独占,其余任务的网络操作(远端显示 /
|
||||
* FTP)整体停摆(历史审计遗留问题)。
|
||||
* 2026-09-22 先落地分片有界读(5ms 片),同日 L3 pending 化后改为"挂起请求":
|
||||
* 2026-09-22 先落地分片有界读(5ms 片),同日 pending 化后改为"挂起请求":
|
||||
* 每次等待 = 一次挂起登记(netTask 零占用,完成按主循环节拍检查),调用方
|
||||
* 单次超时 = 剩余总预算(总等待 ≤ TIME_SYNC_TOTAL_BUDGET_MS,语义与旧 30s
|
||||
* 一致);等待期间调用方在自己上下文睡任务通知,旧分片协议(片长/片间让出)退役。
|
||||
@@ -142,7 +142,7 @@ static void time_sync_handle_conn(int conn_sock) {
|
||||
TickType_t t0 = xTaskGetTickCount();
|
||||
|
||||
while (got < (int)sizeof(buf)) {
|
||||
/* 单次预算 = 剩余总预算(L3 pending:等待期 netTask 零占用,调用方
|
||||
/* 单次预算 = 剩余总预算(pending:等待期 netTask 零占用,调用方
|
||||
* 在自己上下文睡任务通知,旧片间 vTaskDelay(1) 让出退役)
|
||||
* ⚠ 看门狗约束:本任务在 required_mask 内,而单次 net_recv_to 可睡满
|
||||
* 30s 预算 —— 等待期必须周期性喂心跳,否则"对端连上但不发时间包"这种
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:保护任务(L3 板端接线,B5)——实现
|
||||
* 模块名称:保护任务(板端接线,B5)——实现
|
||||
* 模块功能:见 protect_task.h。每拍三件事:
|
||||
* ① 自检失败闭锁 采样故障闭锁:adc_health_flags() 电平位命中 → 元件状态
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:保护任务(L3 板端接线,B5)
|
||||
* 模块名称:保护任务(板端接线,B5)
|
||||
* 模块功能:protectTask 线程入口——以固定节拍驱动保护判据
|
||||
* (`prot_elm_run()`:phasor rms → 元件步进),并落实 自检失败闭锁 采样
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
|
||||
@@ -62,7 +62,7 @@ BASELINE = os.path.join(REPO, ".cubemx_survival_baseline.json")
|
||||
|
||||
CHECKS = [
|
||||
# ---------------- P0:开机死循环防线 ----------------
|
||||
# ✅ 2026-10-09 由 L3 升级为 L2:不再删生成区那句 `HAL_IWDG_Init(&hiwdg)`,
|
||||
# ✅ 2026-10-09 由「审计兜底」升级为「搬进 USER CODE 区」:不再删生成区那句 `HAL_IWDG_Init(&hiwdg)`,
|
||||
# 而是在 `USER CODE BEGIN 0` 里放一个空实现 + `#define HAL_IWDG_Init(a_h)
|
||||
# iwdg_deferred_start(a_h)`,把本编译单元里那句生成调用改名到空实现。
|
||||
# → 生成区保持原样、重生成**零 diff**,不必再手工删那一句。
|
||||
@@ -84,7 +84,7 @@ CHECKS = [
|
||||
# 旧模板在函数前后给自造区(HardFault_Handler / HardFault_Report),
|
||||
# 新模板改成函数体**内部**的 `HardFault_IRQn 0` / `W1_HardFault_IRQn 0`。
|
||||
# 实测"生成区之外的自造标记区"**不会被保留**。
|
||||
# ✅ 2026-10-09 落点升级为 L2(与 iwdg 同一招):4 个 `__asm` Handler 与报告实现
|
||||
# ✅ 2026-10-09 落点升级为「搬进 USER CODE 区」(与 iwdg 同一招):4 个 `__asm` Handler 与报告实现
|
||||
# 全部放 `USER CODE BEGIN 0`(标准保护位),生成区恢复 CubeMX 原样;
|
||||
# 生成实体靠 `#define X X_Gen` 改名让位(未被引用 → 链接器自动移除)。
|
||||
# ⚠ 顺序硬约束:我们的定义必须在 4 个 `#define` **之前**,否则被自己的宏改名。
|
||||
@@ -143,8 +143,8 @@ CHECKS = [
|
||||
"须在 USER CODE BEGIN 0 区内(生成区内的标准保护位)。",
|
||||
),
|
||||
# Error_Handler 统一降级(2026-10-12;详述见看门狗设计说明.md §4.4)。函数体本身在 CubeMX 的
|
||||
# `USER CODE BEGIN/END Error_Handler_Debug` 区内(L2 受保护),重生成不丢;
|
||||
# 本项是 L3 兜底:被打回模板默认(__disable_irq+while(1) 静默挂死)**不报编译错**,
|
||||
# `USER CODE BEGIN/END Error_Handler_Debug` 区内(USER CODE 区受保护),重生成不丢;
|
||||
# 本项是审计兜底:被打回模板默认(__disable_irq+while(1) 静默挂死)**不报编译错**,
|
||||
# 只在真出外设初始化故障时暴露——整机只剩 IWDG 兜底且无自检日志。
|
||||
dict(
|
||||
id="error-handler-degrade",
|
||||
@@ -161,7 +161,7 @@ CHECKS = [
|
||||
# ---------------- P1:FreeRTOS 加固 ----------------
|
||||
# ⚠ 2026-10-09 升级:这两项原先靠 FreeRTOSConfig.h 里**自造**的
|
||||
# `USER CODE BEGIN FREE_RTOS_CONFIG_HARDENING` 区——模板不认这个区名,
|
||||
# 重生成连标记带内容一起消失(实测两次)。现已改为 **L1 写进 .ioc**:
|
||||
# 重生成连标记带内容一起消失(实测两次)。现已改为 **写进 .ioc**:
|
||||
# GUI = FreeRTOS 页 → "Config parameters" 标签 → "Hook function related
|
||||
# definitions" 组 → CHECK_FOR_STACK_OVERFLOW=2 / USE_MALLOC_FAILED_HOOK=1,
|
||||
# 由 CubeMX 模板自己生成到 FreeRTOSConfig.h,永不被打回。
|
||||
@@ -312,7 +312,7 @@ CHECKS = [
|
||||
# (FadcConstraint Max=36000000;APB2=84 MHz → DIV2=42 MHz 超限,选不到),
|
||||
# .ioc 虽不保存 ADC1.ClockPrescaler 键,重生成也只会回落到约束允许的值。
|
||||
# ADC1 上电自校准(2026-10-10 补):RM0090 §13.3.6 的**必需**步骤,CubeMX **不生成**,
|
||||
# 且本仓库裁剪版 HAL **没有** HAL_ADCEx_Calibration_Start → 只能手写(L2),
|
||||
# 且本仓库裁剪版 HAL **没有** HAL_ADCEx_Calibration_Start → 只能手写(搬进 USER CODE 区),
|
||||
# 故必须在此兜底。丢了它不报编译错,只让 ADC 带失调误差(难从日志看出)。
|
||||
dict(
|
||||
id="adc1-calibration-call",
|
||||
|
||||
@@ -312,9 +312,9 @@ static void tc_ring(void) {
|
||||
int ok;
|
||||
|
||||
sample_ring_init();
|
||||
CHECK(sample_ring_filled() == 0u, "L2-in ring: init clears fill");
|
||||
CHECK(sample_ring_frames() == 0u, "L2-in ring: init clears frame counter");
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, 20u, w) == -2, "L2-in ring: window before data -> -2");
|
||||
CHECK(sample_ring_filled() == 0u, "phasor-in ring: init clears fill");
|
||||
CHECK(sample_ring_frames() == 0u, "phasor-in ring: init clears frame counter");
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, 20u, w) == -2, "phasor-in ring: window before data -> -2");
|
||||
|
||||
/* 前 3 帧:UA = 100/200/300 */
|
||||
ok = 1;
|
||||
@@ -323,15 +323,15 @@ static void tc_ring(void) {
|
||||
f[ADC_SEM_UA] = (float)(100 * (i + 1));
|
||||
if (sample_ring_push_frame(f, (uint8_t)ADC_SEM_COUNT) != 0) { ok = 0; }
|
||||
}
|
||||
CHECK(ok, "L2-in ring: 3 frames pushed OK");
|
||||
CHECK(sample_ring_filled() == 3u, "L2-in ring: filled == 3");
|
||||
CHECK(ok, "phasor-in ring: 3 frames pushed OK");
|
||||
CHECK(sample_ring_filled() == 3u, "phasor-in ring: filled == 3");
|
||||
CHECK((sample_ring_window(ADC_SEM_UA, 3u, w) == 0)
|
||||
&& (w[0] == 100.0f) && (w[1] == 200.0f) && (w[2] == 300.0f),
|
||||
"L2-in ring: window is chronological (old -> new)");
|
||||
"phasor-in ring: window is chronological (old -> new)");
|
||||
/* 通道隔离:其它语义通道不应被 UA 的写入污染 */
|
||||
CHECK((sample_ring_window(ADC_SEM_IB, 3u, w) == 0)
|
||||
&& (w[0] == 0.0f) && (w[1] == 0.0f) && (w[2] == 0.0f),
|
||||
"L2-in ring: channels are independent");
|
||||
"phasor-in ring: channels are independent");
|
||||
|
||||
/* 推到 45 帧(> DEPTH=40)→ 回绕 */
|
||||
for (i = 3; i < 45; i++) {
|
||||
@@ -339,25 +339,25 @@ static void tc_ring(void) {
|
||||
f[ADC_SEM_UA] = (float)i;
|
||||
(void)sample_ring_push_frame(f, (uint8_t)ADC_SEM_COUNT);
|
||||
}
|
||||
CHECK(sample_ring_filled() == SAMPLE_RING_DEPTH, "L2-in ring: fill saturates at DEPTH");
|
||||
CHECK(sample_ring_frames() == 45u, "L2-in ring: frame counter is NOT saturated");
|
||||
CHECK(sample_ring_filled() == SAMPLE_RING_DEPTH, "phasor-in ring: fill saturates at DEPTH");
|
||||
CHECK(sample_ring_frames() == 45u, "phasor-in ring: frame counter is NOT saturated");
|
||||
|
||||
ok = (sample_ring_window(ADC_SEM_UA, 20u, w) == 0);
|
||||
for (i = 0; i < 20; i++) { if (w[i] != (float)(25 + i)) { ok = 0; } }
|
||||
CHECK(ok, "L2-in ring: wrapped window == last 20 values, in order");
|
||||
CHECK(ok, "phasor-in ring: wrapped window == last 20 values, in order");
|
||||
|
||||
ok = (sample_ring_window(ADC_SEM_UA, (uint8_t)SAMPLE_RING_DEPTH, w) == 0);
|
||||
for (i = 0; i < (int)SAMPLE_RING_DEPTH; i++) { if (w[i] != (float)(5 + i)) { ok = 0; } }
|
||||
CHECK(ok, "L2-in ring: full-depth window == last DEPTH values, in order");
|
||||
CHECK(ok, "phasor-in ring: full-depth window == last DEPTH values, in order");
|
||||
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, 0u, w) == -1, "L2-in ring: n=0 rejected");
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, 0u, w) == -1, "phasor-in ring: n=0 rejected");
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, (uint8_t)(SAMPLE_RING_DEPTH + 1u), w) == -1,
|
||||
"L2-in ring: n > DEPTH rejected");
|
||||
"phasor-in ring: n > DEPTH rejected");
|
||||
CHECK(sample_ring_window((adc_semantic_t)ADC_SEM_COUNT, 20u, w) == -1,
|
||||
"L2-in ring: out-of-range channel rejected");
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, 20u, NULL) == -1, "L2-in ring: NULL out rejected");
|
||||
CHECK(sample_ring_push_frame(NULL, (uint8_t)ADC_SEM_COUNT) == -1, "L2-in ring: NULL frame rejected");
|
||||
CHECK(sample_ring_push_frame(f, 3u) == -1, "L2-in ring: wrong frame length rejected");
|
||||
"phasor-in ring: out-of-range channel rejected");
|
||||
CHECK(sample_ring_window(ADC_SEM_UA, 20u, NULL) == -1, "phasor-in ring: NULL out rejected");
|
||||
CHECK(sample_ring_push_frame(NULL, (uint8_t)ADC_SEM_COUNT) == -1, "phasor-in ring: NULL frame rejected");
|
||||
CHECK(sample_ring_push_frame(f, 3u) == -1, "phasor-in ring: wrong frame length rejected");
|
||||
}
|
||||
|
||||
/* ===================== TC-PHASOR-020/021/022:实例层 + 滑动窗 + 双区 ===================== */
|
||||
@@ -538,13 +538,13 @@ int main(void) {
|
||||
tc_harmonic();
|
||||
printf("-- frequency sensitivity --\n");
|
||||
tc_freqdev();
|
||||
printf("-- L2 input sample ring --\n");
|
||||
printf("-- phasor input sample ring --\n");
|
||||
tc_ring();
|
||||
printf("-- 基波相量实例 / 每 1 ms 滑动窗刷新 / 双区指针原子交换 instance layer --\n");
|
||||
tc_instances();
|
||||
printf("-- 双区指针原子交换 dual-zone swap --\n");
|
||||
tc_dualzone();
|
||||
printf("-- L2 zero / init --\n");
|
||||
printf("-- phasor zero / init --\n");
|
||||
tc_zero();
|
||||
|
||||
printf("\n=== Phasor Tests: %d/%d PASSED (failed=%d) ===\n",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* 模块名称:主机侧单测桩 - dbg_log.h(sys_log_mcu 套件专用)
|
||||
* 模块功能:DBG_* 换成计数,让"写故障只报第一次(L2 去重)"与"挂载失败重试不刷屏"
|
||||
* 模块功能:DBG_* 换成计数,让"写故障只报第一次(去重)"与"挂载失败重试不刷屏"
|
||||
* 成为可断言的行为。
|
||||
*
|
||||
* ⚠ 仅供 test/host/sys_log_mcu/ 使用,不参与 MCU 构建。
|
||||
*
|
||||
* 为什么本模块尤其需要计数而不是直通打印:sys_log_mcu.c 的 s_append_rec() 里
|
||||
* 有一条刻意设计的静默规则(源码注释)——
|
||||
* "L2 错误去重:持续故障只报第一次,恢复前静默(消除每次开机同一错误刷屏)"
|
||||
* "错误去重:持续故障只报第一次,恢复前静默(消除每次开机同一错误刷屏)"
|
||||
* 直通 printf 只能让人眼看,"到底报了几次"必须可数才能钉住;而另一头,
|
||||
* 挂载幂等里的"建 /log 失败日志去重(成功复位)"同样是次断言。
|
||||
*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* 模块功能:在 PC 上离线验证 App/log/sys_log_mcu.c 的四族契约——
|
||||
* A 64B 定长记录格式(时间戳 / epoch ASCII / 描述三段 + 截断 + 占位)
|
||||
* B 写侧(单条 s_append_rec、批量 s_append_many、日志读写放大收口的"一批一次
|
||||
* open/write/close"、容量轮转、L1 自愈、L2 留痕去重、卷锁 try)
|
||||
* open/write/close"、容量轮转、文件级自愈、留痕去重、卷锁 try)
|
||||
* C 排空(syslog_drain 的 preboot + 队列两条来源、换文件分批、
|
||||
* 失败回投不丢条目、-3 退回慢路径)
|
||||
* D 读侧(日志读写放大收口的 8 条滑动窗口 + 写者代数失效 + 越界/忙/短读处置)
|
||||
@@ -1634,7 +1634,7 @@ static void tc_name_rules(void)
|
||||
(void)ff_fake_mkfile(P_SELFTEST, NULL, SYSLOG_REC_SIZE); /* 邻居文件 */
|
||||
(void)ff_fake_mkfile("/config.ini", NULL, 12u); /* 同卷别的东西 */
|
||||
/* D 项整改后:名字/参数类码**一次都不许 unlink**(旧实现每轮删一次自己的
|
||||
* 历史日志、且永远修不好)。留痕仍受 L2 去重,只 1 条。 */
|
||||
* 历史日志、且永远修不好)。留痕仍受去重约束,只 1 条。 */
|
||||
ff_fake_inject_rc(P_RUN, FF_FAKE_OP_OPEN, FR_INVALID_NAME, 200);
|
||||
for (i = 0u; i < 20u; i++) {
|
||||
(void)s_append(SYSLOG_RUN, "bad-name");
|
||||
@@ -1661,7 +1661,7 @@ static void tc_extra_branches(void)
|
||||
|
||||
printf("-- TC-SYSLOG-090..100 remaining branch coverage --\n");
|
||||
|
||||
/* 090 批量路径的 L1 自愈:open 失败一次 -> unlink + 重开 -> 整批照常落盘
|
||||
/* 090 批量路径的文件级自愈:open 失败一次 -> unlink + 重开 -> 整批照常落盘
|
||||
* (这条钉的是 s_append_many 里那段"和单条同一份自愈表";漏了它,
|
||||
* FTP 侧删过文件之后的第一批日志就会整批丢) */
|
||||
reset_all();
|
||||
@@ -1911,7 +1911,7 @@ static void tc_selfheal_codes(void)
|
||||
* 测不到,只能从"恢复后第一次真失败仍立刻留痕"反证它没被置位) */
|
||||
reset_all();
|
||||
ready_only();
|
||||
/* s_append_rec 的 L2 去重位是函数级 static,外部清不了:先用一次成功写复位 */
|
||||
/* s_append_rec 的去重位是函数级 static,外部清不了:先用一次成功写复位 */
|
||||
ok = (s_append(SYSLOG_RUN, "reset-dedup") == 0);
|
||||
g_sys_err_count = 0;
|
||||
lock_busy_next(1);
|
||||
|
||||
Reference in New Issue
Block a user