Fazecast / jSerialComm

Platform-independent serial port access for Java
GNU Lesser General Public License v3.0
1.34k stars 287 forks source link

How to know the getLastError codes and the location into the reference github code ? #530

Closed EmbGangsta closed 11 months ago

EmbGangsta commented 1 year ago

Hi,

I am evaluating jSerialComm on a project that was using JSSC. I am still facing the same issue after some moments with JSSC or JSerialComm : the writeBytes method seems to be unable to send data or anyway I am not receving data anymore and then com port seems to be stalled. If I restart my application open of com ports doesnt work and I have to unplug/plug the USB cable to make it working again ...

I am wondering if it's not coming from the USB driver itself ... this is a COM port emulated over USB on a PC connected to an NRF52840 board.

Anyway I was wondering when I call the getLastError() and getLastErrorLocation() methods, how to make the relationship with some existing error code table (where is it ?) and the line of code (in C or Java code ???)

For example in my problem I am facing, I am no longer able to write data with writeBytes() method and I see the error code = 121 and location is 1201.

Please advice

hedgecrw commented 1 year ago

The getLastError() and getLastErrorLocation() methods are used to retrieve the underlying cause and location of an error which might vary between different operating systems, architectures, and distributions. You would use the result of the getLastErrorLocation() call to locate the place where the native code is failing in either src/main/c/Posix/SerialPort_Posix.c or `src/main/c/Windows/SerialPort_Windows.c, depending on your OS.

Once you've identified the function causing the error, you can use the getLastError() result to look up the native error code and tie it to the function that threw the error.

Based on the error location you posted, I'm assuming you're using Windows, since the Posix source code doesn't have a line 1201. Error code 121 for this function means "ERROR_SEM_TIMEOUT" (semaphore timeout period has expired). Some quick Googling comes up with a few results (such as https://github.com/serialport/node-serialport/issues/781). Sounds like maybe it's solvable by playing with write timeouts?

EmbGangsta commented 11 months ago

Hi,

I reproduced the problem and it seems the C code on Windows side is there with getLastErrorCode = 121 (ERROR_SEM_TIMEOUT) :

Error is either on first or second test when attempt to write bytes to serial port : // Write to the serial port BOOL result; DWORD numBytesWritten = 0; if (((result = WriteFile(port->handle, writeBuffer + offset, bytesToWrite, NULL, &overlappedStruct)) == FALSE) && (GetLastError() != ERROR_IO_PENDING)) { port->errorLineNumber = LINE - 2; port->errorNumber = GetLastError(); } else if ((result = GetOverlappedResult(port->handle, &overlappedStruct, &numBytesWritten, TRUE)) == FALSE) { port->errorLineNumber = LINE - 2; port->errorNumber = GetLastError(); }

hedgecrw commented 11 months ago

If you are not using write timeouts (i.e., specifying TIMEOUT_WRITE_BLOCKING and a non-0 write timeout in setComPortTimeouts()), then this error indicates that whatever data you are trying to write is overflowing the underlying buffer in the device driver (which we don't have direct access to). In other words, you are writing more quickly than your receiving device is reading.

Two things to try:

  1. Specify a blocking write timeout so that your writeBytes() call doesn't return until the bytes have actually been written, and/or
  2. Try to write your data in smaller chunks (you might be trying to write more data than the underlying buffer can hold).
hedgecrw commented 11 months ago

I just saw this is the same user/issue as #536. Closing this thread, as the title is not related to the issue. Refer to #536 for continued discussions.