Hi all,
I am using a Netduino Plus 2 ([color=rgb(40,40,40);font-family:helvetica, arial, sans-serif;]firmware 4.2.2.2[/color]) and I've run into a problem that SD card writes would interfere with the incoming serial messages. When it happens (once per ~20 incoming messages), the first byte of the incoming message is received, but the rest is lost. It feels like that when SD card write takes place, the interrupt service is disabled, and therefore after the first byte of the incoming serial message is put into the register and an interrupt generated, this interrupt is not serviced and the subsequent serial bytes are thrown away instead of copied to the register. After the SD card write completes, the MCU then services the interrupt and reads that first serial byte. If this conjecture is truly the case, then this is a bug that merits investigation. We would like to use Netduino Plus 2 in out products but would seriously reconsider if this is truly a bug and it can't get resolved.
To reproduce this problem in simpler code, I wrote a very short program that will demonstrate this problem. A peripheral device is connected to the NP+2 and generates one fixed size (9 bytes) serial message once per ~0.5 second. I have a separate USB2Serial device connected to a laptop to sniff the serial messages to verify the messages generated are correct (and they are).
The code is as follows:
using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using System.IO;using System.IO.Ports;namespace SDandUART // demonstrates the sd card interfering with serial port incoming message{ public class Program { public static SerialPort serial; public static void Main() { serial = new SerialPort(SerialPorts.COM2, 115200, Parity.None, 8, StopBits.One); serial.Open(); // open the serial-port, so we can send & receive data int i = 0; while (true) { // every 40 iterations, write something to the sd card if (i % 40 == 0) write_status_to_sdcard(); if (i % 5 == 0) write_serial(); Thread.Sleep(50); if (serial.BytesToRead > 0) { Thread.Sleep(5); int n = serial.BytesToRead; byte [] buffer = new byte [n]; int m = serial.Read(buffer, 0, n); string message = ""; for (int j = 0; j < m; j++) { message += buffer[j].ToString("x2") + " "; } Debug.Print("received " + m + " bytes: 0x" + message); } i++; } } public static void write_status_to_sdcard() { String status = ""; FileStream filestream2 = null; StreamWriter streamWriter = null; DateTime write_begin = DateTime.Now; try { status = DateTime.Now.ToString(); filestream2 = new FileStream(@"SDfile.txt", FileMode.Create, FileAccess.Write, FileShare.None); streamWriter = new StreamWriter(filestream2); streamWriter.WriteLine(status); } catch (Exception ex) { Debug.Print("Exeption Write file.txt : " + ex.Message); } finally { if (streamWriter != null) streamWriter.Dispose(); if (filestream2 != null) filestream2.Dispose(); } } public static void write_serial() { byte[] s = new byte[] { 0x5A, 0xA5, 0x05, 0x82, 0x00, 0x33, 0x00, 0x01 }; serial.Write(s, 0, s.Length); serial.Flush(); } }}
The error log is as follows (3 serial messages were truncated at the first byte). The last byte of each serial message is a simple counter that counts from 0 to 2. So it is obvious that the lost messages were with counter 0, 0 and 1 respectively. This also verified that no serial messages are duplicated; they are indeed truncated.
The thread '<No Name>' (0x2) has exited with code 0 (0x0).received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 1 bytes: 0x5A received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 1 bytes: 0x5A received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 1 bytes: 0x5A received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01 received 9 bytes: 0x5A A5 06 83 00 03 01 00 02 received 9 bytes: 0x5A A5 06 83 00 03 01 00 00 received 9 bytes: 0x5A A5 06 83 00 03 01 00 01
When I change the following line
if (i % 40 == 0) write_status_to_sdcard();
to
if (i % 40 == 40) write_status_to_sdcard();
to disable the sd card writes, then the above serial message errors would never happen.