質問するログイン新規登録

質問編集履歴

3

ソースコードを更新致しました。

2017/07/21 02:32

投稿

GuielNo4
GuielNo4

スコア88

title CHANGED
File without changes
body CHANGED
@@ -9,27 +9,170 @@
9
9
  ###該当のソースコード
10
10
 
11
11
  ```ここに言語を入力
12
- private Queue<byte> receivedDatas = new Queue<byte>();
13
- private int backup_count = 0;
12
+ Program.cs
14
- public void update()
13
+ class Program
15
14
  {
16
- Queue<byte> pickedup = new Queue<byte>();
15
+ volatile static bool _keyReaded = false;
17
- getData(ref pickedup);
18
- if ( pickedup.Count.Equal(0) )
16
+ static void Main(string[] args)
19
17
  {
18
+ ConvertFrame convertFrame = new ConvertFrame();
19
+ bool isFinish = false;
20
+ while (!isFinish)
21
+ {
22
+ convertFrame.update();
23
+ Console.WriteLine(convertFrame.listFrames.Count.ToString());
24
+ /// キー入力で終了します。
25
+ if (_keyReaded)
26
+ {
20
- return;
27
+ isFinish = true;
28
+ }
29
+ }
21
30
  }
22
- foreach( int index in Enumerable.Range(0, pickedup.Count ) )
31
+ static void MonitoringKey(object userState)
23
32
  {
24
- receivedDatas.Enqueue( pickedup.Dequeue() );
33
+ ConsoleKeyInfo keyInfo = Console.ReadKey(true);
34
+ _keyReaded = true;
25
35
  }
36
+ }
37
+
38
+ ConvertFrame.cs
39
+ class ConvertFrame
40
+ {
41
+ private Queue<byte> receivedDatas = new Queue<byte>();
42
+ private int backup_count = 0;
43
+
44
+ public List<byte[]> listFrames { get; private set; }
45
+
26
- if ( receivedDatas.Count.Equal(0) )
46
+ private Serial uart = new Serial();
47
+
48
+
49
+ public ConvertFrame()
27
50
  {
51
+ listFrames = new List<byte[]>();
52
+ uart.Open("COM1", 115200);
53
+ }
54
+
55
+ public void update()
56
+ {
57
+ Queue<byte> pickedup = new Queue<byte>();
58
+ uart.getData(ref pickedup);
59
+ if (pickedup.Count.Equals(0))
60
+ {
61
+ return;
62
+ }
63
+ foreach( int index in Enumerable.Range(0, pickedup.Count ) )
64
+ {
65
+ receivedDatas.Enqueue( pickedup.Dequeue() );
66
+ }
67
+ if ( receivedDatas.Count.Equals(0) )
68
+ {
69
+ return;
70
+ }
71
+ backup_count = receivedDatas.Count; // --- (1)
72
+ byte head = receivedDatas.Peek(); //---- (2)
73
+
74
+ head = 16; /// ---- (A)
75
+
76
+ bool isExistDatas = true;
77
+ while( isExistDatas )
78
+ {
79
+ if ( receivedDatas.Count >= (int)head )
80
+ {
81
+ List<byte> frame = new List<byte>();
82
+ foreach (int index in Enumerable.Range(0, (int)head ))
83
+ {
84
+ frame.Add(receivedDatas.Dequeue()); // ---(3)
85
+ }
86
+ listFrames.Add( frame.ToArray() );
87
+ }
88
+ else
89
+ {
90
+ isExistDatas = false;
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ Serial.cs
97
+ class Serial
98
+ {
99
+ private SerialPort targetPort;
100
+ private List<byte[]> receivedBytes = new List<byte[]>();
101
+ private byte[] pickedupBytes = new byte[4096];
102
+
103
+ public Serial()
104
+ {
105
+ }
106
+
107
+ public void Open(string namePort, int baudRate)
108
+ {
109
+ string PortName = namePort;
110
+ int BaudRate = baudRate;
111
+ Parity Parity = Parity.None;
112
+ int DataBits = 8;
113
+ StopBits StopBits = StopBits.One;
114
+ targetPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits);
115
+ targetPort.Handshake = System.IO.Ports.Handshake.None;
116
+ targetPort.ReadTimeout = 0;
117
+ targetPort.WriteTimeout = 1500;
118
+ targetPort.ReadBufferSize = 1024 * 12;
119
+ targetPort.WriteBufferSize = 1024 * 12;
120
+ targetPort.DataReceived += new SerialDataReceivedEventHandler(ReceivedHandler);
121
+ targetPort.Open();
122
+ }
123
+
124
+ public void Close()
125
+ {
126
+ targetPort.Close();
127
+ }
128
+
129
+ public bool getData(ref Queue<byte> pickedup)
130
+ {
131
+ lock (receivedBytes)
132
+ {
133
+ if (receivedBytes.Count.Equals(0))
134
+ {
135
+ return false;
136
+ }
137
+
138
+ foreach (byte[] array in receivedBytes)
139
+ {
140
+ foreach (byte data in array)
141
+ {
142
+ pickedup.Enqueue(data);
143
+ }
144
+ }
145
+ /// 引数に渡したのでクリアする。
146
+ receivedBytes.Clear();
147
+ }
148
+ return true;
149
+ }
150
+
151
+ private void ReceivedHandler(object sender, SerialDataReceivedEventArgs e)
152
+ {
153
+ int totalCount = 0;
154
+ try
155
+ {
156
+ totalCount = targetPort.Read(pickedupBytes, totalCount, pickedupBytes.Length);
157
+ }
158
+ catch (TimeoutException exception)
159
+ {
160
+ Console.WriteLine(exception);
161
+ Console.ReadKey();
162
+ }
163
+
164
+ /// 固定長サイズのピックアップバッファから、受信データ数の分だけ取り出しておく。
165
+ byte[] buffer = new byte[totalCount];
166
+ Array.Copy(pickedupBytes, 0, buffer, 0, totalCount);
167
+
168
+ lock (receivedBytes)
169
+ {
170
+ receivedBytes.Add(buffer);
171
+ }
28
172
  return;
29
173
  }
30
- backup_count = receivedDatas.Count; --- (1)
31
- byte head = receivedDatas.Peek(); ---- (2)
32
174
  }
175
+
33
176
  ```
