robertkjonesjr
Member
Some questions on raw port usage on a Redlion G3, specifically UDP.
I am trying to read arbitrary bytes from a UDP stream with Ethernet but I get unexpected results.
First of all, my custom message is 5 bytes long encapsulated in UDP. So when I think I need PortRead() for this to get a single byte, therefore, I need to run this five times.
1. What is OnUpdate - I put my comms() program name in here. Is this fired when there is data in the UDP receive buffer, or is it more like a PLC scan model where this runs every cycle?
2. If I constantly call my comms() routine with my PortRead() function, I expect to return a -1 every time if there is nothing in the buffer. If there is something in the buffer, then it should give me the byte of data that is there in the top of the queue. Can I assume that my data, and only my data are there, delivered as a group of 5 bytes? What if I send very fast, will it grow? What delimination exists between UDP message data from the various segments?
3. Some sleuthing around shows that the first byte returned form PortRead() is the number of bytes in the buffer. This is convenient, but unexpected because I could not find it documented. What is really happening under the hood here? I would like to see the first byte read to be number of bytes of data in buffer, then use a for() loop that many times. However, my first PortRead is constantly changing, then if it is equal to 5 I do my 5 other PortReads:
This actually works - but shouldn't (well, not to my expectations, anyway, which must be incorrect). I think the for() loop commented out should work too - that is a more flexible solution, but it doesn't. Since the first PortRead() will return weird data routinely it throws the whole thing off. Notice here I need six PortReads() to get five bytes of data.
Can anyone enhance my understanding of the raw ports capability?
Here is the documentation in the manual, for reference:
PORTREAD(PORT, PERIOD)
DESCRIPTION
Attempts to read a character from the port indicated by port. The port must be configured to use a raw driver, such as the raw serial port driver, or either of the raw TCP/IP drivers. If no data is available within the indicated time period, a value of –1 will be returned. Setting period to zero will result in any queued data being returned, but will prevent Crimson from waiting for data to arrive if none is available.
I am trying to read arbitrary bytes from a UDP stream with Ethernet but I get unexpected results.
First of all, my custom message is 5 bytes long encapsulated in UDP. So when I think I need PortRead() for this to get a single byte, therefore, I need to run this five times.
1. What is OnUpdate - I put my comms() program name in here. Is this fired when there is data in the UDP receive buffer, or is it more like a PLC scan model where this runs every cycle?
2. If I constantly call my comms() routine with my PortRead() function, I expect to return a -1 every time if there is nothing in the buffer. If there is something in the buffer, then it should give me the byte of data that is there in the top of the queue. Can I assume that my data, and only my data are there, delivered as a group of 5 bytes? What if I send very fast, will it grow? What delimination exists between UDP message data from the various segments?
3. Some sleuthing around shows that the first byte returned form PortRead() is the number of bytes in the buffer. This is convenient, but unexpected because I could not find it documented. What is really happening under the hood here? I would like to see the first byte read to be number of bytes of data in buffer, then use a for() loop that many times. However, my first PortRead is constantly changing, then if it is equal to 5 I do my 5 other PortReads:
Code:
UDP1 := PortRead(4,0);
if ( UDP1 == 5 ) {
UDPHdr[0] := UDP1;
UDPHdr[1] := PortRead(4,0);
UDPHdr[2] := PortRead(4,0);
UDPHdr[3] := PortRead(4,0);
UDPHdr[4] := PortRead(4,0);
UDPHdr[5] := PortRead(4,0);
MBdataOut := UDPHdr[5]; //move some data to resend over modbus
//for ( i = 1; i <= UDP1; i++ ) {
// UDPHdr[i] := PortRead(4,0);
//}
}
This actually works - but shouldn't (well, not to my expectations, anyway, which must be incorrect). I think the for() loop commented out should work too - that is a more flexible solution, but it doesn't. Since the first PortRead() will return weird data routinely it throws the whole thing off. Notice here I need six PortReads() to get five bytes of data.
Can anyone enhance my understanding of the raw ports capability?
Here is the documentation in the manual, for reference:
PORTREAD(PORT, PERIOD)
DESCRIPTION
Attempts to read a character from the port indicated by port. The port must be configured to use a raw driver, such as the raw serial port driver, or either of the raw TCP/IP drivers. If no data is available within the indicated time period, a value of –1 will be returned. Setting period to zero will result in any queued data being returned, but will prevent Crimson from waiting for data to arrive if none is available.