Beijer Electronics (formerly QSI Corporation)

Manufacturer of Mobile Data and Human Machine Interface Terminals.
It is currently Mon Jun 24, 2019 2:47 pm

All times are UTC - 7 hours

Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Tue Jun 20, 2006 2:55 pm 
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
One of the most frequently asked questions involves the processing of serial events. Many people are familiar with the DataReceived event of the basic serial object (or for the more adventurous, the MSG_COMM_RECEIVE message), and know simply that it works, but how this event gets fired is somewhat mysterious.

To begin with, the DataReceied event of the BasicSerial object is a trivial wrapper for the firmware level MSG_COMM_RECEIVED. When the BasicSerial object receives a MSG_COMM_RECEIVED, it generates the DataReceived event. This leads to the question: What is a MSG_COMM_RECEIVED? How does the BasicSerial object get it? And when is it fired? It may be helpful to briefly review Chapter 3 of the Qlarity Programmer's Reference for an overview of Qlarity messages which is beyond the scope of this FAQ.

Whenever serial data is received by the Qlarity terminal on a serial port, that data is removed from the terminal's UART and placed in a memory buffer. At the appropriate time (exactly what the "appropriate" time is will be discussed later), the data is removed from this buffer and added to the Qlarity terminal's message queue. When the message reaches the front of this queue it is dispatched to any objects which have requested the data from this serial port.

The BasicSerial object informs the Qlarity terminal's firmware at startup and whenever its settings are changed that it is interested in serial data on the port specified by its comport property. This causes the firmware to route any MSG_COMM_RECEIVED messages to the BasicSerial object which in turn fires DataReceived events. A couple of points of interest here: Any object that wishes to receive a MSG_COMM_RECEIVE message must be enabled. This is why if you set the enabled property of the BasicSerial object to false, or if you place the BasicSerial object on a screen which is disabled, it will not receive any data. It is also possible for multiple objects to listen on a signle serial port if they are designed with this in mind. (The BasicSerial object is NOT designed with this in mind and will not share the serial port).

Finally, when does the MSG_COMM_RECEIVE get generated by the firmware? Remember that incoming serial data is placed in a memory buffer. Whenever that buffer fills up or a specified period of time elapses with no new data arriving, then the firmware generates a MSG_COMM_RECEIVE. Conceptually it is as if, for each byte that arrives on the serial port, the firmware places it in a buffer. If the buffer is full the firmware generates the MSG_COMM_RECEIVE, otherwise the firmware starts a timer. If that timer elapses before any more data arrives, then the MSG_COMM_RECEIVE is generated. (In practice the firmware does things more efficiently that this, but it is a good model for understanding how the serial subsystem works). By default the "buffer" we have talked about is 32 bytes, and the "timer" is about 200 ms. You can control the size of the buffer by calling SetSerialRecvSize and the timer by calling SetSerialTimeout. The BasicSerial object calls SetSerialTimeout for you and specifies the minimum possible time (< 20 ms).

A word of caution here: Do not attempt to use SetSerialRecvSize and SetSerialTimeout to force the firmware "packetize" your serial data for you. This is very tempting as it seems like these function would help you break up the data into exactly the "chunks" your application wants. However these parameters are suggestions to the firmware and the firmware may not always be able to honor them. They are intended for advanced developers who want to fine tune their parsing code and write optimal code for the common parsing case. I include this warning after years of working with people who have attempted to use those functions as their primary means of message parsing and invariably they don't work 100% of the time as serial bytes are occasionally lost or garbled or the remote device decides to send two messages consecutively with no delay or other problems.

The BasicSerial object is well aware of this limitation and provides a buffer property for your use. Most well written BasicSerial DataReceived event handlers begins as follows:


func DataReceived(data[] as byte)

    'Local Variable declarations here


    buffer := buffer + data


    'Parse buffer for a complete message

    'Once a message has been found, remove it from buffer

    'Check to see if we have more than one message in the buffer


For an example of how to use the BasicSerial object to parse simple serial messages, select Help -> Sample Workspaces. In the help window that appears, select Samples -> Communications -> parse_delimited_ascii_packet.


Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 7 hours

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group