Serial port lockups with FB1.01.0-win32
-
- Posts: 9
- Joined: Dec 19, 2011 19:52
- Location: Wisconsin
Serial port lockups with FB1.01.0-win32
I spent the day trying to figure out why a program stopped working after all these years...
I made a little change, recompiled, and the program was broken. Undid my changes, recompiled, and still broken!
After much testing with small test programs (that failed), all I could see that was different was.. a latest version of the compiler since my hard disk crash a while back?
So I downloaded the previous version (0.90.1). Compiled, and just like that, everything was working perfectly.
Has anyone else encountered a serial (com port) problem with the latest compiler (1.01.0)?
The specific issue, as far as I can tell, is that after a few send and receives, my main program stops responding, even though the thread doing the serial communications continues to run! At first I thought it was a thread problem, but in testing, even a simple program (no threads) locks up tight after a few random number of sends. If I never send data, the program never locks up.
I made a little change, recompiled, and the program was broken. Undid my changes, recompiled, and still broken!
After much testing with small test programs (that failed), all I could see that was different was.. a latest version of the compiler since my hard disk crash a while back?
So I downloaded the previous version (0.90.1). Compiled, and just like that, everything was working perfectly.
Has anyone else encountered a serial (com port) problem with the latest compiler (1.01.0)?
The specific issue, as far as I can tell, is that after a few send and receives, my main program stops responding, even though the thread doing the serial communications continues to run! At first I thought it was a thread problem, but in testing, even a simple program (no threads) locks up tight after a few random number of sends. If I never send data, the program never locks up.
Re: Serial port lockups with FB1.01.0-win32
Do you have example minimal test code that fails for you. I tried the following test program with a loopback without any issues.
Win7 pro 64 bit
FB1.01.0-win32
Win7 pro 64 bit
FB1.01.0-win32
Code: Select all
dim as integer x,y
open com "com1:115200,n,8,1,cs0,cd0,ds0,rs" as #1
for x = 1 to 10000
print x,
print #1,x
input #1,y
print y
next x
print "Done"
sleep
-
- Posts: 9
- Joined: Dec 19, 2011 19:52
- Location: Wisconsin
Re: Serial port lockups with FB1.01.0-win32
Okay, I cut and pasted minimal snippets and created this test.
Connect your loopback, then whatever you type, comes right back to you.
Locks up when compiled with 1.01.0, works fine when compiled with previous versions.
Connect your loopback, then whatever you type, comes right back to you.
Locks up when compiled with 1.01.0, works fine when compiled with previous versions.
Code: Select all
DIM SHARED AS INTEGER TERMINATE
TERMINATE = 0 'WHEN THIS GOES 1, EVERYTHING STOPS.
DIM SHARED Transmit AS STRING
DIM Com_Thread As Any Ptr
SUB Com_Handler (param As Any Ptr)
DIM AS STRING Sample
open com "com6:9600,n,8,1,cs0,cd0,ds0,rs" as #1
SLEEP 20
IF ERR <> 0 THEN TERMINATE = 1
DO
Sample=""
WHILE (LOC(1) > 0)
Sample = INPUT(1, #1) 'read one character at a time
Print "Received: " & Sample
WEND
IF (Transmit <> "") THEN
PRINT #1, Transmit;
Print "Sending: " & Transmit
Transmit = ""
END IF
SLEEP 20 'release the processor
LOOP WHILE (TERMINATE = 0)
CLOSE #1
SLEEP 10
END SUB
'==================================================
'MAIN FUNCTION: WHAT YOU TYPE SENDS ON SERIAL PORT.
'WHATEVER COMES BACK ON SERIAL PRINTS TO SCREEN.
'PRESS ESC TO EXIT.
'==================================================
CLS
Com_Thread=THREADCREATE(@Com_Handler,0)
IF Com_Thread = 0 THEN TERMINATE = 1
SLEEP 50
DIM AS STRING Respond
WHILE (TERMINATE = 0)
Respond = INKEY
IF Respond <> "" THEN
IF Respond = chr$(27) THEN
TERMINATE = 1
ELSE
'MUTEXLOCK TransmitLock
Transmit = Respond
'MUTEXUNLOCK TransmitLock
END IF
END IF
SLEEP 50
WEND
THREADWAIT(Com_Thread)
Sleep 50
CLOSE
END
Re: Serial port lockups with FB1.01.0-win32
I tested on my home PC running Windows 8 64 bit this time. Indeed your program works on the older versions of FBC and locks up with 1.01.0. My example code works for any version. So, at this point it seems to be something related to the threading. I'm not sure what though.
Re: Serial port lockups with FB1.01.0-win32
I can get it to work on my system by reading in one byte at a time into a ubyte, so the threading is working. I believe it has to do with how Strings are handled pre and post 1.0.
Re: Serial port lockups with FB1.01.0-win32
I still think that it must have something to do with the thread. The following non-threaded code works without a problem. It's essentially doing the same thing.
Code: Select all
Dim As String a,b
Open Com "com3:115200,n,8,1,cs0,cd0,ds0,rs" As #1
Do
a = Inkey
If a = Chr(27) Then
Exit Do
End If
If a <> "" Then
Print "Sent : ";a,
Print #1,a;
End If
While Loc(1)
b = Input$(1,1)
Print "Received : ";b
Wend
Sleep 5,0
Loop
Print "Done"
Sleep
Re: Serial port lockups with FB1.01.0-win32
Well it's definitely getting stuck in the thread at the input function. I've never actually used it for serial input. I don't use INPUT with serial ports, rather I use GET, since I'm normally reading binary data. It seems like a weird syntax to me (file number as the second parameter, No parameter for data type or size of data type).
I saw another thread that described a difference between input$ and just input, where the first one worked with Open Com, but the second one didn't.
Anyway, I used:
I saw another thread that described a difference between input$ and just input, where the first one worked with Open Com, but the second one didn't.
Anyway, I used:
Code: Select all
Dim c as ubyte
Get #1,,c 'in place of the INPUT function.
Sample = chr(c)
Re: Serial port lockups with FB1.01.0-win32
In coming back to the initial code:
- I cannot test your program with a serial port (it is why I did not propose change until now).
- But 'Transmit' is not a simple flag as 'Terminate' (an integer) where you can probably avoid using a mutex.
- 'Transmit' is a string, and so a dynamic object which is constructed then destructed by both the thread 'Com_Handler()' and by the main loop (the main thread).
- You must mandatory put a 'Mutexlock/Mutexunlock' block around the accesses to 'Transmit' in the two threads ('Com_Handler()' and main thread).
- For safety, I added the test 'Transmit = ""' in the main loop before requesting another send.
- I cannot test your program with a serial port (it is why I did not propose change until now).
- But 'Transmit' is not a simple flag as 'Terminate' (an integer) where you can probably avoid using a mutex.
- 'Transmit' is a string, and so a dynamic object which is constructed then destructed by both the thread 'Com_Handler()' and by the main loop (the main thread).
- You must mandatory put a 'Mutexlock/Mutexunlock' block around the accesses to 'Transmit' in the two threads ('Com_Handler()' and main thread).
- For safety, I added the test 'Transmit = ""' in the main loop before requesting another send.
Code: Select all
DIM SHARED AS INTEGER TERMINATE
TERMINATE = 0 'WHEN THIS GOES 1, EVERYTHING STOPS.
DIM SHARED Transmit AS STRING
Dim Shared TransmitLock As Any Ptr
DIM Com_Thread As Any Ptr
SUB Com_Handler (param As Any Ptr)
DIM AS STRING Sample
open com "com6:9600,n,8,1,cs0,cd0,ds0,rs" as #1
SLEEP 20
IF ERR <> 0 THEN TERMINATE = 1
DO
Sample=""
WHILE (LOC(1) > 0)
Sample = INPUT(1, #1) 'read one character at a time
Print "Received: " & Sample
WEND
MUTEXLOCK TransmitLock
IF (Transmit <> "") THEN
PRINT #1, Transmit;
Print "Sending: " & Transmit
Transmit = ""
END IF
MUTEXUNLOCK TransmitLock
SLEEP 20 'release the processor
LOOP WHILE (TERMINATE = 0)
CLOSE #1
SLEEP 10
END SUB
'==================================================
'MAIN FUNCTION: WHAT YOU TYPE SENDS ON SERIAL PORT.
'WHATEVER COMES BACK ON SERIAL PRINTS TO SCREEN.
'PRESS ESC TO EXIT.
'==================================================
CLS
TransmitLock = Mutexcreate
Com_Thread=THREADCREATE(@Com_Handler,0)
IF Com_Thread = 0 THEN TERMINATE = 1
SLEEP 50
DIM AS STRING Respond
WHILE (TERMINATE = 0)
Respond = INKEY
IF Respond <> "" THEN
IF Respond = chr$(27) THEN
TERMINATE = 1
ELSE
DO
MUTEXLOCK TransmitLock
IF (Transmit = "") THEN
Transmit = Respond
MUTEXUNLOCK TransmitLock
EXIT DO
END IF
MUTEXUNLOCK TransmitLock
SLEEP 15
LOOP
END IF
END IF
SLEEP 15
WEND
THREADWAIT(Com_Thread)
MUTEXDESTROY(TransmitLock)
Sleep 50
CLOSE
END
Last edited by fxm on Mar 02, 2015 22:27, edited 1 time in total.
Re: Serial port lockups with FB1.01.0-win32
Does the same still happen with the latest development version of fbc? It sounds a lot like a regression bug in 1.00.0 that I fixed recently (threads and Input...):
http://sourceforge.net/p/fbc/code/ci/f2 ... 8965921d9/
http://forum.qbasic.at/viewtopic.php?t=8580
http://sourceforge.net/p/fbc/code/ci/f2 ... 8965921d9/
http://forum.qbasic.at/viewtopic.php?t=8580
Re: Serial port lockups with FB1.01.0-win32
Current fbc version (1.02.0) available at:
http://users.freebasic-portal.de/stw/builds/
http://users.freebasic-portal.de/stw/builds/
Re: Serial port lockups with FB1.01.0-win32
I just tried FBC 1.02.0. The problem appears to be fixed.
-
- Posts: 9
- Joined: Dec 19, 2011 19:52
- Location: Wisconsin
Re: Serial port lockups with FB1.01.0-win32
Thank you all for your input. I will give the newest compiler version a try. Sounds like this will solve the problem.
To address some of the other comments:
Get vs Input. I will read about and play around with Get, and see if it can help me out in any way.
Threads. I wrote this program several years ago to log data from certain machines in our factory. In the first year it evolved into far more than I originally intended. The program is using 4 serial ports, connected to Bluetooth adapters. The program has to talk to the Bluetooth adapters to continuously search for it's mating adapter (as machines are turned on and off throughout the week) and also talk "different languages" to the various machines once connected. Certain data is logged to files; other data calculated and sent to label printers; and other data is sent to http server variables, so that the engineers can pull up the machines on a webpage and see what is happening. The main program does the bulk of the work, while the second thread continuously loops through the open serial ports sending and receiving data, reading and storing variables for use by the main thread. The program did not start out with a thread, but it's where I ended up in trying to keep a constant flow of data while doing "all this other stuff" at the same time. Amazingly, it has worked quite well for several years.
MutexLock. Yes, I learned rather quickly about this when I started with threads. My program only uses the mutexlock when the serial thread writes (or changes) variables. I don't have any locks in the main thread. I understand why it seems they should be included... but so far everything has worked fine without. (If it ain't broke, don't rewrite it! Right? Maybe?)
To address some of the other comments:
Get vs Input. I will read about and play around with Get, and see if it can help me out in any way.
Threads. I wrote this program several years ago to log data from certain machines in our factory. In the first year it evolved into far more than I originally intended. The program is using 4 serial ports, connected to Bluetooth adapters. The program has to talk to the Bluetooth adapters to continuously search for it's mating adapter (as machines are turned on and off throughout the week) and also talk "different languages" to the various machines once connected. Certain data is logged to files; other data calculated and sent to label printers; and other data is sent to http server variables, so that the engineers can pull up the machines on a webpage and see what is happening. The main program does the bulk of the work, while the second thread continuously loops through the open serial ports sending and receiving data, reading and storing variables for use by the main thread. The program did not start out with a thread, but it's where I ended up in trying to keep a constant flow of data while doing "all this other stuff" at the same time. Amazingly, it has worked quite well for several years.
MutexLock. Yes, I learned rather quickly about this when I started with threads. My program only uses the mutexlock when the serial thread writes (or changes) variables. I don't have any locks in the main thread. I understand why it seems they should be included... but so far everything has worked fine without. (If it ain't broke, don't rewrite it! Right? Maybe?)