From 559890c482f5973f06aafdfec9550fee5ba3c7f2 Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 09 十一月 2026 17:02:15 +0800
Subject: [PATCH] feat: CAN 模拟器 TCP 化 + 多设备并发调试 + 后台生命周期管理
---
docs/MultiProcess_Instrument_Resource_Solution.html | 799 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 799 insertions(+), 0 deletions(-)
diff --git a/docs/MultiProcess_Instrument_Resource_Solution.html b/docs/MultiProcess_Instrument_Resource_Solution.html
new file mode 100644
index 0000000..d4ae689
--- /dev/null
+++ b/docs/MultiProcess_Instrument_Resource_Solution.html
@@ -0,0 +1,799 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>澶氳繘绋�/澶氱嚎绋嬪満鏅笅鐨勪华鍣ㄨ祫婧愮嫭鍗犱笌鍏变韩鏂规</title>
+<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
+<style>
+ * { box-sizing: border-box; }
+ body {
+ font-family: -apple-system, "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif;
+ max-width: 1240px; margin: 0 auto; padding: 32px 24px 80px;
+ background: #FAFAFA; color: #212121; line-height: 1.75;
+ }
+ h1 { font-size: 29px; color: #1565C0; border-bottom: 3px solid #1976D2; padding-bottom: 12px; }
+ h2 { font-size: 23px; color: #0D47A1; margin-top: 42px; padding-left: 12px; border-left: 4px solid #FF9800; }
+ h3 { font-size: 17px; color: #37474F; margin-top: 26px; }
+ h4 { font-size: 15px; color: #455A64; margin-top: 18px; }
+ .subtitle { color: #757575; font-size: 14px; margin-bottom: 24px; }
+ .card { background: white; border-radius: 8px; padding: 18px 22px; margin: 16px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
+ .highlight { background: #FFF8E1; border-left: 4px solid #FFC107; padding: 12px 16px; margin: 12px 0; border-radius: 4px; }
+ .info { background: #E3F2FD; border-left: 4px solid #2196F3; padding: 12px 16px; margin: 12px 0; border-radius: 4px; }
+ .success { background: #E8F5E9; border-left: 4px solid #4CAF50; padding: 12px 16px; margin: 12px 0; border-radius: 4px; }
+ .warn { background: #FBE9E7; border-left: 4px solid #FF5722; padding: 12px 16px; margin: 12px 0; border-radius: 4px; }
+ table { width: 100%; border-collapse: collapse; margin: 16px 0; background: white; border-radius: 6px; overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,0.06); font-size: 13.5px; }
+ th { background: #1976D2; color: white; padding: 9px 12px; text-align: left; font-weight: 600; }
+ td { padding: 8px 12px; border-bottom: 1px solid #EEEEEE; vertical-align: top; }
+ tr:nth-child(even) td { background: #FAFAFA; }
+ tr:hover td { background: #E3F2FD; }
+ code { font-family: "Consolas", "Monaco", monospace; background: #F5F5F5; color: #C62828; padding: 2px 6px; border-radius: 3px; font-size: 13px; }
+ pre { background: #263238; color: #ECEFF1; padding: 16px 20px; border-radius: 6px; overflow-x: auto; font-family: "Consolas", monospace; font-size: 13px; line-height: 1.55; }
+ pre code { background: transparent; color: inherit; padding: 0; font-size: 13px; }
+ .mermaid { background: white; padding: 20px; border-radius: 8px; margin: 20px 0; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.06); overflow-x: auto; }
+ ul { padding-left: 22px; } li { margin: 4px 0; }
+ .toc { background: #F5F5F5; padding: 16px 24px; border-radius: 6px; margin: 20px 0; }
+ .toc a { color: #1976D2; text-decoration: none; display: block; padding: 3px 0; }
+ .toc a:hover { text-decoration: underline; }
+ .kwd { color: #FFCC80; } .str { color: #C5E1A5; } .cmt { color: #546E7A; } .fn { color: #82AAFF; }
+ .good { color: #2E7D32; font-weight: 600; } .bad { color: #C62828; font-weight: 600; } .mid { color: #EF6C00; font-weight: 600; }
+ footer { margin-top: 60px; padding-top: 20px; border-top: 1px solid #E0E0E0; color: #757575; font-size: 12px; text-align: center; }
+ .path { font-family: Consolas, monospace; font-size: 12.5px; background: #ECEFF1; color: #37474F; padding: 1px 6px; border-radius: 3px; }
+</style>
+</head>
+<body>
+
+<h1>澶氳繘绋� / 澶氱嚎绋嬪満鏅笅鐨勪华鍣ㄨ祫婧愮嫭鍗犱笌鍏变韩鏂规</h1>
+<div class="subtitle">TestPlatform Aging Software 路 SQLite 璁惧娉ㄥ唽 + Aging.Infrastructure 绉熺害 + OpenTAP 搴忓垪鎵ц鍣� 涓夋爤铻嶅悎璁捐 路 2026-11-03</div>
+
+<div class="toc">
+ <strong>鐩綍</strong>
+ <a href="#s1">1. 鐜扮姸鐩樼偣涓庨棶棰樺畾涔�</a>
+ <a href="#s2">2. 涓ょ被骞跺彂鍦烘櫙鐨勪弗鏍煎尯鍒�</a>
+ <a href="#s3">3. 浜斾釜鍊欓�夋柟妗堥�愪竴璇勪及涓庢í鍚戝姣�</a>
+ <a href="#s4">4. 鎺ㄨ崘鐩爣鏋舵瀯锛氬垎灞傛贩鍚堬紙绉熺害琛� + 浠茶瑙勫垯 + 鎸夐渶 Broker锛�</a>
+ <a href="#s5">5. 绉熺害瀹屾暣鐢熷懡鍛ㄦ湡锛氱敵璇� / 缁湡 / 閲婃斁 / 瓒呮椂鎶㈠崰</a>
+ <a href="#s6">6. 鍏ㄨ嚜鍔� vs 鎵嬪姩缁存姢鐨勪簰鏂ヤ徊瑁佽鍒�</a>
+ <a href="#s7">7. 寮傚父鍦烘櫙澶勭悊锛氭閿� / 瀛ゅ効閿� / 鏃堕挓 / 骞傜瓑</a>
+ <a href="#s8">8. 鐙崰 or 鍒嗘椂澶嶇敤锛氳澶囧垎缁勪笌 Slot 缁戝畾绛栫暐</a>
+ <a href="#s9">9. 鏈粨搴撴敼閫犳竻鍗曪紙鍏蜂綋鏂囦欢璺緞 + 鎺ュ彛绛惧悕 + DDL锛�</a>
+ <a href="#s10">10. 娴嬭瘯瑕佺偣锛氬崟鍏� / 澶氳繘绋嬮泦鎴� / 宕╂簝婕旂粌</a>
+ <a href="#s11">11. 鍒嗛樁娈靛疄鏂借鍒掍笌宸ヤ綔閲忎及绠�</a>
+ <a href="#s12">12. 椋庨櫓銆佸弽妯″紡涓庝笉鎺ㄨ崘鍋氭硶</a>
+ <a href="#s13">13. 缁撹</a>
+</div>
+
+<!-- ================================================================= -->
+<h2 id="s1">1. 鐜扮姸鐩樼偣涓庨棶棰樺畾涔�</h2>
+
+<div class="card">
+<strong>鍏堣缁撹锛氫綘浠殑鏋舵瀯宸茬粡"鍗婂彧鑴�"韪╁湪姝g‘鏂规涓娿��</strong>
+<code>ResourceOwnerToken</code>锛堝惈 Generation 涓栦唬鍙凤級銆�<code>reservation_ref</code> 瀛楁銆�<code>IAutoDeviceLease</code> 浣滅敤鍩熲�斺�旇繖浜涙蹇典笌宸ヤ笟鐣屾爣鍑嗙殑"绉熺害锛圠ease锛�+ 鏍呮爮浠ょ墝锛團encing Token锛�"妯″瀷涓�涓�瀵瑰簲銆傚敮涓�鐨勯棶棰樻槸锛�<strong>鏁村鏈哄埗娲诲湪鍐呭瓨閲�</strong>銆�
+</div>
+
+<h3>1.1 鐜扮姸浠g爜浜嬪疄鏍告煡</h3>
+<table>
+ <tr><th>缁勪欢</th><th>鏂囦欢</th><th>鐜扮姸</th><th>璺ㄨ繘绋嬭兘鍔�</th></tr>
+ <tr>
+ <td>ResourceManager</td>
+ <td><span class="path">Aging.Infrastructure/Core/ResourceManager.cs</span></td>
+ <td><code>ConcurrentDictionary</code> 瀛橀绾� + <code>SemaphoreSlim(1,1)</code> 姣忚祫婧愮粏閿侊紱Generation 鍏ㄥ眬鑷</td>
+ <td class="bad">鉂� 绾繘绋嬪唴瀛橈紝鍏朵粬杩涚▼瀹屽叏涓嶅彲瑙�</td>
+ </tr>
+ <tr>
+ <td>ResourceOwnerToken</td>
+ <td><span class="path">Contracts/ResourceOwnerToken.cs</span></td>
+ <td>TokenId + OwnerType(Production/Maintenance) + Generation + IssuedAt/ExpiresAt</td>
+ <td class="mid">鈿狅笍 缁撴瀯鍙簭鍒楀寲锛屼絾鐩墠娌℃湁璺ㄨ繘绋嬫牎楠岃矾寰�</td>
+ </tr>
+ <tr>
+ <td>AutoDeviceFacade / Lease</td>
+ <td><span class="path">Services/AutoDeviceFacade.cs</span></td>
+ <td>Reserve 鈫� DeviceService 鍒嗘淳 鈫� finally Release锛汱ease 浣滅敤鍩熷鐢�</td>
+ <td class="bad">鉂� 渚濊禆鍐呭瓨鐗� ResourceManager</td>
+ </tr>
+ <tr>
+ <td>DeviceService</td>
+ <td><span class="path">Services/DeviceService.cs</span></td>
+ <td>鎵ц鍓� <code>ValidateOwner</code>锛堝唴瀛樻煡琛級鈫� <code>AcquireOperationAsync</code> 鈫� driver 涓嬪彂</td>
+ <td class="bad">鉂� 鏍¢獙浠呮湰杩涚▼鏈夋晥</td>
+ </tr>
+ <tr>
+ <td>DebugSessionManager</td>
+ <td><span class="path">Plugin.DeviceDebug/Model/DebugSessionManager.cs</span></td>
+ <td>RequestMaintenance 宸叉崟鑾� <code>ResourceConflictException</code>锛屽苟鎶� <code>reservation.ReservationId</code> 鍐欏叆 <code>session.ReservationRef</code> 鎸佷箙鍖�</td>
+ <td class="mid">鈿狅笍 宸查鐣欐寕鎺ョ偣锛屽樊涓�涓�"娲荤殑"浠茶婧�</td>
+ </tr>
+ <tr>
+ <td>debug_session 琛�</td>
+ <td><span class="path">Plugin.DeviceDebug/Model/DeviceDebugModel.cs</span></td>
+ <td>鏈� <code>reservation_ref TEXT</code>銆�<code>state</code>銆�<code>closed_at</code>锛屾棤蹇冭烦/杩囨湡鍒�</td>
+ <td class="mid">鈿狅笍 鍙墿灞�</td>
+ </tr>
+ <tr>
+ <td>IPC 璁炬柦</td>
+ <td><span class="path">ConnectionUtil/PipeServer.cs 路 PipeClient.cs</span></td>
+ <td>鍛藉悕绠¢亾锛圡essage 妯″紡锛夊凡瀹炵幇锛氬瀹炰緥鏈嶅姟绔�佽繛鎺ヤ簨浠躲�佽姹�-鍝嶅簲 SendMessage锛堝甫瓒呮椂锛�</td>
+ <td class="good">鉁� 鍙洿鎺ヤ綔涓� Device Broker 鐨勪紶杈撳眰锛屾棤闇�鏂伴�犺疆瀛�</td>
+ </tr>
+ <tr>
+ <td>OpenTAP SynchronizationManager</td>
+ <td>OpenTAP 9.31 寮曟搸</td>
+ <td>杩涚▼鍐� <code>RequestLock(resource, timeout)</code> 鎸変华鍣ㄤ簰鏂�</td>
+ <td class="bad">鉂� 瀹樻柟鏂囨。鏄庣‘锛氫粎杩涚▼鍐�</td>
+ </tr>
+</table>
+
+<h3>1.2 闂鏈川鎷嗚В</h3>
+<div class="highlight">
+"澶氬伐浣嶅叡鐢ㄤ竴鍙颁华鍣�"鍏跺疄鍖呭惈 <strong>涓変釜涓嶅悓灞傞潰</strong>鐨勯棶棰橈紝蹇呴』鍒嗗紑瑙e喅锛屾贩鍦ㄤ竴璧疯皥蹇呯劧鏂规璧板舰锛�
+<ol>
+<li><strong>浠茶锛圓rbitration锛�</strong>锛氳皝<em>鏈夋潈</em>鍦ㄨ繖鍙颁华鍣ㄤ笂鍙戝懡浠わ紵鈫� 闇�瑕佽法杩涚▼鍙銆佸彲鎸佷箙鍖栥�佸穿婧冨彲鍥炴敹鐨�<strong>绉熺害鐘舵��</strong>銆�</li>
+<li><strong>杩炴帴鐙崰锛圕onnection锛�</strong>锛氱墿鐞嗗彞鏌勶紙COM 鍙c�乁SB銆丆AN 鍗★級鍚屼竴鏃跺埢鍙兘琚竴涓繘绋� <code>open</code>锛涚綉鍙d华鍣ㄥ垯鍏佽鍚屾満澶氳繛鎺ヤ絾闇�瑕�"閫昏緫鐙崰"璇箟銆傗啋 闇�瑕佹妸<strong>杩炴帴鎸佹湁鑰呬笌绉熺害鎸佹湁鑰呯粦瀹�</strong>锛屽繀瑕佹椂寮曞叆浠g悊杩涚▼銆�</li>
+<li><strong>鍛戒护涓茶鍖栵紙Serialization锛�</strong>锛氬垎鏃跺鐢ㄥ瀷璁惧锛堝鍏变韩娓╃锛夛紝鍏佽澶氬伐浣嶆帓闃熶笅鍙戝師瀛愬懡浠ょ墖娈点�傗啋 闇�瑕�<strong>闃熷垪/鏍呮爮浠ょ墝</strong>锛岃�岄潪鐙崰绉熺害銆�</li>
+</ol>
+</div>
+
+<!-- ================================================================= -->
+<h2 id="s2">2. 涓ょ被骞跺彂鍦烘櫙鐨勪弗鏍煎尯鍒�</h2>
+
+<div class="mermaid">
+graph TB
+ subgraph 鍦烘櫙A["鍦烘櫙 A锛氬悓杩涚▼澶氱嚎绋嬶紙鍗� HMI 涓荤▼搴忓唴锛�"]
+ A1["OpenTAP 骞惰姝ラ / MultiSite 璋冨害绾跨▼"] --- A2["WPF UI 绾跨▼锛堟墜鍔ㄨ皟璇曪級"]
+ A3["ResultProxy 钀藉簱绾跨▼"]
+ end
+ subgraph 鍦烘櫙B["鍦烘櫙 B锛氳法杩涚▼ / 璺ㄦ満鍣�"]
+ B1["宸ヤ綅杩涚▼1 tap.exe/Station1.exe"]
+ B2["宸ヤ綅杩涚▼2 Station2.exe"]
+ B3["HMI 涓荤▼搴忥紙缁存姢宸ョ▼甯堬級"]
+ B4["鍏朵粬鏈哄櫒涓婄殑鎵ц鑺傜偣<br/>锛堝鏈哄叡娴嬩竴鍙颁华鍣級"]
+ end
+ subgraph 瑙e喅鎵嬫["鍒嗗埆瀵瑰簲鐨勬墜娈�"]
+ S1["OpenTAP SynchronizationManager<br/>+ 鐜版湁鍐呭瓨鐗� ResourceManager<br/>锛堜繚鎸佷笉鍙� 鉁咃級"]
+ S2["鎸佷箙鍖栫绾﹁〃锛圖B Lease锛�<br/>+ Fencing Generation<br/>+ 蹇冭烦 TTL + 浠茶绛栫暐<br/>锛堟湰娆℃柊寤� 猸愶級"]
+ end
+ 鍦烘櫙A --> S1
+ 鍦烘櫙B --> S2
+</div>
+
+<table>
+ <tr><th>缁村害</th><th>鍦烘櫙 A锛氳繘绋嬪唴澶氱嚎绋�</th><th>鍦烘櫙 B锛氳法杩涚▼/璺ㄦ満鍣�</th></tr>
+ <tr><td>鍏稿瀷瑙﹀彂</td><td>TestPlan 涓� Parallel 姝ラ / MultiSite 鍚屾椂璺戜笉鍚屽垎鏀�</td><td>澶氬伐浣嶇嫭绔嬭繘绋嬨�丠MI 涓庤嚜鍔ㄦ祴璇曞苟琛屻�丆I 鑺傜偣</td></tr>
+ <tr><td>浜掓枼鍘熻</td><td>SemaphoreSlim / lock / SynchronizationManager.RequestLock</td><td>OS 鍛藉悕鍐呮牳瀵硅薄 / DB 绉熺害 / Broker 闃熷垪</td></tr>
+ <tr><td>宕╂簝琛ㄧ幇</td><td>杩涚▼姝� 鈫� 閿侀殢杩涚▼娑堝け锛堝唴鏍稿洖鏀讹級</td><td class="bad">鎸佹湁鑰呮浜″悗閿�<strong>娈嬬暀</strong>锛屽繀椤婚潬 TTL/鐪嬮棬鐙楀洖鏀�</td></tr>
+ <tr><td>鍙鎬�</td><td>澶╃劧鍙锛堝悓涓�鍫嗭級</td><td>蹇呴』澶栭儴鍖栫姸鎬侊紙DB / Broker / 鍏变韩鍐呭瓨锛�</td></tr>
+ <tr><td>浣犱滑鐨勭幇鐘�</td><td class="good">宸茶В鍐筹紙ResourceManager 鍐呭瓨鐗堝嵆鏄共杩欎釜鐨勶級</td><td class="bad">瀹屽叏鏈В鍐斥�斺�旀湰娆℃柟妗堢殑涓绘垬鍦�</td></tr>
+</table>
+
+<div class="info"><strong>璁捐鍘熷垯锛氬満鏅� A 鐢ㄨ交閲忓唴瀛橀攣锛堝揩锛夛紝鍦烘櫙 B 鐢ㄦ寔涔呭寲绉熺害锛堝彲闈狅級锛屼袱灞傚鍚堟垚涓�涓� <code>LayeredResourceManager</code>锛屽涓婂眰 <code>IAutoDeviceFacade</code> 瀹屽叏閫忔槑銆�</strong></div>
+
+<!-- ================================================================= -->
+<h2 id="s3">3. 浜斾釜鍊欓�夋柟妗堥�愪竴璇勪及涓庢í鍚戝姣�</h2>
+
+<h3>鏂规 鈶狅細鍏ㄩ儴鏀舵暃鍒板崟杩涚▼ + OpenTAP 鍐呯疆鍚屾</h3>
+<div class="card">
+鎶婃墍鏈夊伐浣嶆墽琛屼綋閮藉杩涗竴涓富杩涚▼锛堜竴涓� TestPlan 璺戝鍒嗘敮锛夛紝瀹屽叏渚濊禆 <code>SynchronizationManager</code>銆�
+<br><br>
+<span class="mid">璇勪及锛�</span>鐗╃悊涓婃渶鐪佷簨锛�<strong>浣嗚繚鍙嶈�佸寲娴嬭瘯鐨勭嫭绔嬫晠闅滃煙鍘熷垯</strong>鈥斺�斾竴涓伐浣� <code>StackOverflow</code>/鍘熺敓椹卞姩宕╂簝鎷栨鍏ㄩ儴 N 涓伐浣嶏紱鑰佸寲宸ラ緞鍔ㄨ緞鍑犲崄灏忔椂锛岃繘绋嬬骇闅旂鏄垰闇�銆傚唴瀛樻硠婕忓湪澶氳繘绋嬩笅鍙互鎸夊伐浣嶈疆鎹㈠洖鏀讹紝鍗曡繘绋嬫棤瑙c��
+<br><strong>缁撹锛氫粎浣滀负鍏滃簳绠�鍖栧舰鎬侊紙鍗曞伐浣嶅皬鍨嬫満鍙板彲鐢級锛屼笉浣滀负澶氬伐浣嶇洰鏍囨灦鏋勩��</strong>
+</div>
+
+<h3>鏂规 鈶★細鍛藉悕鍐呮牳瀵硅薄锛圢amed Mutex / Named Semaphore锛�</h3>
+<div class="card">
+<code>new Mutex(false, "Global\\Lease_CAN-001")</code>锛岃法杩涚▼鎶㈠唴鏍稿璞°��
+<br><br>
+<strong>浼樼偣锛�</strong>瀹炵幇鎴愭湰鈮�0锛涜繘绋嬫浜℃椂鍐呮牳鑷姩閲婃斁 Abandoned锛堝悓鏈哄彲闈狅級銆�
+<br><strong>鑷村懡缂洪櫡锛�</strong>
+<ul>
+<li><strong>鏃犺涔夌姸鎬�</strong>锛歁utex 鍙煡閬�"璋佹嬁鐫�"锛屼笉鐭ラ亾"鎷垮幓骞蹭粈涔堛�佷粈涔堟椂鍊欒杩�"鈥斺��<code>AbandonedMutexException</code> 鏃朵笂涓�涓寔鏈夎��<em>鎿嶄綔鍒板摢涓�姝ヤ簡</em>瀹屽叏涓嶅彲鐭ワ紝瀵�"浜哄湪鎺ョ嚎/杈撳嚭宸叉墦寮�"杩欑被瀹夊叏鐘舵�佹槸鐩插尯锛�</li>
+<li><strong>鏃犱紭鍏堢骇浠茶</strong>锛氱淮鎶ゆā寮忔姠鍗犵敓浜с�佷紭闆呬氦鎺ワ紙handover锛夐兘琛ㄨ揪涓嶄簡锛�</li>
+<li><strong>鏃犲璁�</strong>锛氳皝鍦ㄤ粈涔堟椂闂存寔鏈変簡澶氫箙锛屽唴鏍稿璞′笉璁板綍锛屼笌浣犱滑 <code>debug_operation</code> 瀹¤浣撶郴鑴辫妭锛�</li>
+<li><strong>涓嶈法鏈哄櫒</strong>锛�<code>Global\</code> 鍛藉悕鍦� Windows 鏈嶅姟/浼氳瘽闅旂涓嬭繕鏈夋潈闄愬潙銆�</li>
+</ul>
+<strong>缁撹锛氫笉鑳藉崟鐙垚绔嬶紱鍙互浣滀负鏂规鈶㈢殑"鍚屾満鍔犻�熶俊鍙�"鍋氭贩鍚堬紙瑙� 搂4 鍒嗗眰璁捐锛夈�備笉鎺ㄨ崘鐢� NamedEvent 杞妯℃嫙绉熺害锛堢珵鎬佸銆佽皟璇曞湴鐙憋級銆�</strong>
+</div>
+
+<h3>鏂规 鈶細鏁版嵁搴撶绾﹁〃锛圠ease + TTL + 蹇冭烦 + 宕╂簝鍥炴敹锛夆瓙 鎺ㄨ崘涓讳綋</h3>
+<div class="card">
+鎶婄绾︾姸鎬佹寔涔呭寲鍒� <code>data.db</code> 鏂拌〃 <code>device_lease</code>锛岀敤 <code>BEGIN IMMEDIATE</code> 浜嬪姟瀹炵幇璺ㄨ繘绋嬪師瀛愮殑"姣旇緝骞舵崲鍏�"锛圕AS锛夛紝TTL 杩囨湡鍗宠瑙嗕负宕╂簝鍙洖鏀讹紝Generation 浣滄爡鏍忎护鐗岄槻"鍍靛案鎸佹湁鑰�"銆�
+<br><br>
+<strong>涓庣幇鏈� IResourceManager 鐨勮鎺ワ細</strong>鎺ュ彛绛惧悕<strong>涓�涓兘涓嶆敼</strong>銆傛柊澧� <code>DbLeaseStore</code> 鍐呴儴绫伙紝<code>ResourceManager</code> 鍗囩骇涓虹粍鍚堟ā寮忥細鍐呭瓨瀛楀吀缁х画鍋氭湰杩涚▼蹇�熻矾寰勪笌淇″彿閲忎簰鏂ワ紝棰勭害/鏍¢獙鍚屾椂璇诲啓 DB 琛ㄣ�備笂灞� <code>AutoDeviceFacade / DeviceService / DebugSessionManager / IAutoDeviceLease</code> 闆舵敼鍔紝鍙崲 Bootstrapper 閲岀殑娉ㄥ唽瀹炰緥銆�
+<br><strong>闄愬埗锛�</strong>SQLite 鏄崟鏈烘枃浠跺簱鈥斺�斿鏈哄叡浜渶鎶婅琛ㄨ縼鍒版湇鍔$鏁版嵁搴擄紙鎴栬蛋鏂规鈶� Broker 浠g悊锛夛紝涓� SQLite 鍐欏苟鍙戣闈� WAL + 鐭簨鍔★紝绉熺害鎿嶄綔璁捐鎴愭绉掔骇鐐规煡/鐐瑰啓锛屽疄娴嬫敮鎾戞瘡宸ヤ綅绉掔骇鍛戒护娴佹鏃犲帇鍔涖��
+<strong>缁撹锛氳法杩涚▼浠茶鐨勬渶浣虫�т环姣旓紝浣滀负涓讳綋鏂规銆�</strong>
+</div>
+
+<h3>鏂规 鈶o細鐙珛璁惧浠g悊杩涚▼锛圖evice Broker + IPC锛�</h3>
+<div class="card">
+涓�鍙版満鍣ㄤ笂璺戜竴涓� <code>DeviceBroker.exe</code>锛�<strong>鎵�鏈夌墿鐞嗚繛鎺ワ紙COM/USB/CAN 鍗″彞鏌勩�丼CPI TCP socket锛夊彧鐢卞畠鎸佹湁</strong>锛涘悇宸ヤ綅杩涚▼閫氳繃鍛藉悕绠¢亾鎶婂懡浠よ浆鍙戠粰 Broker 鎺掗槦鎵ц銆備粨搴撶幇鎴愮殑 <span class="path">ConnectionUtil/PipeServer路PipeClient</span> 鍗冲彲鍋氫紶杈撳眰銆�
+<br><br>
+<strong>瑙e喅鐨勬牳蹇冪棝鐐癸紙绉熺害琛ㄨВ鍐充笉浜嗙殑锛夛細</strong>
+<ul>
+<li><strong>鍙ユ焺鐙崰</strong>锛氫覆鍙�/USB 涓嶅厑璁哥浜屼釜杩涚▼ <code>CreateFile</code>銆傝嫢浠呴潬绉熺害锛屾瘡娆$绾︽槗鎵嬮兘瑕� close鈫抩pen 涓�娆★紝USB 閲嶆灇涓惧彲杈剧绾т笖涓㈢紦鍐诧紱Broker 璁╄繛鎺�<strong>姘镐笉鎹㈡墜</strong>锛屽垏鎹㈢殑鍙槸"閫昏緫鎵�鏈夋潈"锛�</li>
+<li><strong>澶氭満鍏变韩</strong>锛欰 鏈烘彃鐫� CAN 鍗★紝B/C 鏈虹殑娴嬭瘯涔熻兘缁� TCP/绠¢亾璁� Broker 浠e彂鈥斺�擝roker 澶╃劧鏄法鏈虹綉鍏筹紱</li>
+<li><strong>鍛戒护绾т覆琛屽寲</strong>锛氬垎鏃跺鐢ㄨ澶囷紙鍏变韩娓╃锛夊湪 Broker 鍐呮槸鍗曢槦鍒楋紝姣旂绾︽姠鍗犻珮鏁堝緱澶氥��</li>
+</ul>
+<strong>浠d环</strong>锛氬涓�涓父椹昏繘绋嬭杩愮淮锛堢湅闂ㄧ嫍銆佸崌绾с�佹棩蹇楋級锛涙墍鏈� I/O 澶氫竴璺� IPC锛垀姣绾э紝鑰佸寲鍦烘櫙鍙拷鐣ワ級锛涘紑鍙戦噺鏈�澶с��
+<strong>缁撹锛氫覆鍙�/USB/CAN 鍗¤繖绫�"鍗曟満鐗╃悊鐙崰"璁惧鐨�<strong>缁堝眬鏂规</strong>锛涗絾寤鸿 Phase 3 鍐嶄笂锛孭hase 1 鐢ㄧ绾﹁〃 + "绉熺害鎸佹湁鏈熷唴淇濇寔杩炴帴"鍗冲彲婊¤冻澶ч儴鍒嗗満鏅��</strong>
+</div>
+
+<h3>鏂规 鈶わ細鐩存帴澶嶇敤 OpenTAP 鐢熸�佽兘鍔�</h3>
+<div class="card">
+閫愰」鏍告煡 OpenTAP 鐜版垚鑳藉姏鑳藉惁瑕嗙洊璺ㄨ繘绋嬮渶姹傦紙璇︾粏鍒嗘瀽瑙佸濡圭瘒 <a href="./OpenTAP_Instrument_Package_Analysis.html">銆奜penTAP Instrument + 鎻掍欢鍖呮満鍒跺垎鏋愩�嬄�9</a>锛夛細
+<table>
+ <tr><th>OpenTAP 鑳藉姏</th><th>鏄粈涔�</th><th>鑳藉惁瑙e喅璺ㄨ繘绋嬩徊瑁�</th></tr>
+ <tr><td><code>Instrument : Resource</code> 璧勬簮妯″瀷</td><td>浠櫒鐢熷懡鍛ㄦ湡鎵樼 + 缂栬緫鍣ㄧ粦瀹�</td><td class="bad">鉂� 瀹炰緥鐢熷懡鍛ㄦ湡浠呰繘绋嬪唴锛涗笉鎰熺煡鍏朵粬杩涚▼</td></tr>
+ <tr><td><code>SynchronizationManager</code></td><td>杩涚▼鍐呮寜浠櫒浜掓枼閿�</td><td class="bad">鉂� 璁捐鐩爣灏辨槸鍗曡繘绋�</td></tr>
+ <tr><td>ResultProxy / 杩滅▼鎵ц锛�<code>tap run --remote</code>銆丼ession.Local锛�</td><td>鎶婁竴涓� TestPlan 鍒囧垎鍒拌繙绔墽琛岃妭鐐癸紝缁撴灉鍥炴祦</td><td class="mid">鈿狅笍 瑙e喅"鎵ц鍒嗗竷"锛屼笉瑙e喅"涓ゅ彴鏈烘姠涓�鍙颁华鍣�"鈥斺�旀瘡涓繙绔� session 鍚勮嚜杩樻槸鍗曡繘绋嬭閲�</td></tr>
+ <tr><td>BenchStore / ResourceSettings锛�9.23+锛�</td><td>鍙版灦璧勬簮閰嶇疆鎸佷箙鍖栵紙XML锛�</td><td class="mid">鈿狅笍 閰嶇疆鍙互鍏变韩锛�<strong>浠茶鐘舵�佷笉琛�</strong>锛堟棤 TTL/蹇冭烦姒傚康锛�</td></tr>
+ <tr><td>绉佹湁鍖呬粨搴撳垎鍙�</td><td>椹卞姩浠� <code>.opentap</code> 鍖呭畨瑁�</td><td class="good">鉁� 瑙e喅椹卞姩鍒嗗彂锛堜笌骞跺彂浠茶姝d氦锛屽�煎緱骞惰鎺ㄨ繘锛�</td></tr>
+ <tr><td><code>IResourcePlan</code>/ResourceConflicts锛�9.20+锛�</td><td>璧勬簮瑙勫垝/鍐茬獊<strong>闈欐�佹鏌�</strong>锛堢紪杈戝櫒閲屾彁绀�"涓や釜搴忓垪鐢ㄤ簡鍚屼竴浠櫒"锛�</td><td class="mid">鈿狅笍 鍙兘鎻愬墠鍙戠幇鍐茬獊锛岃繍琛屾椂澶氳繘绋嬪苟鍙戜粛涓嶄徊瑁�</td></tr>
+</table>
+<strong>缁撹锛歄penTAP 鐢熸�佹病鏈変换浣曚竴鍧楄兘鐩存帴鏇夸唬璺ㄨ繘绋嬭繍琛屾椂浠茶鈥斺�旇繖鏄紑婧愭祴璇曟鏋剁殑鏅亶绌虹櫧锛屼篃姝f槸浣犱滑 IResourceManager 浣撶郴鐨勬垬鐣ヤ环鍊笺�傝兘澶嶇敤鐨勬槸锛氬垎鍙戯紙鍖呮満鍒讹級銆侀厤缃ā鍨嬶紙BenchStore 鎬濊矾锛夈�佷互鍙婃妸鏈�缁堥┍鍔ㄥ仛鎴� Instrument 鎻掍欢鐨勯暱鏈熷舰鎬併��</strong>
+</div>
+
+<h3>妯悜瀵规瘮鎬昏〃</h3>
+<table>
+ <tr><th>缁村害</th><th>鈶犲崟杩涚▼鏀舵暃</th><th>鈶amed Mutex</th><th>鈶B 绉熺害琛� 猸�</th><th>鈶evice Broker</th><th>鈶penTAP 鐜版垚</th></tr>
+ <tr><td>骞跺彂瀹夊叏锛堣法杩涚▼锛�</td><td class="bad">浼懡棰橈紙鏃犲杩涚▼锛�</td><td class="mid">浜掓枼鍙互锛屼絾鏃犵姸鎬佽涔�</td><td class="good">寮轰竴鑷达紙DB 浜嬪姟 CAS锛�</td><td class="good">鍗曠偣涓茶鍖栵紝鏈�寮�</td><td class="bad">涓嶆敮鎸�</td></tr>
+ <tr><td>宕╂簝娈嬬暀澶勭悊</td><td class="good">杩涚▼姝�=閿佹秷澶�</td><td class="mid">Abandoned 鍙劅鐭ヤ絾鐩叉帴</td><td class="good">TTL 鑷姩杩囨湡 + 鍥炴敹</td><td class="mid">Broker 姝�=鍏ㄥ仠锛堥渶鐪嬮棬鐙楋級</td><td>鈥�</td></tr>
+ <tr><td>浼樺厛绾�/鎶㈠崰/浼橀泤浜ゆ帴</td><td class="mid">浠g爜鍙疄鐜�</td><td class="bad">琛ㄨ揪涓嶄簡</td><td class="good">鐘舵�佸垪+grace 瀛楁鍘熺敓鏀寔</td><td class="good">闃熷垪绛栫暐浠绘剰瀹氬埗</td><td class="bad">鏃�</td></tr>
+ <tr><td>瀹¤鍙拷婧�</td><td class="bad">鏃�</td><td class="bad">鏃�</td><td class="good">琛ㄥ嵆鍘嗗彶锛堝彲鎸� debug_operation锛�</td><td class="good">Broker 鍏ㄦ潈鏃ュ織</td><td class="mid">ResultProxy 鏈夌粨鏋滄棤浠茶</td></tr>
+ <tr><td>鎬ц兘寮�閿�</td><td class="good">绾崇绾�</td><td class="good">寰绾�</td><td class="mid">姣绾э紙WAL 鐐瑰啓锛�</td><td class="mid">姣绾э紙IPC 涓�璺筹級</td><td>鈥�</td></tr>
+ <tr><td>瀹炵幇鎴愭湰</td><td class="good">0锛堥噸鏋勬灦鏋勪负璐燂級</td><td class="good">0.5 浜烘棩</td><td class="good">3~4 浜烘棩</td><td class="mid">5~8 浜烘棩</td><td class="good">宸插唴寤�/涓嶉�傜敤</td></tr>
+ <tr><td>鍙墿灞曞埌澶氭満</td><td class="bad">鍚�</td><td class="bad">鍚�</td><td class="mid">闇�鎹㈡湇鍔$ DB</td><td class="good">鏄紙Broker=缃戝叧锛�</td><td class="mid">閮ㄥ垎</td></tr>
+ <tr><td>鐗╃悊鍙ユ焺鐙崰闂</td><td class="good">澶╃劧瑙勯伩</td><td class="bad">涓嶈В鍐筹紙close/open 鎶栧姩锛�</td><td class="mid">绉熺害鏈熷唴淇濊繛鎺ュ彲缂撹В</td><td class="good">鏍规不锛堝敮涓�鎸佹湁鑰咃級</td><td class="bad">涓嶈В鍐�</td></tr>
+ <tr><td>璋冭瘯闅惧害</td><td class="good">浣�</td><td class="mid">鍐呮牳瀵硅薄榛戠洅</td><td class="good">浣庯紙涓�寮犺〃鍏ㄩ�忔槑锛孲ELECT 鍗崇幇鍦猴級</td><td class="mid">闇�鍙岃繘绋嬭仈璋�</td><td>鈥�</td></tr>
+ <tr><td>涓庣幇鏈変唬鐮佽鎺�</td><td class="mid">澶ф敼</td><td class="mid">闇�鏂板鏃佽矾</td><td class="good">IResourceManager 瀹炵幇灞傛浛鎹紝涓婂眰闆舵敼</td><td class="mid">Driver 灞傛媶鍒嗚浆鍙戠/瀹夸富绔�</td><td class="good">姝d氦澶嶇敤</td></tr>
+</table>
+
+<!-- ================================================================= -->
+<h2 id="s4">4. 鎺ㄨ崘鐩爣鏋舵瀯锛氬垎灞傛贩鍚堬紙绉熺害琛� + 浠茶瑙勫垯 + 鎸夐渶 Broker锛�</h2>
+
+<div class="mermaid">
+graph TB
+ subgraph L4["涓婂眰璋冪敤锛堜繚鎸佷笉鍙橈級"]
+ TS["OpenTAP TestStep<br/>锛堝叏鑷姩 路 IAutoDeviceLease 浣滅敤鍩燂級"]
+ DBG["DeviceDebug UI<br/>锛堟墜鍔ㄧ淮鎶� 路 DebugSessionManager锛�"]
+ end
+ subgraph L3["闂ㄩ潰灞� Aging.Infrastructure/Services"]
+ FAC["AutoDeviceFacade<br/>锛堢绾︾敵璇�/蹇冭烦/鏍呮爮鏍¢獙锛�"]
+ SVC["DeviceService<br/>锛堝懡浠ゅ垎娲� + owner 鏍¢獙鍗囩骇涓鸿法杩涚▼锛�"]
+ end
+ subgraph L2["浠茶灞傦紙鏈鏍稿績鏀归�狅級"]
+ LRM["LayeredResourceManager : IResourceManager"]
+ MEM["杩涚▼鍐呭眰锛歋emaphoreSlim + 鍐呭瓨缂撳瓨<br/>锛堝鐢ㄧ幇鏈� ResourceManager 閫昏緫锛�"]
+ DBL["璺ㄨ繘绋嬪眰锛欴bLeaseStore<br/>device_lease 琛� 路 BEGIN IMMEDIATE CAS"]
+ POL["浠茶绛栫暐寮曟搸锛氫紭鍏堢骇/鎶㈠崰/grace"]
+ LRM --> MEM & DBL & POL
+ end
+ subgraph L1["鐗╃悊杩炴帴灞傦紙Phase 3 鎸夐渶锛�"]
+ OWN["鏈繘绋嬬洿杩烇細缃戝彛浠櫒锛圫CPI/TCP/CAN鎬荤嚎妯℃嫙锛�<br/>绉熺害=閫昏緫鐙崰锛屽彞鏌勯殢绉熺害寮�鍏�"]
+ BRK["DeviceBroker.exe锛氫覆鍙�/USB/CAN鍗″敮涓�鎸佹湁鑰�<br/>澶嶇敤 ConnectionUtil.PipeServer/PipeClient"]
+ end
+ TS & DBG --> FAC --> SVC --> LRM
+ DBL --> SQLITE[("data.db<br/>device_lease 琛�<br/>WAL 妯″紡")]
+ SVC --> OWN & BRK
+</div>
+
+<h3>4.1 鍒嗗眰鑱岃矗涓庡喅绛栬鍒�</h3>
+<table>
+ <tr><th>灞�</th><th>瑙e喅浠�涔�</th><th>浣曟椂鍚敤</th></tr>
+ <tr><td>鍐呭瓨灞傦紙宸叉湁锛�</td><td>鍚岃繘绋嬪绾跨▼缁嗛攣銆佸揩閫熷け璐�</td><td class="good">濮嬬粓锛堥浂鎴愭湰锛�</td></tr>
+ <tr><td>DB 绉熺害灞傦紙鏂板锛�</td><td>璺ㄨ繘绋嬭繍琛屾椂浠茶銆佷紭鍏堢骇鎶㈠崰銆佸璁°�佸穿婧冨洖鏀�</td><td class="good">Phase 1 鈥斺�� 涓讳綋鎶曞叆</td></tr>
+ <tr><td>Broker 灞傦紙鏂板锛�</td><td>鐗╃悊鍙ユ焺鐙崰銆佸鏈哄叡浜�佸懡浠ら槦鍒�</td><td class="mid">Phase 3 鈥斺�� 浠呭綋鍑虹幇锛氣憼 涓插彛/USB 閲嶅紑鎴愭湰涓嶅彲鎺ュ彈 鈶� 澶氭満鍏辨祴涓�鍙版満涓婄殑璁惧 鈶� 鍒嗘椂澶嶇敤璁惧瑕佹帓闃�</td></tr>
+ <tr><td>OpenTAP 鐢熸��</td><td>椹卞姩鍒嗗彂锛堝寘锛夈�侀厤缃叡浜紙Bench 鎬濊矾锛�</td><td class="mid">涓� Phase 1/3 姝d氦骞惰鎺ㄨ繘</td></tr>
+</table>
+
+<!-- ================================================================= -->
+<h2 id="s5">5. 绉熺害瀹屾暣鐢熷懡鍛ㄦ湡锛氱敵璇� / 缁湡 / 閲婃斁 / 瓒呮椂鎶㈠崰</h2>
+
+<h3>5.1 绉熺害鐘舵�佹満</h3>
+<div class="mermaid">
+stateDiagram-v2
+ [*] --> Free: device_lease 鏃犺/宸插洖鏀�
+ Free --> Active: Acquire锛堜簨鍔AS鎴愬姛<br/>generation++ 鍐欏叆 owner锛�
+ Active --> Active: Heartbeat 缁湡<br/>锛坋xtends expires_at锛�
+ Active --> PendingHandover: 鏇撮珮浼樺厛绾х敵璇峰埌杈�<br/>锛圡aintenance 璇锋眰锛屽啓 grace 鎴锛�
+ PendingHandover --> Released: 鎸佹湁鑰呬紭闆呰娓�<br/>锛堝畬鎴愬綋鍓� TestStep 鍚� Release锛�
+ PendingHandover --> ForceReleased: grace 瓒呮椂<br/>锛堣姹傝�呭彲鎶㈠崰 generation++锛�
+ Active --> Expired: 蹇冭烦鏂紙杩涚▼宕╂簝/鏂綉锛�<br/>expires_at < DB now
+ Expired --> Free: 鍥炴敹锛堜换浣� Acquire 椤哄甫 DELETE<br/>+ 鍚庡彴 Sweep 鍏滃簳锛�
+ Active --> Released: 姝e父 Dispose/ReleaseReservation
+ Released --> Free
+</div>
+
+<h3>5.2 鐢宠 + 鎶㈠崰 + 鏍呮爮鎷掔粷鏃跺簭</h3>
+<div class="mermaid">
+sequenceDiagram
+ autonumber
+ participant P1 as 宸ヤ綅杩涚▼1<br/>(Production 绉熺害鎸佹湁鑰�)
+ participant DB as device_lease 琛�<br/>(SQLite WAL)
+ participant HMI as 宸ヤ綅杩涚▼2<br/>(Maintenance 璇锋眰鑰�)
+ participant DRV as DeviceService/椹卞姩
+
+ Note over P1,DB: 鈥斺�� 姝e父鎸佺 + 蹇冭烦 鈥斺��
+ P1->>DB: Acquire CAN-001锛圔EGIN IMMEDIATE鈫掓棤鍐茬獊鈫扞NSERT gen=41锛�
+ DB-->>P1: lease(tokenA, gen41, expires=now+30s)
+ loop 姣� 10s锛圱TL/3锛�
+ P1->>DB: Renew WHERE token=tokenA AND gen=41
+ DB-->>P1: 褰卞搷琛屾暟=1 鉁� expires 椤哄欢
+ end
+ P1->>DRV: ExecuteCommandAsync("OUTP ON") [鎼哄甫 gen41]
+ DRV->>DB: FenceCheck(gen41) 鈫� 閫氳繃 鉁�
+ DRV-->>P1: OK
+
+ Note over HMI,DB: 鈥斺�� 缁存姢妯″紡鎶㈠崰 鈥斺��
+ HMI->>DB: RequestMaintenance(CAN-001)
+ DB-->>HMI: 宸插崰鐢� 鈫� 鍐� state=PendingHandover,<br/>grace_until=now+30s, 杩斿洖"绛夊緟璁╂浮"
+ P1->>DB: 锛堜笅涓�娆″績璺冲彂鐜� state=PendingHandover锛�
+ P1->>P1: 瀹屾垚褰撳墠 TestStep 鈫� 涓诲姩 Release
+ P1->>DB: Release(tokenA) 鈫� DELETE 琛�
+ HMI->>DB: 杞/閫氱煡鍚庨噸璇� Acquire 鈫� 鎴愬姛锛坓en=42, Maintenance锛�
+ HMI->>HMI: DebugSessionManager 杩涘叆 MaintenanceActive
+
+ Note over P1,DRV: 鈥斺�� 鍍靛案鎸佹湁鑰呰鏍呮爮鎷︽埅 鈥斺��
+ P1->>P1: 锛堝穿婧冨娲�/缃戠粶鍒嗗尯鍚庝粛浠ヤ负鑷繁鎸佹湁 gen41锛�
+ P1->>DRV: ExecuteCommandAsync锛堟棫 tokenA gen41锛�
+ DRV->>DB: FenceCheck: 琛ㄥ唴 gen=42 鈮� 41
+ DRV-->>P1: 鉂� LEASE_STALE 鈫� 鏈湴鐔旀柇锛屼細璇濊浆 RecoveryRequired
+</div>
+
+<h3>5.3 鏍稿績 SQL锛堝師瀛愮敵璇凤紝涓�娆′簨鍔″畬鎴愬洖鏀�+妫�鏌�+鍐欏叆锛�</h3>
+<pre><code>BEGIN IMMEDIATE; <span class="cmt">-- 鎷垮啓閿侊細璺ㄨ繘绋嬩覆琛屽寲鍏ュ彛锛圫QLite WAL 涓嬭鍐欎笉浜掓枼锛屽啓鍐欐帓闃燂級</span>
+
+<span class="cmt">-- 鈶� 椤哄甫鍥炴敹鎵�鏈夊凡杩囨湡绉熺害锛堟噿鍥炴敹锛屾棤闇�鐙珛瀹堟姢涔熻兘鑷剤锛�</span>
+DELETE FROM device_lease
+ WHERE resource_key = @rk AND expires_at < datetime('now');
+
+<span class="cmt">-- 鈶� 妫�鏌ュ綋鍓嶆湁鏁堝崰鐢�</span>
+SELECT owner_id, owner_type, state, grace_until INTO @cur FROM device_lease WHERE resource_key = @rk;
+
+<span class="cmt">-- 鈶� 鏃犲崰鐢� 鈫� 鎻掑叆鏂扮绾︼紙generation 鍙栧叏灞�搴忥級</span>
+INSERT INTO device_lease(resource_key, owner_id, owner_type, token_id, generation,
+ machine_name, host_process_id, state, acquired_at, heartbeat_at, expires_at)
+VALUES(@rk, @owner, @otype, @token, @gen, @machine, @pid, 0,
+ datetime('now'), datetime('now'), datetime('now', '+30 seconds'));
+
+<span class="cmt">-- 鈶� 鏈夊崰鐢ㄤ笖璇锋眰鑰呮槸 Maintenance 鈫� 涓嶇洿鎺ユ姠锛屾爣璁拌娓$獥鍙�</span>
+UPDATE device_lease SET state = 1, grace_until = datetime('now','+30 seconds')
+ WHERE resource_key = @rk AND state = 0;
+
+COMMIT;</code></pre>
+
+<h3>5.4 缁湡锛堝績璺筹級涓庡け鏁堝垽瀹�</h3>
+<pre><code><span class="cmt">// AutoDeviceLease 鍐呴儴锛歍TL/3 鍛ㄦ湡瀹氭椂鍣紙Phase 1 鍗冲疄鐜帮級</span>
+<span class="kwd">var</span> affected = db.<span class="fn">ExecuteNonQuery</span>(<span class="str">@"
+ UPDATE device_lease
+ SET heartbeat_at = datetime('now'),
+ expires_at = datetime('now', '+30 seconds'),
+ state = CASE WHEN state = 1 THEN state ELSE 0 END <span class="cmt">-- 淇濈暀璁╂浮鏍囪</span>
+ WHERE resource_key = @rk AND token_id = @token AND generation = @gen"</span>);
+
+<span class="kwd">if</span> (affected == 0) {
+ <span class="cmt">// 琛屼笉鍦ㄤ簡鎴� generation 宸茶瓒呰秺 鈬� 鎴戝凡琚姠鍗�/鍥炴敹 鈥斺�� 鏈湴绔嬪嵆鐔旀柇锛�</span>
+ <span class="cmt">// 1) 鍋滄涓嬪彂浠讳綍鍛戒护 2) 閲婃斁鐗╃悊杩炴帴 3) 浼氳瘽鏍囪 RecoveryRequired 4) 涓婃姤涓�娆″憡璀�</span>
+ <span class="fn">OnLeaseLost</span>();
+}
+<span class="kwd">if</span> (db.<span class="fn">ReadState</span>() == PendingHandover && InStepBoundary) {
+ <span class="fn">Dispose</span>(); <span class="cmt">// 浼橀泤璁╂浮锛氬彧鍦� TestStep 杈圭晫閲婃斁锛岀粷涓嶅湪涓�鏉″懡浠や腑闂存斁鎵�</span>
+}</code></pre>
+
+<div class="highlight"><strong>涓夋潯閾佸緥锛�</strong>鈶� 鎵�鏈夋椂闂存埑涓�寰嬬敤 <code>datetime('now')</code>锛圖B 鏃堕挓锛夛紝瀹㈡埛绔椂闂翠粎浣滃弬鑰冨垪锛涒憽 姣忔潯鍛戒护涓嬪彂鍓嶅繀椤� <code>FenceCheck</code>锛堜竴琛岀偣鏌ワ紝鎴愭湰鈮�1ms锛夛紱鈶� 璁╂浮/閲婃斁鍙彂鐢熷湪 TestStep 杈圭晫锛屼繚璇佽澶囦笉澶勪簬"鍗婃潯鎸囦护"鐘舵�併��</div>
+
+<!-- ================================================================= -->
+<h2 id="s6">6. 鍏ㄨ嚜鍔� vs 鎵嬪姩缁存姢鐨勪簰鏂ヤ徊瑁佽鍒�</h2>
+
+<p>鐩爣鍦烘櫙锛氬伐绋嬪笀姝f墦寮�鏈烘煖鎺� CAN 绾匡紙缁存姢妯″紡锛夛紝鍏ㄨ嚜鍔ㄧ▼搴忕粷涓嶈兘绐佺劧涓嬪彂 <code>OUTP ON</code>銆傝鍒欐槑纭畾涔夊涓嬶紙绛栫暐寮曟搸闆嗕腑瀹炵幇浜庢柊澧� <span class="path">Aging.Infrastructure/Core/LeaseArbiter.cs</span>锛夛細</p>
+
+<h3>6.1 浼樺厛绾х煩闃碉紙琛�=褰撳墠鎸佹湁鑰咃紝鍒�=鏂拌姹傝�咃級</h3>
+<table>
+ <tr><th></th><th>璇锋眰锛歅roduction锛堝叏鑷姩锛�</th><th>璇锋眰锛歁aintenance锛堟墜鍔ㄧ淮鎶わ級</th><th>璇锋眰锛歊eadOnly锛堢洃鎺�/鐪嬫暟鎹級</th></tr>
+ <tr>
+ <td><strong>鎸佹湁锛歅roduction</strong></td>
+ <td class="mid">鎺掗槦锛團IFO 鎴栨寜宸ヤ綅浼樺厛绾э紝甯﹁秴鏃讹級</td>
+ <td class="mid"><strong>璁╂浮娴佺▼</strong>锛歅endingHandover + grace 30s锛涜秴鏃舵湭璁╂浮 鈫� 鍏佽寮哄崰 + 鏃ф寔鏈夎�呮爡鏍忓け鏁�</td>
+ <td class="good">鏀捐锛堜笉寤虹绾︼紝璧版梺璺彧璇伙級</td>
+ </tr>
+ <tr>
+ <td><strong>鎸佹湁锛歁aintenance</strong></td>
+ <td class="bad"><strong>鐩存帴鎷掔粷</strong>锛圧esourceConflictException锛�"鏈変汉鍦ㄧ淮鎶�"锛沀I 寮圭獥鍛婄煡宸ョ▼甯堬級</td>
+ <td class="bad">鎷掔粷锛堢浜屼釜浜轰篃涓嶈纰扳�斺�斾竴鍙拌澶囧悓鏃跺彧鍏佽涓�涓淮鎶や細璇濓紝澶嶇敤鐜版湁 OpenSession 閲嶅妫�鏌ラ�昏緫锛�</td>
+ <td class="good">鏀捐</td>
+ </tr>
+ <tr>
+ <td><strong>鎸佹湁锛歊eadOnly</strong></td>
+ <td class="good">绔嬪嵆鏀捐锛堣閿佷笉鏋勬垚闅滅锛�</td>
+ <td class="good">绔嬪嵆鏀捐</td>
+ <td class="good">鏀捐</td>
+ </tr>
+</table>
+
+<div class="info"><strong>涓庣幇鏈変唬鐮佺殑鎸傛帴鐐癸細</strong><span class="path">DebugSessionManager.RequestMaintenance()</span> 宸茬粡鍋氫簡 <code>ReserveAsync</code> + 鎹曡幏 <code>ResourceConflictException</code> 鈫� 鍙渶鎶婂唴瀛樼増鎹㈡垚 Layered 鐗堝嵆鑷姩鑾峰緱璺ㄨ繘绋嬫嫆缁濓紱<span class="path">ValidateCommand()</span> 宸叉湁"MaintenanceActive + ValidateOwner"鍙岄噸妫�鏌ワ紝鎶� <code>ValidateOwner</code> 鏀逛负鏌� DB 鏍呮爮锛屽氨寰楀埌<strong>"浜哄湪鎺ョ嚎鏃剁▼搴忚繛鍛戒护閮藉彂涓嶅嚭"</strong>鐨勭‖淇濊瘉鈥斺�斿嵆浣胯嚜鍔ㄧ▼搴忛�昏緫鏈� bug銆�</div>
+
+<h3>6.2 缁存姢妯″紡閫�鍑轰笌鑷姩娴佺▼鎭㈠</h3>
+<ul>
+<li>宸ョ▼甯堥��鍑虹淮鎶わ紙<span class="path">ExitMaintenanceBtn_Click 鈫� CloseSession</span>锛夛細閲婃斁琛� + <code>UPDATE debug_session SET state=Closed</code>锛堢幇鏈夐�昏緫淇濇寔锛夛紱</li>
+<li>鑷姩宸ヤ綅瀵� PendingHandover 鐨勬劅鐭ュ欢杩� 鈮� 蹇冭烦鍛ㄦ湡锛�10s锛夛紝鑰佸寲闀挎楠わ紙灏忔椂绾э級涓嶉�傜敤鎶㈠崰鈥斺�斿 <code>grace</code> 鍐呮湭瀹屾垚鐨勬楠わ紝绛栫暐鏀逛负<strong>"鎷掔粷杩涘叆锛屽凡杩愯涓嶆墦鏂�"</strong>锛堝彲閰嶇疆锛氬畨鍏ㄧ被宸ヤ綅閫夋嫨寮哄崰+璁惧绱ф�ュ畨鍏ㄦ�侊紱浜ц兘绫诲伐浣嶉�夋嫨鎺掗槦绛夊緟锛夛紱</li>
+<li>HMI 渚у缓璁細璁惧琚嚜鍔ㄥ崰鐢ㄦ椂锛岀淮鎶ょ敵璇锋樉绀�"鍗犵敤鑰�:Station-3 路 宸茶繍琛� 01:23:45 路 棰勮鍓╀綑 02:10"锛堟暟鎹叏鍦� <code>device_lease</code> + <code>debug_session</code>锛屼竴鏉� JOIN 鍗冲彲锛夈��</li>
+</ul>
+
+<h3>6.3 瀹¤闂幆</h3>
+<ul>
+<li><code>device_lease</code> 琛ㄦ湰韬氨鏄�"鍗犵敤鍘嗗彶"锛圧elease 鏃舵敼鍐� <code>released_at</code> 鍐嶄繚鐣� 7 澶╋紝鎴栧弻琛細褰撳墠 + 褰掓。锛夛紱</li>
+<li>姣忔潯缁� <code>DeviceService</code> 鐨勫懡浠ょ户缁啓 <code>debug_operation</code>锛屾柊澧炰袱鍒� <code>owner_type, lease_generation</code>锛屽嵆鍙洖绛�"杩欐潯 OUTP ON 鏄摢涓伐浣嶃�佸摢涓�浠f寔鏈夎�呭彂鐨�"鈥斺�斾簨鏁呰拷婧棴鐜��</li>
+</ul>
+
+<!-- ================================================================= -->
+<h2 id="s7">7. 寮傚父鍦烘櫙澶勭悊锛氭閿� / 瀛ゅ効閿� / 鏃堕挓 / 骞傜瓑</h2>
+
+<table>
+ <tr><th>寮傚父鍦烘櫙</th><th>鎴愬洜</th><th>瀵圭瓥</th><th>鏈哄埗钀界偣</th></tr>
+ <tr>
+ <td><strong>澶氳澶囨閿�</strong>锛堝伐浣岮閿亄鐢垫簮}绛墈CAN}锛孊鍙嶅簭锛�</td>
+ <td>缁勭敵璇峰姞閿侀『搴忎笉涓�鑷�</td>
+ <td class="good">鈶� 鍏ㄥ眬寮哄埗鎸� <code>resource_key</code> 瀛楀吀搴忕敵璇凤紙AcquireGroupAsync 鍐呴儴鎺掑簭锛�<br>鈶� 浜嬪姟鍐�"鍏ㄦ湁鎴栧叏鏃�"锛氫换涓�鍐茬獊鍒欐暣浣撳洖婊氶噸璇曪紙<strong>wait-die</strong>锛氭柊璇锋眰鑰呴��閬块噸璇曪紝鑰佹寔鏈夎�呬笉琚タ姝伙級<br>鈶� 缁勭敵璇锋�昏秴鏃讹紙榛樿 60s锛�</td>
+ <td>AutoDeviceFacade 鏂板 <code>AcquireGroupAsync</code></td>
+ </tr>
+ <tr>
+ <td><strong>杩涚▼宕╂簝 鈫� 瀛ゅ効閿�</strong></td>
+ <td>kill / BSOD / 鏂數锛孯elease 娌¤窇</td>
+ <td class="good">鈶� TTL 30s 鑷姩杩囨湡锛堜换浣� Acquire 椤哄甫 DELETE 杩囨湡琛� = 鎳掑洖鏀讹級<br>鈶� 鍚屾満鐪嬮棬鐙楋細lease 璁板綍 <code>machine_name + host_process_id</code>锛屾湰鏈烘柊杩涚▼鍚姩鏃舵灇涓惧瓨娲� PID 鎻愬墠鍥炴敹锛堜笉鐢ㄧ瓑 TTL锛�<br>鈶� HMI"寮哄埗閲婃斁"鎸夐挳锛堥渶 ADMIN 瑙掕壊锛屽啓瀹¤ note="force_release"锛�</td>
+ <td>device_lease 鍒� + Bootstrapper 鍚姩鑷</td>
+ </tr>
+ <tr>
+ <td><strong>鍍靛案鎸佹湁鑰�</strong>锛堢綉缁滃垎鍖�/GC鍋滈】鍚庡娲荤户缁彂鍛戒护锛�</td>
+ <td>杩涚▼娲荤潃浣嗚鎶㈠崰杩�</td>
+ <td class="good">鏍呮爮浠ょ墝锛氬懡浠ゅ繀椤绘惡甯� <code>(token_id, generation)</code>锛孌B 涓� generation 宸插彉 鈫� 椹卞姩鍏ュ彛鐩存帴鎷掔粷锛埪�5.2 鏃跺簭 15-17 姝ワ級銆�<strong>杩欐槸姣� TTL 鏇存牴鏈殑瀹夊叏缃�</strong>鈥斺�擳TL 绠�"璋佽兘鎷�"锛屾爡鏍忕"鎷胯繃鐨勪汉杩囨湡鍚庝笉鑳界"銆�</td>
+ <td>DeviceService.ExecuteCommandAsync 鍏ュ彛 FenceCheck</td>
+ </tr>
+ <tr>
+ <td><strong>鏃堕挓涓嶄竴鑷�</strong>锛堝鏈� NTP 婕傜Щ锛�</td>
+ <td>expires 鐢ㄦ湰鍦版椂闂存瘮杈冧細璇垽</td>
+ <td class="good">鈶� 鍏ㄩ儴鏃堕棿鍒ゅ畾鐢� DB 渚ф椂閽燂紙<code>datetime('now')</code>锛夛紝瀹㈡埛绔彧浼犵浉瀵� TTL锛�"+30 seconds"锛夛紝浠庝笉浼犵粷瀵规椂闂�<br>鈶� Phase 3 Broker 鍖栧悗缁熶竴鐢� Broker 鏃堕挓<br>鈶� 澶氭満 + 鍏变韩 DB 鍦烘櫙瑕佹眰 NTP锛堣繍缁撮」锛岃宸�<1s 鍗冲彲锛�</td>
+ <td>SQL 鍐欐硶绾︽潫锛埪�5.3 鍏ㄩ儴鍚堣锛�</td>
+ </tr>
+ <tr>
+ <td><strong>蹇冭烦绾跨▼琚� UI 鍗¢】楗挎</strong></td>
+ <td>WPF 涓荤嚎绋嬮樆濉� / 杩涚▼鍋囨</td>
+ <td class="good">蹇冭烦鐢�<strong>鐙珛鍚庡彴绾跨▼</strong>锛堥潪 UI Dispatcher锛夛紝涓斿績璺冲け璐ヨ繛缁� 2 娆″嵆鏈湴鐔旀柇鈥斺�斿畞鍙鍋滀笉鍙紡鍋�</td>
+ <td>AutoDeviceLease 鍐� Timer 瀹炵幇</td>
+ </tr>
+ <tr>
+ <td><strong>閲嶈瘯涓嶅箓绛�</strong>锛堣秴鏃跺悗閲嶅彂"OUTP ON"鏄畨鍏ㄧ殑锛岄噸鍙�"璁℃暟鍣�+1"涓嶅畨鍏級</td>
+ <td>缃戠粶/DB 鎶栧姩鑷姩閲嶈瘯</td>
+ <td class="good">鈶� 鍛戒护鍒嗙骇锛氳澶囧眰鍙畨鍏ㄩ噸鍙戯紙璁剧疆鍨� SET xx=yy 鉁� 骞傜瓑锛涚疮鍔�/瑙﹀彂鍨� 鈿狅笍 绂佹鑷姩閲嶈瘯锛屼笂鎶涳級<br>鈶� <code>debug_operation.operation_id</code> 宸叉槸瀹㈡埛绔敓鎴� GUID 鈫� 浣滀负骞傜瓑閿� INSERT OR IGNORE锛岄噸澶嶅埌杈句笉浜屾鎵ц<br>鈶� 鑰佸寲鍦烘櫙鐨� SCPI/CAN 鍐欏懡浠ゅ涓鸿缃瀷锛屽ぉ鐒跺箓绛夊弸濂斤紝浣嗗繀椤诲湪椹卞姩鎺ュ彛涓婄敤 <code>CommandSemantics.Idempotent</code> 鏄惧紡澹版槑</td>
+ <td>DeviceCommandResult + 椹卞姩瑁呴グ鍣�</td>
+ </tr>
+ <tr>
+ <td><strong>SQLite 鍐欑珵浜�</strong>锛圢 涓伐浣� 脳 蹇冭烦+鐢宠闆嗕腑鍐欎竴琛屽尯鍩燂級</td>
+ <td>鍐欓攣涓茶鍖�</td>
+ <td class="good">WAL 妯″紡 + busy_timeout=5000 + 浜嬪姟鍙寘浣� 2~3 鏉$偣鍐欙紙<5ms锛夛紱鑰佸寲鍛戒护鑺傚锛堢绾э級涓嬪苟鍙戝啓鍘嬪姏鍙拷鐣ャ�傜湡鍒伴珮棰戯紙>100 鍐�/绉掞級鍐嶈縼鏈嶅姟绔� DB</td>
+ <td>杩炴帴涓� PRAGMA锛堣 搂9 DbLeaseStore锛�</td>
+ </tr>
+ <tr>
+ <td><strong>鎶㈠崰椋庢毚</strong>锛堜袱涓珮浼樿姹傚悓鏃跺埌杈撅級</td>
+ <td>骞跺彂 PendingHandover 鏍囪</td>
+ <td class="good">浠茶鍦� <code>BEGIN IMMEDIATE</code> 浜嬪姟鍐呬覆琛屽垽瀹氾紱绗簩涓淮鎶よ姹備細鐪嬪埌"宸叉湁缁存姢鎺掗槦"鑰岃鍛婄煡鎺掗槦浣嶇疆锛屼笉浜х敓鍙� grace 绔炰簤</td>
+ <td>浜嬪姟澶╃劧瑕嗙洊</td>
+ </tr>
+</table>
+
+<!-- ================================================================= -->
+<h2 id="s8">8. 鐙崰 or 鍒嗘椂澶嶇敤锛氳澶囧垎缁勪笌 Slot 缁戝畾绛栫暐</h2>
+
+<h3>8.1 璁惧璁块棶妯″紡锛堟柊澧炲垪锛屾敞鍐岄〉鍙厤锛�</h3>
+<table>
+ <tr><th>妯″紡</th><th>璇箟</th><th>绉熺害褰㈡��</th><th>鍏稿瀷璁惧锛堟湰椤圭洰锛�</th></tr>
+ <tr>
+ <td><code>Exclusive</code> 鐙崰</td>
+ <td>涓�涓伐浣嶅叏绋嬫寔鏈夛紝娴嬭瘯鏈熼棿鍒汉纰颁笉鍒�</td>
+ <td>鏁存楠ょ骇闀跨绾︼紙TTL 闈犲績璺崇淮鎸佹暟灏忔椂锛�</td>
+ <td>宸ヤ綅涓撶敤鐢垫簮銆丏UT 涓撶敤 CAN 鍗¢�氶亾</td>
+ </tr>
+ <tr>
+ <td><code>TimeShared</code> 鍒嗘椂涓茶</td>
+ <td>澶氭潯鍛戒护鎺掗槦杩囪澶囷紝姣忔潯鍘熷瓙</td>
+ <td>鍛戒护绾х煭绉熺害锛堢绾э級鎴� Broker 闃熷垪</td>
+ <td>鍏变韩 DAQ 璇绘暟銆佸叕鐢ㄤ竾鐢ㄨ〃</td>
+ </tr>
+ <tr>
+ <td><code>SharedRead</code> 鍏变韩璇�+鐙崰鍐�</td>
+ <td>鐩戞帶闅忎究璇伙紙鏃佽矾锛夛紝鍐欏繀椤绘姠绉熺害</td>
+ <td>璇讳笉璧颁徊瑁侊紱鍐�=Exclusive 绉熺害</td>
+ <td>娓╃锛堢姸鎬佷汉浜哄彲鐪嬶紝璁炬俯蹇呴』鐙崰锛夈�丆AN 鎬荤嚎鐩戝惉</td>
+ </tr>
+</table>
+
+<h3>8.2 鍐崇瓥瑙勫垯锛堟柊澧� <code>DeviceDefinition.access_mode</code> 鍒楋紝娉ㄥ唽椤典笅鎷夐�夋嫨锛�</h3>
+<div class="card">
+<b>涓�闂細</b>"涓や釜宸ヤ綅<strong>鍚屾椂</strong>鐢ㄨ繖鍙拌澶囷紝鐗╃悊涓�/鍗忚涓婁細涓嶄細浜掔浉骞叉壈锛�"<br>
+<b>浼�</b>锛堜覆鍙f寚浠や氦鍙夈�佺數婧愯鏀瑰帇锛夆啋 <code>Exclusive</code>锛�<br>
+<b>涓嶄細浣嗚涔変細涔�</b>锛堜竾鐢ㄨ〃 A 璇绘暟鏄� B 瑙﹀彂涓嬩骇鐢熺殑锛夆啋 <code>TimeShared</code>锛堜覆琛岄槦鍒楋級锛�<br>
+<b>璇绘棤瀹炽�佸啓鏈夊</b>锛堟俯绠辩姸鎬佸箍鎾級鈫� <code>SharedRead</code>銆�<br>
+<b>鍒ゆ嵁鏉ユ簮锛�</b>璁惧浼犺緭灞傜被鍨� + 鍗忚鏄惁鏀寔浼氳瘽闅旂銆侰AN 鍗¢粯璁� Exclusive锛堥�氶亾绾у彲缁嗗垎锛夛紝TCP SCPI 鐪嬩华鍣ㄨ繛鎺ユ暟闄愬埗锛堝鏁� DMM 鍙厑璁� 1 涓� socket 鈫� 瀹炶川 Exclusive锛夈��
+</div>
+
+<h3>8.3 宸ヤ綅 鈫� 璁惧鍒嗙粍锛氱粦瀹氬埌 Slot 浣撶郴</h3>
+<div class="mermaid">
+graph LR
+ subgraph 鍙版灦["鐗╃悊鍙版灦"]
+ S1["Slot-A锛堝伐浣�1锛�"] --- S2["Slot-B锛堝伐浣�2锛�"]
+ P1["PS-001 涓撶敤鐢垫簮"] --- S1
+ C1["CAN-001 鍗� CH0"] --- S1
+ C2["CAN-002 鍗� CH1"] --- S2
+ T1["CHAMBER-01 鍏变韩娓╃"] --- S1 & S2
+ end
+ subgraph 鏁版嵁["data.db 鏄犲皠锛堝凡鏈夎〃 + 鏂板垪锛�"]
+ M1["SlotDeviceMapping<br/>SlotId 鈫� DeviceId+ChannelId"]
+ G1["鏂板 device_group:<br/>group_key 鈫� {resource_keys}<br/>access_mode 鎸夎澶囧彇"]
+ end
+</div>
+
+<ul>
+<li><strong>澶嶇敤鐜版湁 <span class="path">SlotDeviceMapping</span> 琛�</strong>锛氬伐浣嶈韩浠� = <code>SlotId</code>銆傚伐浣嶈繘绋嬪惎鍔ㄥ弬鏁板甫 SlotId 鈫� 缁勭绾﹁嚜鍔ㄥ睍寮�涓鸿 Slot 缁戝畾鐨勫叏閮ㄨ澶� resource_key 鍒楄〃锛堟寜瀛楀吀搴忕敵璇凤級锛�</li>
+<li><strong>缁勭敵璇峰師瀛愬寲</strong>锛氭柊澧� <code>AcquireGroupAsync(groupKey, ...)</code>锛氭煡 <code>device_group</code>锛堟垨鍗虫椂 JOIN SlotDeviceMapping锛夆啋 鎺掑簭 鈫� 鍗曚簨鍔¢�愬彴 INSERT锛屼换涓�鍐茬獊鏁翠綋鍥炴粴 鈫� 閬垮厤"鍗犱簡涓�鍗�"鐨勫崐姝荤姸鎬侊紱</li>
+<li><strong>鍏变韩璁惧涓嶈繘缁�</strong>锛�<code>CHAMBER-01</code> 杩欑被璺� Slot 璁惧鍦� <code>DeviceDefinition.access_mode</code> 鏍� TimeShared/SharedRead锛岀粍鐢宠鏃惰烦杩囷紝鍛戒护鎵ц鏃舵墠鎶㈢煭绉熺害锛�</li>
+<li><strong>CAN 澶氬伐浣嶅叡鍗�</strong>锛歳esource key 缁嗗寲鍒� <code>CAN_CARD01:CH2</code>鈥斺��<code>ResourceKey</code> 鏈潵灏辨敮鎸� Channel锛堣 <span class="path">Contracts/ResourceKey.cs</span>锛夛紝CAN 甯� ID 绾у啀缁嗗垎鍙敤 <code>resource_type='CAN_FRAME'</code> + channel=甯ф锛圔roker 闃舵瀹炵幇鍛戒护绾т覆琛屽寲鏃跺鐢級銆�</li>
+</ul>
+
+<!-- ================================================================= -->
+<h2 id="s9">9. 鏈粨搴撴敼閫犳竻鍗曪紙鍏蜂綋鍒版枃浠讹級</h2>
+
+<h3>9.1 鏁版嵁搴� DDL锛堟柊澧炲埌 <span class="path">Plugin.DeviceConfig/Model/DeviceConfigModel.cs</span> InitDatabase 鐨� sqls 鍒楄〃锛�</h3>
+<pre><code><span class="cmt">-- 鈶� 璺ㄨ繘绋嬬绾﹁〃锛堟牳蹇冩柊琛級</span>
+CREATE TABLE IF NOT EXISTS device_lease (
+ resource_key TEXT PRIMARY KEY, <span class="cmt">-- 'CAN-001:Generic' 涓� ResourceKey.ToString() 涓�鑷�</span>
+ owner_id TEXT NOT NULL, <span class="cmt">-- 'Station3.Run20261103' 宸ヤ綅鍙鏍囪瘑</span>
+ owner_type INTEGER NOT NULL, <span class="cmt">-- 0=Production 1=Maintenance 2=ReadOnly</span>
+ token_id TEXT NOT NULL, <span class="cmt">-- ResourceOwnerToken.TokenId</span>
+ generation INTEGER NOT NULL, <span class="cmt">-- 鏍呮爮浠ょ墝锛氭瘡娆℃垚鍔熺敵璇� +1锛堝叏灞�鍙� max+1锛�</span>
+ machine_name TEXT NOT NULL DEFAULT '',
+ host_process_id INTEGER NOT NULL DEFAULT 0,
+ slot_id TEXT, <span class="cmt">-- 鍏宠仈宸ヤ綅 Slot锛堢粍瀹¤鐢級</span>
+ state INTEGER NOT NULL DEFAULT 0, <span class="cmt">-- 0=Active 1=PendingHandover</span>
+ acquired_at TEXT NOT NULL,
+ heartbeat_at TEXT NOT NULL,
+ expires_at TEXT NOT NULL, <span class="cmt">-- 鍏ㄩ儴鐢� DB datetime('now') 鐢熸垚</span>
+ grace_until TEXT,
+ note TEXT DEFAULT ''
+);
+CREATE INDEX IF NOT EXISTS idx_lease_expire ON device_lease(expires_at);
+
+<span class="cmt">-- 鈶� 璁惧璁块棶妯″紡锛堢幇鏈夎〃鍔犲垪锛岃�佸簱骞傜瓑杩佺Щ锛�</span>
+ALTER TABLE DeviceDefinition ADD COLUMN access_mode INTEGER NOT NULL DEFAULT 0;
+<span class="cmt">-- 0=Exclusive 1=TimeShared 2=SharedRead</span>
+
+<span class="cmt">-- 鈶� 宸ヤ綅璁惧缁勶紙缁勭绾︾殑灞曞紑渚濇嵁锛涗篃鍙笉寤鸿〃锛岃繍琛屾椂 JOIN SlotDeviceMapping锛�</span>
+CREATE TABLE IF NOT EXISTS device_group (
+ group_key TEXT PRIMARY KEY, <span class="cmt">-- = SlotId 鎴栬嚜瀹氫箟</span>
+ resource_key TEXT NOT NULL,
+ order_hint INTEGER DEFAULT 0,
+ PRIMARY KEY (group_key, resource_key)
+);
+
+<span class="cmt">-- 鈶� debug_session 鍔� 3 鍒楋紙浼氳瘽鈫旂绾﹁仈鍔ㄥ彲瑙嗗寲锛�</span>
+ALTER TABLE debug_session ADD COLUMN lease_generation INTEGER;
+ALTER TABLE debug_session ADD COLUMN lease_owner_type INTEGER;
+ALTER TABLE debug_session ADD COLUMN heartbeat_at TEXT;
+
+<span class="cmt">-- 鈶� debug_operation 鍔� 2 鍒楋紙鍛戒护绾ц拷婧級</span>
+ALTER TABLE debug_operation ADD COLUMN lease_generation INTEGER;
+ALTER TABLE debug_operation ADD COLUMN idempotency_key TEXT; <span class="cmt">-- 骞傜瓑閲嶈瘯鍘婚噸</span>
+CREATE UNIQUE INDEX IF NOT EXISTS idx_op_dedup ON debug_operation(idempotency_key) WHERE idempotency_key != '';</code></pre>
+
+<h3>9.2 鎺ュ彛涓庡疄鐜版敼鍔�</h3>
+<table>
+ <tr><th>鏂囦欢</th><th>鏀瑰姩绫诲瀷</th><th>鍐呭</th></tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Contracts/IResourceManager.cs</span></td>
+ <td>鎵╁睍锛堝悜鍚庡吋瀹癸級</td>
+ <td>鏂板 3 涓柟娉曪紝榛樿瀹炵幇濮旀墭鐜版湁璇箟锛�<br>
+ <code>Task<bool> RenewAsync(ResourceOwnerToken, ResourceKey, int ttlSeconds, CancellationToken)</code><br>
+ <code>(bool valid, string? holderInfo, int? graceSeconds) ProbeConflict(ResourceKey)</code> <span class="cmt">// UI 鏄剧ず"琚皝鍗犵敤"</span><br>
+ <code>Task<GroupLeaseHandle> AcquireGroupAsync(string groupKey, ResourceOwnerToken owner, CancellationToken ct)</code></td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Core/DbLeaseStore.cs</span> 鈽呮柊寤�</td>
+ <td>鏂板</td>
+ <td>搂5.3/搂5.4 鐨� SQL 灏佽锛沇AL/busy_timeout PRAGMA锛涙噿鍥炴敹锛涘悓鏈� PID 鐪嬮棬鐙椼�傜害 250 琛�</td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Core/ResourceManager.cs</span></td>
+ <td>鏀归�犱负缁勫悎</td>
+ <td>淇濈暀鍐呭瓨瀛楀吀 + SemaphoreSlim锛堝揩閫熻矾寰勶級锛涢绾�/鏍¢獙杞彂 <code>DbLeaseStore</code>锛涚绾挎ā寮忥紙DB 涓嶅彲杈撅級闄嶇骇涓虹函鍐呭瓨 + 姣� 5s 閲嶈繛骞跺湪閲嶈繛鍚庢爡鏍忚嚜妫�</td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Core/LeaseArbiter.cs</span> 鈽呮柊寤�</td>
+ <td>鏂板</td>
+ <td>搂6.1 浼樺厛绾х煩闃电殑绛栫暐寮曟搸锛氳娓�/鎷掔粷/鎺掗槦鍒ゅ畾锛岀瓥鐣ュ弬鏁帮紙grace銆佹姠鍗犲紑鍏筹級杩涢厤缃�</td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Services/AutoDeviceFacade.cs</span></td>
+ <td>澧炲己</td>
+ <td>鈶� <code>ReserveCoreAsync</code> 鐨� owner 鏍囪瘑浠庨殢鏈� Guid 鏀逛负鍙厤缃� <code>StationGlobals.StationId</code>锛堝鏈�/澶氬伐浣嶅彲璇绘�э級锛涒憽 <code>AutoDeviceLease</code> 鏋勯�犲嚱鏁板惎鍔ㄥ悗鍙板績璺� Timer锛圱TL/3锛夛紝Dispose 鍋滄锛涒憿 鎹曡幏 PendingHandover 鈫� <code>TryYieldAtBoundary()</code></td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Services/DeviceService.cs</span></td>
+ <td>澧炲己</td>
+ <td><code>ValidateOwner</code> 鍗囩骇涓� DB 鏍呮爮鏍¢獙锛堟煡 generation 鍖归厤锛夛紱涓嶅尮閰嶈繑鍥� <code>ErrorCode="LEASE_STALE"</code> 缁撴瀯鍖栧け璐ワ紝涓嶆姏瑁稿紓甯�</td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/Drivers/DriverFactory.cs</span> + 鍚勯┍鍔�</td>
+ <td>Phase 3</td>
+ <td>鏂板 <code>transport=="CAN-REMOTE"</code> 绛変唬鐞嗗瀷椹卞姩锛堟妸鍛戒护搴忓垪鍖栦负 Broker 璇锋眰锛夛紱鐜版湁鐩磋繛椹卞姩涓嶅姩銆�<code>IBrokeredTransport</code> 鎺ュ彛瀹氫箟浜� Contracts</td>
+ </tr>
+ <tr>
+ <td><span class="path">Plugin.DeviceDebug/Model/DebugSessionManager.cs</span></td>
+ <td>寰皟</td>
+ <td><code>RequestMaintenance</code> 澶勭悊 <code>PendingHandover</code>锛堣浆寮傛绛夊緟 + UI 鍥炶皟"绛夊緟宸ヤ綅璁╂浮锛屽墿浣� X 绉�"锛夛紱鍐茬獊寮傚父 message 宸插惈鍗犵敤鑰� 鈫� 鐩存帴缁� ToastHelper</td>
+ </tr>
+ <tr>
+ <td><span class="path">Plugin.DeviceDebug/Model/DeviceDebugModel.cs</span></td>
+ <td>寰皟</td>
+ <td>debug_session 鏂板鍒楀啓鍏ワ紱鍚姩鏃� <code>SELECT ... WHERE state NOT IN (Closed) AND heartbeat杩囨湡</code> 鍋氬鍎夸細璇濆洖鏀讹紙缃� Faulted锛�</td>
+ </tr>
+ <tr>
+ <td><span class="path">Plugin.DeviceConfig/Model/DeviceConfigModel.cs</span></td>
+ <td>DDL</td>
+ <td>搂9.1 鐨勫缓琛�/鍔犲垪锛堝箓绛夛紝IF NOT EXISTS / try-catch ALTER锛夛紱<span class="path">DeviceEditModal.xaml(.cs)</span> 澧炲姞 access_mode 涓嬫媺</td>
+ </tr>
+ <tr>
+ <td><span class="path">Aging.Infrastructure/InfrastructureBootstrapper.cs</span></td>
+ <td>閰嶇疆鐐�</td>
+ <td>娉ㄥ唽 <code>LayeredResourceManager</code>锛堝甫 dbPath锛夋浛浠g函鍐呭瓨鐗堬紱璇� <code>StationId</code>锛涘彲閫夋敞鍐� BrokerClient 浼犺緭</td>
+ </tr>
+ <tr>
+ <td>鈽呮柊寤� <span class="path">DeviceBroker/</span> 鎺у埗鍙板伐绋嬶紙Phase 3锛�</span></td>
+ <td>鏂板</td>
+ <td>寮曠敤 ConnectionUtil 鐜版垚 PipeServer锛涘崗璁細<code>{op, deviceId, channel, payload, token, gen, idemKey}</code>锛涘唴閮ㄦ寜璁惧闃熷垪 + 澶嶇敤 DriverFactory 鍒涘缓鐪熷疄椹卞姩锛涘穿婧冪湅闂ㄧ嫍锛堢埗杩涚▼鍙ユ焺澶辫仈鑷姩閫�鍑轰氦 HMI 鎷夎捣锛�</td>
+ </tr>
+</table>
+
+<h3>9.3 鍏抽敭鎺ュ彛绛惧悕锛圥hase 1 鏍稿績浠g爜绀轰緥锛�</h3>
+<pre><code><span class="cmt">// DbLeaseStore 鈥斺�� 鍘熷瓙鐢宠锛堝搴� 搂5.3 SQL锛�</span>
+<span class="kwd">public sealed class</span> DbLeaseStore
+{
+ <span class="kwd">public</span> DbLeaseStore(<span class="kwd">string</span> dataDbPath) { <span class="cmt">/* PRAGMA journal_mode=WAL; busy_timeout=5000 */</span> }
+
+ <span class="kwd">public enum</span> AcquireResult { Acquired, Renewed, QueuedHandover, RejectedMaintenanceHeld, RejectedByProductionHeld }
+
+ <span class="kwd">public</span> AcquireResult TryAcquire(<span class="kwd">string</span> resourceKey, ResourceOwnerToken owner, OwnerType type,
+ <span class="kwd">string</span> machine, <span class="kwd">int</span> pid, <span class="kwd">string</span>? slotId, <span class="kwd">int</span> ttlSeconds);
+ <span class="kwd">public bool</span> Renew(<span class="kwd">string</span> resourceKey, <span class="kwd">string</span> tokenId, <span class="kwd">long</span> generation, <span class="kwd">int</span> ttlSeconds);
+ <span class="kwd">public bool</span> Release(<span class="kwd">string</span> resourceKey, <span class="kwd">string</span> tokenId);
+ <span class="kwd">public long</span> CurrentGeneration(<span class="kwd">string</span> resourceKey); <span class="cmt">// FenceCheck 鐢�</span>
+ <span class="kwd">public int</span> SweepExpired(); <span class="cmt">// 鎳掑洖鏀跺厹搴�</span>
+ <span class="kwd">public</span> (bool valid, <span class="kwd">string</span>? holder, <span class="kwd">int</span>? graceSec) ProbeConflict(<span class="kwd">string</span> resourceKey);
+}
+
+<span class="cmt">// AutoDeviceLease 蹇冭烦锛圥hase 1锛夆�斺�旂嫭绔嬬嚎绋嬶紝UI 鍗¢】涓嶅奖鍝�</span>
+_beacon = <span class="kwd">new</span> Timer(_ => {
+ <span class="kwd">try</span> {
+ <span class="kwd">if</span> (!_store.Renew(DeviceId, _owner.TokenId, _owner.Generation, _ttl))
+ { LeaseLost?.Invoke(<span class="kwd">this</span>, EventArgs.Empty); <span class="kwd">return</span>; }
+ <span class="kwd">if</span> (_store.IsPendingHandover(DeviceId)) _handoverTcs.TrySetResult(<span class="kwd">true</span>);
+ _failCount = 0;
+ } <span class="kwd">catch</span> { <span class="kwd">if</span> (++_failCount >= 2) LeaseLost?.Invoke(<span class="kwd">this</span>, EventArgs.Empty); }
+}, <span class="kwd">null</span>, _ttlMs/3, _ttlMs/3);
+
+<span class="cmt">// TestStep 鍩虹被鍦ㄦ楠よ竟鐣岃娓★紙闆嗘垚娴嬭瘯婕旂ず鐢ㄦ硶锛�</span>
+<span class="kwd">if</span> (lease.HandoverRequested) lease.Dispose(); <span class="cmt">// 姝ラ缁撴潫鐐规鏌ワ紝缁濅笉鍦ㄥ懡浠や腑閫旀斁鎵�</span></code></pre>
+
+<!-- ================================================================= -->
+<h2 id="s10">10. 娴嬭瘯瑕佺偣</h2>
+
+<h3>10.1 鍗曞厓锛�<span class="path">HMI.UnitTest</span> 鎴栨柊寤� xUnit锛�</h3>
+<table>
+ <tr><th>鐢ㄤ緥</th><th>楠岃瘉鐐�</th></tr>
+ <tr><td>Acquire 骞跺彂 20 绾跨▼鍚� key</td><td>鎭板ソ 1 涓� Acquired锛屽叾浣� Rejected/Renewed锛堝悓 token锛夛紱generation 涓ユ牸 +1 鏃犺烦鍙樼珵浜�</td></tr>
+ <tr><td>Renew 鐢ㄦ棫 generation</td><td>杩斿洖 false锛堟爡鏍忚涔夛級</td></tr>
+ <tr><td>TTL 杩囨湡 鈫� 鐩存帴 Acquire 杩囨湡鎸佹湁鑰呯殑 key</td><td>鎳掑洖鏀剁敓鏁堬細鍏� DELETE 杩囨湡琛屽啀鎻掑叆鎴愬姛</td></tr>
+ <tr><td>浠茶鐭╅樀鍏ㄩ亶鍘嗭紙3脳3 鎸佹湁脳璇锋眰锛�</td><td>搂6.1 姣忎釜鏍煎瓙涓�涓柇瑷�</td></tr>
+ <tr><td>缁勭敵璇烽儴鍒嗗啿绐�</td><td>鍏ㄥ洖婊氾紝涓嶇暀涓�"鍗犱簡涓�鍗�"鐨勮</td></tr>
+</table>
+
+<h3>10.2 澶氳繘绋嬮泦鎴愶紙鍒╃敤 <span class="path">Plugin.IntegrationTest</span> 鎵╁睍锛岄噸鐐癸級</h3>
+<div class="card">
+鍦�"鍏ㄨ嚜鍔ㄦ祴璇�" Tab 澧炲姞 <strong>銆愬杩涚▼鍘嬪姏鐢ㄤ緥銆�</strong>鎸夐挳锛�
+<pre><code><span class="cmt">// 浼唬鐮侊細涓昏繘绋� fork N 涓嚜韬� --station-worker 妯″紡鐨勫瓙杩涚▼</span>
+<span class="kwd">for</span> (<span class="kwd">int</span> s = 0; s < 4; s++)
+ Process.Start(exe, $<span class="str">"--worker {s} --device CAN-001 --loops 200"</span>);
+
+<span class="cmt">// 瀛� worker 閫昏緫锛氬惊鐜� [TryAcquire 鈫� 鍙戜竴甯� 鈫� 鏍¢獙 鈫� Dispose]锛岀粺璁℃垚鍔熻疆杞鏁�</span>
+<span class="cmt">// 涓昏繘绋嬫柇瑷�锛氣憼 浠绘剰鏃跺埢 device_lease 鍙湁 1 琛屾湁鏁� 鈶� 鎵�鏈夊抚鐨� generation 鍗曡皟 鈶� 鏃犲弻鍐�</span>
+<span class="cmt">// 鈶� 涓�� Kill(闅忔満 worker) 鈫� 鍏朵綑 worker 鈮� TTL+5s 鍐呮帴绠★紝娴嬭瘯缁х画鏀舵暃涓� PASS</span></code></pre>
+棰濆涓や釜鏉�鎵嬬骇鐢ㄤ緥锛�
+<ul>
+<li><strong>宕╂簝瀛ゅ効閿�</strong>锛�<code>Process.Kill</code> 鎸佹湁鑰咃紙涓嶈窇 Dispose锛夆啋 鏂█ 鈮�35s 鍚庤鍏朵粬宸ヤ綅鑷姩鎺ョ锛�<code>host_process_id</code> 鍚屾満鐪嬮棬鐙楄矾寰勫垯 鈮�2s 鍥炴敹锛�</li>
+<li><strong>缁存姢鎶㈠崰婕旂粌</strong>锛歸orker A 闀垮惊鐜寔绉� 鈫� UI 鍙戣捣 RequestMaintenance 鈫� 鏂█ grace 鍐呰娓°�丮aintenance 鑾峰緱銆丄 閲嶇敵璇疯鎷掞紙RejectionMessage 鍚�"缁存姢"锛夛紱鏈熼棿 A 鑻ヨ繚瑙勭‖鍙戝懡浠� 鈫� 椹卞姩杩斿洖 <code>LEASE_STALE</code>銆�</li>
+</ul>
+</div>
+
+<!-- ================================================================= -->
+<h2 id="s11">11. 鍒嗛樁娈靛疄鏂借鍒掍笌宸ヤ綔閲�</h2>
+
+<table>
+ <tr><th>闃舵</th><th>浜や粯鐗�</th><th>瑙e喅鐨勭棝鐐�</th><th>宸ヤ綔閲�</th></tr>
+ <tr>
+ <td><strong>Phase 1<br>璺ㄨ繘绋嬬绾�</strong></td>
+ <td>device_lease DDL锛�<code>DbLeaseStore</code>锛�<code>ResourceManager</code> 缁勫悎鍖栵紱蹇冭烦 + 鏍呮爮 + 鎳掑洖鏀讹紱Bootstrapper 鍒囨崲锛涘杩涚▼闆嗘垚娴嬭瘯</td>
+ <td class="good">澶氳繘绋嬩簰鏂ヤ徊瑁� 鉁� 宕╂簝鑷剤 鉁� 瀹¤鍙拷婧� 鉁� 涓婂眰闆舵敼鍔� 鉁�</td>
+ <td><strong>3~4 浜烘棩</strong></td>
+ </tr>
+ <tr>
+ <td><strong>Phase 2<br>浠茶瑙勫垯 & UI</strong></td>
+ <td><code>LeaseArbiter</code> 浼樺厛绾х煩闃碉紱缁存姢鎶㈠崰/璁╂浮娴佺▼锛�<span class="path">DebugSessionManager</span> PendingHandover锛汬MI"鍗犵敤鑰呬俊鎭�/寮哄埗閲婃斁"锛沘ccess_mode 娉ㄥ唽椤� + 缁勭绾� <code>AcquireGroupAsync</code></td>
+ <td class="good">"浜哄湪鎺ョ嚎绋嬪簭涓嶈兘鍔�"纭繚璇� 鉁� 宸ヤ綅鍒嗙粍 鉁�</td>
+ <td><strong>2~3 浜烘棩</strong></td>
+ </tr>
+ <tr>
+ <td><strong>Phase 3<br>Device Broker锛堟寜闇�瑙﹀彂锛�</strong></td>
+ <td><span class="path">DeviceBroker</span> 宸ョ▼锛堝鐢� ConnectionUtil 绠¢亾锛夛紱浠g悊鍨嬮┍鍔� <code>*BrokeredDriver</code>锛涘鏈烘帴鍏ワ紱鍛戒护闃熷垪 + TimeShared 绛栫暐钀藉湴</td>
+ <td class="good">涓插彛/USB 鍙ユ焺鐙崰鏍规不 鉁� 澶氭満鍏变韩 鉁� 鍒嗘椂鍛戒护涓茶鍖� 鉁�</td>
+ <td><strong>5~8 浜烘棩</strong></td>
+ </tr>
+ <tr>
+ <td><strong>Phase 4<br>婕旇繘锛堝彲閫夛級</strong></td>
+ <td>椹卞姩杩佺Щ涓� OpenTAP Instrument 鎻掍欢鍖咃紙.opentap锛夛紱Bench 閰嶇疆涓� DeviceConfig 鍗曟簮鍖栵紱HMI 鍐呭祵椹卞姩绠$悊锛圛mage API锛�</td>
+ <td class="good">鍘傚晢椹卞姩鐢熸�佸鐢ㄣ�佸垎鍙戣繍缁�</td>
+ <td>鍙﹁瘎浼�</td>
+ </tr>
+</table>
+
+<div class="success"><strong>瑙﹀彂 Phase 3 鐨勫垽鏂爣鍑嗭紙閬垮厤杩囧害璁捐锛夛細</strong>鍑虹幇浠ヤ笅浠讳竴鎯呭喌鎵嶇珛椤光�斺�斺憼涓插彛/USB 璁惧绉熺害鏄撴墜棰戠巼楂樺埌 close/open 鎶栧姩鎴愪负鐡堕锛涒憽纭湁 2 鍙颁互涓婄數鑴戦渶瑕佹搷浣滃悓涓�鍙扮墿鐞嗕华鍣紱鈶㈠嚭鐜� 鈮�1 鍙� TimeShared 鍛戒护绾т覆琛岃澶囨湁骞惰鎺掗槦闇�姹傘�傚惁鍒� Phase 1+2 宸查棴鐜富瑕侀闄┿��</div>
+
+<!-- ================================================================= -->
+<h2 id="s12">12. 椋庨櫓銆佸弽妯″紡涓庝笉鎺ㄨ崘鍋氭硶</h2>
+
+<table>
+ <tr><th>鍙嶆ā寮�</th><th>鍚庢灉</th><th>姝g‘鍋氭硶</th></tr>
+ <tr><td class="bad">澶氳繘绋嬪悇鑷� open 鍚屼竴 COM 鍙�/CAN 鍗″彞鏌�"纰拌繍姘�"</td><td>WriteFile 浜ら敊銆佹暟鎹挄瑁傘�佽摑灞忕骇鏈畾涔夎涓�</td><td>瑕佷箞绉熺害淇濊瘉鍗曟寔鏈夎�咃紙Phase 1锛夛紝瑕佷箞 Broker 鍞竴鎸佹湁锛圥hase 3锛夈��<strong>鐗╃悊灞備笉鍏佽骞跺彂鏄‖绾︽潫锛屼换浣曡蒋浠舵柟妗堜笉鑳芥寫鎴�</strong></td></tr>
+ <tr><td class="bad">浠呯敤 Named Mutex 褰撶绾�</td><td>宕╂簝鍚庢帴绠℃柟瀵硅澶囩姸鎬佸叏鐩诧紙杈撳嚭鍙兘杩樺紑鐫�锛�</td><td>Mutex 鍙厤鍋氬悓鏈哄揩閫熶俊鍙凤紝鐘舵�佷笌浜ゆ帴璇箟蹇呴』鍦� DB 琛紙搂3 鏂规鈶¤瘎浼帮級</td></tr>
+ <tr><td class="bad">缃戠粶鍏变韩鐩橈紙SMB锛変笂鏀� data.db 渚涘鏈哄啓</td><td>SQLite 閿佸湪 SMB 璇箟涓嶅彲闈� 鈫� 鍙屾寔鏈夎�� = 鐪熷疄鐐告満椋庨櫓</td><td>澶氭満鍦烘櫙锛歅hase 3 Broker锛堟瘡鍙扮墿鐞嗘満涓�浠� DB锛夋垨绉熺害琛ㄨ縼鍒版湇鍔$ SQL</td></tr>
+ <tr><td class="bad">瀹㈡埛绔嚜宸辩畻 expires_at 浼犵粷瀵规椂闂�</td><td>鏃堕挓婕傜Щ瀵艰嚧鎻愬墠/寤惰繜鍥炴敹</td><td>鍙紶鐩稿 TTL锛孌B 渚� <code>datetime('now')</code> 璁$畻锛埪�7锛�</td></tr>
+ <tr><td class="bad">TTL 璁� 5 鍒嗛挓"姹傜ǔ"</td><td>宕╂簝鍚庡叾浠栧伐浣嶅共绛� 5 鍒嗛挓</td><td>TTL 30s + 蹇冭烦 10s锛涘悓鏈� PID 鐪嬮棬鐙楃绾у厹搴�</td></tr>
+ <tr><td class="bad">鎶㈠崰鍙戠敓鍦ㄤ竴鏉″瀛楄妭 CAN 浜嬪姟涓棿</td><td>璁惧鍗″湪鍗婂寘鐘舵��</td><td>璁╂浮鐐逛弗鏍煎榻� TestStep 杈圭晫/鍗曟潯鍛戒护瀹屾垚锛埪�5.4 閾佸緥鈶級</td></tr>
+ <tr><td class="bad">缁存姢妯″紡涓嶅仛鏍呮爮鏍¢獙"鍙嶆鏈� UI 寮圭獥"</td><td>UI 寮圭獥鍙蹇界暐锛岀▼搴� bug 缁曚笉杩�</td><td>椹卞姩鍏ュ彛 FenceCheck 鏄墿鐞嗛椄闂紙搂7 鍍靛案琛岋級锛屽脊绐楀彧鏄綋楠屽眰</td></tr>
+ <tr><td class="bad">蹇冭烦鎸傚湪 UI Dispatcher</td><td>WPF 涓荤嚎绋嬪崱椤库啋鍋囨璇垽琚姠鍗�</td><td>鐙珛鍚庡彴绾跨▼锛埪�9.3 浠g爜宸插悎瑙勶級</td></tr>
+</table>
+
+<h3>宸茬煡灞�闄愶紙璇氬疄澹版槑锛�</h3>
+<ul>
+<li><strong>SQLite 鍗曞啓鑰�</strong>锛氱绾﹀啓 QPS 涓婇檺绾︾櫨绾э紱鑰佸寲鑺傛媿锛堢绾э級杩滀綆浜庢锛屼絾楂橀閬ユ祴涓嶈璧扮绾﹁〃锛堣蛋缁撴灉閫氳矾锛夈��</li>
+<li><strong>Phase 1 鍚庡鏈轰粛鍙楅檺</strong>锛氬崟鏈哄唴澶氳繘绋嬪畬鍏ㄨВ鍐筹紱澶氭満闇�瑕佹妸 <code>device_lease</code> 鎵�鍦ㄥ簱鏀惧埌鏈嶅姟鍣紙琛ㄧ粨鏋勪笉鍙橈紝<code>DbLeaseStore</code> 鎹㈣繛鎺ュ伐鍘傚嵆鍙�斺�旇繖鏄� Phase 3 鍓嶇殑鏈�灏忓彴闃讹級銆�</li>
+<li><strong>Broker 鍗曠偣</strong>锛歅hase 3 寮曞叆鐪嬮棬鐙楁媺璧凤紱Broker 閲嶅惎鏈熼棿鍛戒护鐭殏涓嶅彲鐢紙璁惧鏈韩涓嶅彈褰卞搷锛夈��</li>
+</ul>
+
+<!-- ================================================================= -->
+<h2 id="s13">13. 缁撹</h2>
+
+<div class="success">
+<ol>
+<li><strong>涓ょ被鍦烘櫙鍒嗗埆娌荤悊</strong>锛氳繘绋嬪唴澶氱嚎绋嬬户缁敤鐜版湁鍐呭瓨閿� + OpenTAP 鍚屾锛涜法杩涚▼鎵嶆槸鐪熸缂哄彛锛屼笉瑕佺敤涓�涓満鍒剁‖鍚冧袱涓満鏅��</li>
+<li><strong>涓讳綋鏂规 = SQLite 绉熺害琛紙TTL+蹇冭烦+generation 鏍呮爮+鎳掑洖鏀讹級</strong>锛屼綔涓� <code>IResourceManager</code> 鐨勮法杩涚▼瀹炵幇锛屼笂灞� <code>IAutoDeviceFacade</code>/<code>AutoDeviceLease</code>/<code>DebugSessionManager</code> 鎺ュ彛绛惧悕涓庝笟鍔′唬鐮�<strong>闆舵敼鍔�</strong>锛圥hase 1锛�3~4 浜烘棩锛夈��</li>
+<li><strong>瀹夊叏纭繚璇侀潬鏍呮爮锛屼笉闈犵ぜ璨�</strong>锛氭瘡鏉″懡浠ら┍鍔ㄥ叆鍙f牎楠� generation锛屽疄鐜�"浜哄湪鎺ョ嚎鏃剁▼搴忕墿鐞嗗彂涓嶅嚭鎸囦护"锛埪�6 淇℃伅+搂7 鍍靛案琛岋級銆傛姠鍗�/璁╂浮鍙湪 TestStep 杈圭晫锛実race 榛樿 30s銆�</li>
+<li><strong>Device Broker锛圥hase 3锛変粎鍦ㄨЕ鍙戞潯浠跺嚭鐜版椂绔嬮」</strong>锛氫覆鍙�/USB 鍙ユ焺鎶栧姩銆佸鏈哄叡娴嬨�佸垎鏃舵帓闃熲�斺�斾笁鑰呬换涓�銆備紶杈撳眰鐩存帴澶嶇敤浠撳簱鐜版垚鐨� <code>ConnectionUtil.PipeServer/PipeClient</code>锛屼笉蹇呭紩鍏� WCF/gRPC銆�</li>
+<li><strong>OpenTAP 鐢熸�佽В鍐崇殑鏄�"鍒嗗彂涓庡舰鎬�"鑰岄潪"杩愯鏃朵徊瑁�"</strong>鈥斺�旇法杩涚▼浠茶鏄畠鐨勭┖鐧斤紝浣犱滑鐨� IResourceManager + 绉熺害琛ㄦ伆濂借ˉ浣嶏紝杩欐槸鏈」鐩樊寮傚寲璧勪骇锛涢暱鏈熸妸鐗╃悊浠櫒鍖呰鎴� OpenTAP Instrument 鎻掍欢鍖呬笌绉熺害浣撶郴骞惰涓嶆倴銆�</li>
+<li><strong>鐙崰 vs 鍒嗘椂鐢� <code>access_mode</code> 鏄惧紡寤烘ā</strong>锛堟敞鍐岄〉鍙�夛級锛屽伐浣嶅垎缁勫鐢� <code>SlotDeviceMapping</code> + 缁勭绾︽寜 key 瀛楀吀搴忓師瀛愮敵璇凤紝鏉滅粷姝婚攣銆�</li>
+<li><strong>宕╂簝娈嬬暀鏄敮涓�鐪熸闅剧殑闂锛孴TL+鐪嬮棬鐙�+鎳掑洖鏀朵笁灞傚啑浣欒В鍐�</strong>锛涙祴璇曠敤 Kill 杩涚▼婕旂粌鎺ョ鏀舵暃锛埪�10.2锛夛紝涓婄嚎鍓嶅繀椤昏繃銆�</li>
+</ol>
+</div>
+
+<footer>
+ 澶氳繘绋�/澶氱嚎绋嬩华鍣ㄨ祫婧愮嫭鍗犱笌鍏变韩鏂规 路 TapProject Aging Infrastructure 鏋舵瀯璁捐 路 2026-11-03<br>
+ 鍏宠仈鏂囨。锛�<a href="./OpenTAP_Instrument_Package_Analysis.html">OpenTAP Instrument + 鎻掍欢鍖呮満鍒跺垎鏋�</a> 路
+ <a href="./DeviceConfig_DeviceDebug_Architecture.html">浠櫒娉ㄥ唽涓庣‖浠惰皟璇曡皟鐢ㄥ叧绯�</a>
+</footer>
+
+<script>
+ mermaid.initialize({
+ startOnLoad: true, theme: 'default', securityLevel: 'loose',
+ fontFamily: 'Segoe UI, Microsoft YaHei, sans-serif',
+ flowchart: { curve: 'basis', padding: 16 },
+ sequence: { showSequenceNumbers: false, actorMargin: 50 }
+ });
+</script>
+
+</body>
+</html>
--
Gitblit v1.9.1