modelica-3rdparty/Modelica_DeviceDrivers

A spurious byte sent at the end of simulation

max-privato opened this issue · 6 comments

Consider the below model IntU16SendOnly.mo:
IntU16SendOnly.mo.txt

It sends a few instances of decimal 10 over a serial connection.
Its hexadecimal representation, with the byte order of Modelica Device Drivers (little endian) is 0x0a 0x00.
Below the screenshot of what is received by RealTerm:
image
As you can see, at the end of the sequence there is a spurious 0x00 byte.

This is not totally harmless: if we let RealTerm (or other receiving software) interpret the sequences as u16 integers, there will be a misalignment of bytes, and therefore, if we launch the exe from IntU16SendOnly.mo several times in sequence, the received interpreted numbers will toggle between 10=0x000a and 2516=0x0a00.

Strange. Unfortunately, I don't understand the Windows serial code very well (was contributed by others). If I look into the destructor, there is code which sends a "0" byte (MDD_serialPortSend(p_serial, &c, 1);) before closing the handle:

DllExport void MDD_serialPortDestructor(void * p_serial) {
    MDDSerialPort * serial = (MDDSerialPort *) p_serial;
    if (serial) {
        char c = 0;
        serial->receiving = 0;
        EscapeCommFunction(serial->hComm, CLRDTR);
        PurgeComm(serial->hComm, PURGE_TXABORT | PURGE_TXCLEAR);
        PurgeComm(serial->hComm, PURGE_RXABORT | PURGE_RXCLEAR);
        MDD_serialPortSend(p_serial, &c, 1);
        /*
             ... 
        */
        CloseHandle(serial->hComm);
        free(serial);
    }
}

We don't have that in the Linux version. Would be good to have somebody comment who knows about serial programming in Windows why this is done.

I would like to make tests on my PC, just commenting out the row
MDD_serialPortSend(p_serial, &c, 1);

Is there a way for me to do this?
I suppose I should create a new dll (I don't know which dll and how to do: which compiler, what options, etc.).

Or, in case for you @bernhard-thiele is straightforward, can you create such dll and make it available to me for testing?
Thanks

@max-privato You can simply comment out the line in

and do your test with OpenModelica or Dymola. Both simply include the complete C code in MDDSerialPort.h (just check that the model is really retranslated and not only resimulated with an already existing binary). For most devices it is not needed to build a DLL, since respective external C code is directly included (exception: SimulationX uses DLLs for all devices).

Thanks a lot!
I commented out that row, and got the expected result!.
This solves my issue.
I don't close this ticket yet, because, I suppose, we should wait for someone to say what the rationale beyond row 318 of MDDSerislPort.h is, and whether it should be deleted for everyone (I mean, for the official library).

Thanks again.

tbeu commented

I took it from line 176 of com_port.cpp (of com_port_Rx_Thread.zip (login required)) when I implemented it in 7717f0c almost 45 months ago. I have to admit that I do not know the purpose behind that code.

/////////////////////////////////////////////////////////////////////////
BOOL CloseComPort( void )
{
    // ...
    char c = 0;
    // ...
    WriteComPort( &c, 1 );  // Event to wake RX thread
    // ...
}

Thanks, since @max-privato tested it and it seems to work fine without that line I'd say we just take it out. I'll do a commit soon.