Hi, I have a rather interesting problem at my hands now. I have an application which runs perfectly fine when I run from visual studio which means:
Open Visual Studio, Select Project, Hit F5
After starting application that way, even if I stop debugging and close visual studio my application continues running. But if I plug out the usb cable and plug it back in it hangs at a specific point, which is reading from a buffer that holds the data from the serial port. I am logging everything happening in a SD Card so that I know my application hangs at the line gpsStr = gps.GetGPSsentence(“$GPGGA”); I can’t upload the whole project to public access due to some privacy issues(its for a competition, after the competition I will gladly upload the project here to help people that might have the same issue.) but I can send it over personally if needed.
I am using 2 COMs, COM3 for gps and COM2 for a wireless module. The code for gps part is down here:
GPS Class
class GPS_NMEA
{
public static SerialPort UART;
private SerialBuffer sbuffer;
public GPS_NMEA(String Com, Int32 Baud)
{
UART = new SerialPort(Com, 9600);
sbuffer = new SerialBuffer(1024);
UART.DataReceived += new SerialDataReceivedEventHandler(UART_DataReceived);
}
public int GPSOpen()
{
UART.Open();
return 0;
}
void UART_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
sbuffer.LoadSerial(UART);
}
public void PrintGPSsentence()
{
Debug.Print(sbuffer.ReadLine());
}
public string GetGPSsentence(string type)
{
try
{
string temp;
// int dolarindex;
int tayp;
do
{
temp = sbuffer.ReadLine();
Thread.Sleep(10);
} while ((temp.IndexOf(type) < 0));
Thread.Sleep(10);
tayp = temp.IndexOf(type);
sbuffer.Read(sbuffer.DataSize);
// dolarindex = temp.IndexOf('$');
if ((temp.IndexOf(type) < 0))
{
return "$GPGGA,211449.891,4106.0406,N,02901.3695,E,1,03,8.5,-39.5,M,39.5,M,,0000*46";
}
return temp;
}
catch (Exception)
{
return "$GPGGA,211449.891,4106.0406,N,02901.3695,E,1,03,8.5,-39.5,M,39.5,M,,0000*46";
}
}
}
SerialBuffer: This one is derived from this link, but I changed a lot in it:
http://code.tinyclr.com/project/130/serialbuffer-simple-fast-way-to-read-serial-data/
public class SerialBuffer
{
private System.Text.Decoder decoder = System.Text.UTF8Encoding.UTF8.GetDecoder();
private byte[] buffer;
private int startIndex = 0;
private int endIndex = 0;
private char[] charBuffer;
public SerialBuffer(int initialSize)
{
buffer = new byte[initialSize];
charBuffer = new char[256];
}
public void LoadSerial(SerialPort port)
{
int bytesToRead = port.BytesToRead;
if (buffer.Length < endIndex + bytesToRead) // do we have enough buffer to hold this read?
{
// if not, look and see if we have enough free space at the front
if (buffer.Length - DataSize >= bytesToRead)
{
ShiftBuffer();
}
else
{
// not enough room, we'll have to make a bigger
ExpandBuffer(DataSize + bytesToRead);
}
}
port.Read(buffer, endIndex, bytesToRead); //out of range yedi
endIndex += bytesToRead;
}
private void ShiftBuffer()
{
// move the data to the left, reclaiming space from the data already read out
Array.Copy(buffer, startIndex, buffer, 0, DataSize);
endIndex = DataSize;
startIndex = 0;
}
private void ExpandBuffer(int newSize)
{
byte[] newBuffer = new byte[newSize];
Array.Copy(buffer, startIndex, newBuffer, 0, DataSize);
buffer = newBuffer;
endIndex = DataSize;
startIndex = 0;
}
public byte[] Buffer
{
get
{
return buffer;
}
}
public int DataSize
{
get
{
return endIndex - startIndex;
}
}
public string ReadLine()
{
try
{
lock (buffer)
{
int lineStartPos;
do
{
lineStartPos = Array.IndexOf(buffer, '$', startIndex);
}
while (lineStartPos < 0);
{
int lineEndPos;
do
{
lineEndPos = Array.IndexOf(buffer, '\n', lineStartPos);
} while (lineEndPos < 0);
int lineLength = lineEndPos - lineStartPos;
if (charBuffer.Length < lineLength) // do we have enough space in our char buffer?
{
charBuffer = new char[lineLength];
}
int bytesUsed, charsUsed;
bool completed;
decoder.Convert(buffer, lineStartPos, lineLength, charBuffer, 0, lineLength, true, out bytesUsed, out charsUsed, out completed);
string line = new string(charBuffer, 0, lineLength);
startIndex = lineEndPos + 1;
return line;
}
}
}
catch (Exception)
{
return "$GPGGA,211449.891,4106.0406,N,02901.3695,E,1,03,8.5,-39.5,M,39.5,M,,0000*46";
}
}
public byte[] Read(int length)
{
lock (buffer)
{
int lineEndPos = startIndex + length;
int oldStartIndex = startIndex;
if (buffer.Length > 0)
{
int lineLength = length;
Byte[] returnBuffer = new Byte[length];
if (charBuffer.Length < lineLength)
{
charBuffer = new char[lineLength];
}
startIndex = lineEndPos; //+1;
Array.Copy(buffer, oldStartIndex, returnBuffer, 0, length);
return returnBuffer;
}
else
{
return null;
}
}
}
}
To add, I get messages like this from debug window when my applications is running:
Type 0F (STRING ): 372 bytes
Type 11 (CLASS ): 3024 bytes
Type 12 (VALUETYPE ): 96 bytes
Type 13 (SZARRAY ): 4944 bytes
Type 15 (FREEBLOCK ): 26820 bytes
Type 17 (ASSEMBLY ): 12720 bytes
Type 18 (WEAKCLASS ): 48 bytes
Type 19 (REFLECTION ): 24 bytes
Type 1B (DELEGATE_HEAD ): 288 bytes
Type 1D (OBJECT_TO_EVENT ): 192 bytes
Type 1E (BINARY_BLOB_HEAD ): 11544 bytes
Type 1F (THREAD ): 1152 bytes
Type 20 (SUBTHREAD ): 144 bytes
Type 21 (STACK_FRAME ): 1332 bytes
Type 27 (FINALIZER_HEAD ): 312 bytes
Type 31 (IO_PORT ): 288 bytes
Type 34 (APPDOMAIN_HEAD ): 72 bytes
Type 36 (APPDOMAIN_ASSEMBLY ): 1008 bytes
Failed allocation for 268 blocks, 3216 bytes
I don’t know what that means but the word Failed made me suspect :).
+
I added try-catches with hopes to solve the problem, normally they weren’t there, and I run the application for hours without any problems or exceptions in debug mode.
Thanks for all your help in advance.