1
+ using ISPCore . Connect ;
2
+ using ISPCore . Packet ;
3
+ using ISPCore . Util ;
4
+ using SMTool . Protocol ;
5
+ using SMTool . Protocol . ShellCmd ;
6
+ using SMTool . UI ;
7
+ using System ;
8
+ using System . Collections . Generic ;
9
+ using System . IO . Ports ;
10
+ using System . Linq ;
11
+
12
+ namespace SMTool . Connect
13
+ {
14
+ public class SerialConnector : ConnectorBase , IProtocolConnector
15
+ {
16
+ // 私有方法及对象
17
+ public SerialPort serialport ;
18
+ public bool IsUSBSerial ;
19
+
20
+ public CmdManager Cmd ;
21
+
22
+ public MainWindow Mw ;
23
+
24
+ #region ShellCmd
25
+ private Queue < ShellCmd > ShellCmdQueue = new Queue < ShellCmd > ( ) ;
26
+
27
+ private static readonly object ShellCmdLock = new object ( ) ;
28
+
29
+ private bool IsExclusiveMode = false ;
30
+ public int CmdCount
31
+ {
32
+ get
33
+ {
34
+ return ShellCmdQueue . Count ;
35
+ }
36
+ }
37
+
38
+ public SendPacketDelegate SendHandle {
39
+ get
40
+ {
41
+ return SendFunction ;
42
+ }
43
+ }
44
+
45
+ public ReceiveDataDelegate ReceiveHandle { get ; set ; }
46
+
47
+ public bool AddCmd ( ShellCmd cmd )
48
+ {
49
+ lock ( ShellCmdLock )
50
+ {
51
+ try
52
+ {
53
+ ICmd newcmd ;
54
+ switch ( Mw . ChipName )
55
+ {
56
+ default :
57
+ newcmd = null ;
58
+ break ;
59
+ }
60
+ if ( ! Cmd . Add ( newcmd ) )
61
+ {
62
+ return false ;
63
+ }
64
+ Cmd . Start ( ) ;
65
+ return true ;
66
+ }
67
+ catch ( Exception ex )
68
+ {
69
+ Log . error ( "添加命令失败!错误消息:" + ex . Message ) ;
70
+ return false ;
71
+ }
72
+ // TODO
73
+ /*if (IsExclusiveMode) return false;
74
+ ShellCmdQueue.Enqueue(cmd);
75
+ return true;*/
76
+ }
77
+ }
78
+
79
+ public bool AddCmd ( ShellCmd cmd , string groupID )
80
+ {
81
+ lock ( ShellCmdLock )
82
+ {
83
+ if ( IsExclusiveMode && ShellCmdQueue . Count > 0 && ShellCmdQueue . Peek ( ) . GroupID == groupID )
84
+ {
85
+ cmd . GroupID = groupID ;
86
+ ShellCmdQueue . Enqueue ( cmd ) ;
87
+ return true ;
88
+ }
89
+ else if ( ! IsExclusiveMode && ShellCmdQueue . Count == 0 )
90
+ {
91
+ cmd . GroupID = groupID ;
92
+ cmd . IsStartCmd = true ;
93
+ ShellCmdQueue . Enqueue ( cmd ) ;
94
+ IsExclusiveMode = true ;
95
+ return true ;
96
+ }
97
+ else
98
+ {
99
+ return false ;
100
+ }
101
+ }
102
+ }
103
+
104
+ public bool AddCmdGroup ( ShellCmd [ ] cmds , string groupID )
105
+ {
106
+ lock ( ShellCmdLock )
107
+ {
108
+ // TODO
109
+ foreach ( ShellCmd cmd in cmds )
110
+ {
111
+ try
112
+ {
113
+ ICmd newcmd ;
114
+ switch ( Mw . ChipName )
115
+ {
116
+ default :
117
+ newcmd = null ;
118
+ break ;
119
+ }
120
+ if ( ! Cmd . Add ( newcmd ) )
121
+ {
122
+ return false ;
123
+ }
124
+ }
125
+ catch ( Exception ex )
126
+ {
127
+ Log . error ( "添加命令失败!错误消息:" + ex . Message ) ;
128
+ return false ;
129
+ }
130
+ }
131
+ Cmd . Start ( ) ;
132
+ return true ;
133
+ /*
134
+ if (IsExclusiveMode || ShellCmdQueue.Count != 0) return false;
135
+ foreach (ShellCmd cmd in cmds)
136
+ {
137
+ cmd.GroupID = groupID;
138
+ ShellCmdQueue.Enqueue(cmd);
139
+ }
140
+ ShellCmdQueue.Peek().IsStartCmd = true;
141
+ IsExclusiveMode = true;
142
+ return true;*/
143
+ }
144
+ }
145
+
146
+ public void ClearCmd ( bool isInExclusiveMode )
147
+ {
148
+ lock ( ShellCmdLock )
149
+ {
150
+ IsExclusiveMode = isInExclusiveMode ;
151
+ ShellCmdQueue . Clear ( ) ;
152
+ }
153
+ }
154
+ public void ClearCmd ( )
155
+ {
156
+ ClearCmd ( false ) ;
157
+ }
158
+ #endregion
159
+
160
+ public SerialConnector ( )
161
+ : base ( ConnectorType . SerialConnector )
162
+ {
163
+ Cmd = new CmdManager ( this ) ;
164
+ }
165
+
166
+ public List < byte > ReadBlockBytes = new List < byte > ( ) ;
167
+ public DateTime ReadByteTime ;
168
+ public byte [ ] ReadBuffer = new byte [ 0x2000 ] ;
169
+
170
+ public bool SendFunction ( byte [ ] SendBuffer )
171
+ {
172
+ if ( serialport != null && serialport . IsOpen && SendBuffer . Length > 0 )
173
+ {
174
+ Log . debug ( "PSend-> " + Tool . HexToString ( SendBuffer ) . ToUpper ( ) ) ;
175
+ serialport . Write ( SendBuffer , 0 , SendBuffer . Length ) ;
176
+ return true ;
177
+ }
178
+ else
179
+ {
180
+ return false ;
181
+ }
182
+ }
183
+
184
+ private int ReadCount ;
185
+ // 串口读取线程
186
+ private void SerialReadThread ( object sender , SerialDataReceivedEventArgs e )
187
+ {
188
+ // 串口读取事件 每接收一个字节触发一次
189
+ try
190
+ {
191
+ ReadCount = serialport . BytesToRead ;
192
+ ReadCount = ReadCount > 8192 ? 8192 : ReadCount ;
193
+ serialport . Read ( ReadBuffer , 0 , ReadCount ) ;
194
+ byte [ ] recv = new byte [ ReadCount ] ;
195
+ Array . Copy ( ReadBuffer , recv , ReadCount ) ;
196
+ ReceiveHandle ? . Invoke ( ReadBuffer . Take ( ReadCount ) . ToArray ( ) ) ;
197
+ //Log.debug("R: " + Tool.HexToString(ReadBuffer.Take(ReadCount).ToArray()).ToUpper());
198
+ }
199
+ catch ( Exception ex )
200
+ {
201
+ Log . error ( ex . Message ) ;
202
+ Log . debug ( "Rerror: " + Tool . HexToString ( ReadBuffer . Take ( ReadCount ) . ToArray ( ) ) ) ;
203
+ }
204
+ }
205
+
206
+ // 串口发送线程
207
+ protected override void WriteThread ( object state )
208
+ {
209
+ lock ( WriteTimerLock )
210
+ {
211
+ byte [ ] WriteBytes ;
212
+ if ( SerialChannel == SerialChannelEnum . ChipConnect )
213
+ {
214
+ WriteBytes = PACK . ReadyToWrite ( ) ;
215
+ }
216
+ else
217
+ {
218
+ lock ( ShellCmdLock )
219
+ {
220
+ if ( ShellCmdQueue . Count > 0 && ( ! ShellCmdQueue . Peek ( ) . IsSent ) )
221
+ {
222
+ WriteBytes = ShellCmdQueue . Peek ( ) . CmdBytes ;
223
+ ShellCmdQueue . Peek ( ) . IsSent = true ;
224
+ }
225
+ else
226
+ {
227
+ return ;
228
+ }
229
+ }
230
+ }
231
+
232
+ try
233
+ {
234
+ if ( serialport != null && serialport . IsOpen && WriteBytes . Length > 0 )
235
+ {
236
+ serialport . Write ( WriteBytes , 0 , WriteBytes . Length ) ;
237
+ Log . debug ( "send: " + Tool . HexToString ( WriteBytes , " " ) ) ;
238
+ }
239
+ }
240
+ catch ( Exception ex )
241
+ {
242
+ Log . error ( ex . Message ) ;
243
+ Disconnect ( ) ;
244
+ }
245
+ }
246
+ }
247
+
248
+ protected override void ReadThread ( object state )
249
+ {
250
+ lock ( ShellCmdLock )
251
+ {
252
+ if ( ShellCmdQueue . Count > 0 )
253
+ {
254
+ ShellCmd CurrentCmd = ShellCmdQueue . Peek ( ) ;
255
+ if ( CurrentCmd . TryAnalysisReslut ( ) )
256
+ {
257
+ if ( ShellCmdQueue . Count > 0 ) ShellCmdQueue . Dequeue ( ) ;
258
+ if ( IsExclusiveMode && ShellCmdQueue . Count == 0 )
259
+ {
260
+ Log . info ( "========== 命令组 [" + CurrentCmd . GroupID + "] 执行完成 ==========" ) ;
261
+ Log . info ( "开始时间: " + CurrentCmd . StartCmdTime . ToString ( "yyyy-MM-dd HH:mm:ss.fff" ) ) ;
262
+ Log . info ( "停止时间: " + CurrentCmd . ReadTime . ToString ( "yyyy-MM-dd HH:mm:ss.fff" ) ) ;
263
+ Log . info ( "执行时长: " + ( ( ( int ) ( CurrentCmd . ReadTime - CurrentCmd . StartCmdTime ) . TotalMilliseconds ) * 0.001 ) . ToString ( ) + " 秒!" ) ;
264
+ IsExclusiveMode = false ;
265
+ }
266
+ else if ( IsExclusiveMode && ShellCmdQueue . Peek ( ) . GroupID == CurrentCmd . GroupID )
267
+ {
268
+ ShellCmdQueue . Peek ( ) . StartCmdTime = CurrentCmd . StartCmdTime ;
269
+ }
270
+ else if ( IsExclusiveMode )
271
+ {
272
+ Log . error ( "未知情景,退出命令独占状态!" ) ;
273
+ IsExclusiveMode = false ;
274
+ }
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ public override void AutoConnectChip ( string devicename )
281
+ {
282
+ }
283
+
284
+ public enum SerialChannelEnum
285
+ {
286
+ ChipConnect ,
287
+ TestConnect
288
+ }
289
+
290
+ public SerialChannelEnum SerialChannel = SerialChannelEnum . TestConnect ;
291
+
292
+ public override void Connect ( object device )
293
+ {
294
+ if ( device is SerialPort )
295
+ {
296
+ IsUSBSerial = false ;
297
+ serialport = ( SerialPort ) device ;
298
+ try
299
+ {
300
+ serialport . DataBits = 8 ;
301
+ serialport . StopBits = StopBits . One ;
302
+ serialport . Parity = Parity . None ;
303
+ serialport . ReadTimeout = 50 ;
304
+ serialport . ReceivedBytesThreshold = 1 ;
305
+ serialport . DataReceived +=
306
+ new SerialDataReceivedEventHandler ( SerialReadThread ) ;
307
+ serialport . ReadBufferSize = 8192 ;
308
+ serialport . WriteBufferSize = 8192 ;
309
+ PACK . FlushReadBuffer ( ) ;
310
+ PACK . FlushWriteBuffer ( ) ;
311
+ CMD . ClearTask ( ) ;
312
+ serialport . Open ( ) ;
313
+ WriteTimer . Change ( 0 , 25 ) ;
314
+ ReadTimer . Change ( 0 , 25 ) ;
315
+ SerialChannel = SerialChannelEnum . ChipConnect ;
316
+ CreateEvent ( EventReason . ChipConnected , null ) ; // 仅串口连接成功
317
+ return ;
318
+ }
319
+ catch ( Exception ex )
320
+ {
321
+ Disconnect ( ) ;
322
+ CreateEvent ( EventReason . ConnectFailed , ex . Message ) ;
323
+ return ;
324
+ }
325
+ }
326
+ CreateEvent ( EventReason . ConnectFailed , "连接的不是串口设备!" ) ;
327
+ }
328
+
329
+ public void WaitUntilThreadOver ( ) {
330
+ lock ( ShellCmdLock )
331
+ {
332
+ Log . info ( "等待命令结束..." ) ;
333
+ }
334
+ lock ( WriteTimerLock ) {
335
+ serialport . BreakState = false ;
336
+ Log . info ( "等待发送结束..." ) ;
337
+ } ;
338
+ lock ( PacketTimerLock ) {
339
+ serialport . ReadExisting ( ) ;
340
+ Log . info ( "等待接收结束..." ) ;
341
+ } ;
342
+ }
343
+
344
+ public override void Disconnect ( ) {
345
+ try
346
+ {
347
+ ClearCmd ( ) ;
348
+ Cmd . Clear ( ) ;
349
+ ReadTimer . Change ( - 1 , - 1 ) ;
350
+ WriteTimer . Change ( - 1 , - 1 ) ;
351
+ WaitUntilThreadOver ( ) ;
352
+ serialport . Close ( ) ;
353
+ CreateEvent ( EventReason . Disconnected , null ) ;
354
+ }
355
+ catch ( Exception ex )
356
+ {
357
+ CreateEvent ( EventReason . Disconnected , ex . Message ) ;
358
+ }
359
+ finally
360
+ {
361
+ PACK . FlushReadBuffer ( ) ;
362
+ PACK . FlushWriteBuffer ( ) ;
363
+ CMD . ClearTask ( ) ;
364
+ serialport = null ;
365
+ }
366
+ }
367
+
368
+ internal void SerialChangedEvent ( DeviceListenerArgs e )
369
+ {
370
+ if ( e . DeviceType == DeviceListener . DBT_DEVTYP_PORT )
371
+ {
372
+ if ( e . DeviceAction == DeviceListener . DBT_DEVICEREMOVECOMPLETE && serialport != null && ! serialport . IsOpen )
373
+ {
374
+ Log . warn ( "串口已经断开!芯片连接即将关闭!" ) ;
375
+ Disconnect ( ) ;
376
+ }
377
+ CreateEvent ( EventReason . SerialChanged , null ) ;
378
+ }
379
+ }
380
+
381
+ protected override void ClearRead ( )
382
+ {
383
+ }
384
+ }
385
+ }
0 commit comments