34
177
 
35
178
  (2) で「InvalidOprationException」が発生し、ウォッチで確認すると、
@@ -37,6 +180,16 @@
37
180
  直前の(1) backup_count は 0x20 とゼロではないため、
38
181
  今後、どのような分析を行うべきか、質問させて頂きました。
39
182
 
183
+ 追記:
184
+ 問題の発生する部分だけ抽出してコード全体を書き直しました。
185
+ 上記のコードを実際に走らせ、現象の再発を確認できしました。
186
+ ただ、今度は(3) で発生するようになりました。
187
+ このとき、backup_count = 0x36 , head = 0x06 なのですが、
188
+ 例外で Queue が空という内容でした。
189
+
190
+ また、(A)の部分ですが、head の値が大きい場合に問題が発生している可能性も考えて、
191
+ 16 byte に変更しています。だた、同じ例外が発生しました。
192
+
40
193
  アドバイスの程、宜しくお願い申し上げます。
41
194
 
42
195
 

2

コードにミスがありました。修正致します。

2017/07/21 02:32

投稿

GuielNo4
GuielNo4

スコア88

title CHANGED
File without changes
body CHANGED
@@ -19,7 +19,7 @@
19
19
  {
20
20
  return;
21
21
  }
22
- foreach( int index in Enumerable.Range(0, pickedup ) )
22
+ foreach( int index in Enumerable.Range(0, pickedup.Count ) )
23
23
  {
24
24
  receivedDatas.Enqueue( pickedup.Dequeue() );
25
25
  }

1

変数名のミスを修正しました。

2017/07/20 13:01

投稿

GuielNo4
GuielNo4

スコア88

title CHANGED
File without changes
body CHANGED
@@ -28,7 +28,7 @@
28
28
  return;
29
29
  }
30
30
  backup_count = receivedDatas.Count; --- (1)
31
- byte head = receivedBuffer.Peek(); ---- (2)
31
+ byte head = receivedDatas.Peek(); ---- (2)
32
32
  }
33
33
  ```
34
34
 
@@ -39,6 +39,8 @@
39
39
 
40
40
  アドバイスの程、宜しくお願い申し上げます。
41
41
 
42
+
43
+
42
44
  ###補足情報(言語/FW/ツール等のバージョンなど)
43
45
  visual studio 2013
44
46
  .NET Framework 3.5