Author Topic: fnRead() ignoring line feed, but prepends on next message  (Read 8751 times)

Offline alager

  • Jr. Member
  • **
  • Posts: 92
    • View Profile
fnRead() ignoring line feed, but prepends on next message
« on: May 08, 2009, 08:15:14 PM »
The messages coming from my interface hardware on uart0 always (for now) end with <CR><LF>
When a message is sent:
mess1<CR><LF>
fnRead read gives a length of 5 and will read the 5 characters

But the second message:
mess2<CR><LF>
the buffer 'ucInputMessage' shows:
Code: [Select]
0x0a,m,e,s,s,2
The <LF> from the first message is leftover and is now at the start of message two.
My message terminator is set to '\r' aka <CR>.

How can I get this leftover 0x0a to be read during the initial message, so the pointers are in the correct spots?
Here is the code section from application.c where I'm running into this issue:
Code: [Select]
#ifdef TEST_MSG_CNT_MODE
    while (fnMsgs(SerialPortID) != 0) {
        unsigned char ucLength;
        fnRead( SerialPortID, &ucLength, 1);                     // get message length
        Length = fnRead( SerialPortID, ucInputMessage, ucLength);

Thanks,
Aaron

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: fnRead() ignoring line feed, but prepends on next message
« Reply #1 on: May 08, 2009, 10:22:34 PM »
Hi Aaron

I think that this behavior is in fact normal when the terminal emulator is sending <CR> + <LF> and the message mode is set up to respond to <CR>

The first reception is "mess1<CR><LF>" but the driver will recognise the <CR> as the terminator. This means that the message is 5 bytes in length, "mess1" - the <CR> is dropped since it is the terminator (and known to have also arrived).

At this moment in time <LF> may not in fact have arrived (still in transmission) or is in the buffer, but considered a part of a following message.

Now the second message arrives "mess2<CR><LF>" whereby the <CR> is again recognised as the terminator.
The message will now be 6 bytes long, consisting of "<LF>mess2", and the new <LF> is either in the process of being received or could already be in the buffer, again considered as the start of a following message.

What you can however do (assuming that you will always receive <CR><LF> is change the terminating character (passed when the UART is opened) from <CR> (\r) to <LF>(\n). What happens now is that each of the messages will terminate on the <LF> and each be 6 bytes long "messx<CR>". The <CR> can then be ignored.

The complication may however be that you don't know whether the terminal will use <CR> or <CR><LF> and so the second setting wouldn't work at all if the <LF> were deactivated!!!

I would thus (assuming you can't be sure) do the following, with terminator left as \r:

    while (fnMsgs(SerialPortID) != 0) {
        unsigned char ucLength;
        fnRead( SerialPortID, &ucLength, 1);                     // get message length
        Length = fnRead( SerialPortID, ucInputMessage, ucLength);
        if (ucInputMessage[0] == '\n') {
                fnEchoInput(&ucInputMessage[1], (ucLength-1));
        }
        else {
                fnEchoInput(ucInputMessage, ucLength);
        }


The fact is that the handling of an unsure <LF> has to be performed somewhere, and this is probably a practical solution.

Regards

Mark





Offline alager

  • Jr. Member
  • **
  • Posts: 92
    • View Profile
Re: fnRead() ignoring line feed, but prepends on next message
« Reply #2 on: May 08, 2009, 10:40:53 PM »
You are right, I can not rely on the order nor the existence of the '\r\n' sequence.
I could get all of these:
\r
\r\n
\n\r
I was hoping that there would be some uber elegant solution, but that code works too.

Thanks,
Aaron