Serial port lockups with FB1.01.0-win32

For issues with communication ports, protocols, etc.
Post Reply
ThisPlaceHere
Posts: 9
Joined: Dec 19, 2011 19:52
Location: Wisconsin

Serial port lockups with FB1.01.0-win32

Post by ThisPlaceHere »

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.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Re: Serial port lockups with FB1.01.0-win32

Post by phishguy »

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


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
ThisPlaceHere
Posts: 9
Joined: Dec 19, 2011 19:52
Location: Wisconsin

Re: Serial port lockups with FB1.01.0-win32

Post by ThisPlaceHere »

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.

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
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Re: Serial port lockups with FB1.01.0-win32

Post by phishguy »

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.
abece
Posts: 6
Joined: Mar 17, 2010 18:25

Re: Serial port lockups with FB1.01.0-win32

Post by abece »

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.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Re: Serial port lockups with FB1.01.0-win32

Post by phishguy »

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
abece
Posts: 6
Joined: Mar 17, 2010 18:25

Re: Serial port lockups with FB1.01.0-win32

Post by abece »

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:

Code: Select all

Dim c as ubyte
Get #1,,c 'in place of the INPUT function.
Sample = chr(c)


fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Serial port lockups with FB1.01.0-win32

Post by fxm »

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.

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.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Serial port lockups with FB1.01.0-win32

Post by dkl »

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
fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Serial port lockups with FB1.01.0-win32

Post by fxm »

Current fbc version (1.02.0) available at:
http://users.freebasic-portal.de/stw/builds/
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Re: Serial port lockups with FB1.01.0-win32

Post by phishguy »

I just tried FBC 1.02.0. The problem appears to be fixed.
ThisPlaceHere
Posts: 9
Joined: Dec 19, 2011 19:52
Location: Wisconsin

Re: Serial port lockups with FB1.01.0-win32

Post by ThisPlaceHere »

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?)
Post Reply