Serial Input on MOD5270

Discussion to talk about software related topics only.
Post Reply
BMillikan
Posts: 14
Joined: Thu Dec 23, 2010 7:56 am

Serial Input on MOD5270

Post by BMillikan »

I am trying to implement a serial interface on a MOD5270 development board. But it seems that I can only read 1 character from the port at a time. Why is this? I am doing a select() on the port followed by a read(). Here is the code snippet...

while (1)
{
FD_ZERO( &read_fds );
FD_SET( fdserial, &read_fds );

FD_ZERO( &error_fds );
FD_SET( fdserial, &error_fds );

if ( select( FD_SETSIZE,
&read_fds,
( fd_set * ) 0,
( fd_set * ) 0,
20 ) )
{

if ( FD_ISSET( fdserial, &read_fds ) )
{

OSLock();

n = read(fdserial, &buffer[0], BUFFER_SIZE);

OSUnlock();
}
}

putleds(toggle);
toggle ^= 1;
}
User avatar
Chris Ruff
Posts: 222
Joined: Thu Apr 24, 2008 4:09 pm
Location: topsail island, nc
Contact:

Re: Serial Input on MOD5270

Post by Chris Ruff »

Why lock the OS? I never do this. Have you seen this done somewhere? The OS needs to continue working for the file descriptors to be processed by other (netburner core) threads

Chris
Real Programmers don't comment their code. If it was hard to write, it should be hard to understand
v8dave
Posts: 333
Joined: Thu Dec 31, 2009 8:31 pm

Re: Serial Input on MOD5270

Post by v8dave »

I don't see any OSTimeDly in your code to yield to other tasks (assuming more than 1) either so it is possible that you are just running much faster through your loop than the data is available. What is your baud rate for the serial port? I am not familiar with SELECT as I have not used this.

Chris is also right, you don't need the locks on the OS during reading as long as only one task at a time is reading the port which is what you want anyway.

Try putting in a delay as a test, something like OSTimeDly(TICKS_PER_SECOND) which will wait 1 second before it continues and see if you read more data this time. Put this before the read() call.

It all depends on what your data is, but you may have to delay whilst data arrives. I use a timeout based on a number of character lengths for some projects (MODBUS etc) and others are based on recieving certain characters to delimit the reception (carriage return is common)

Dave...
User avatar
Chris Ruff
Posts: 222
Joined: Thu Apr 24, 2008 4:09 pm
Location: topsail island, nc
Contact:

Re: Serial Input on MOD5270

Post by Chris Ruff »

select() is a blocking call. It is not necessary to provide an OSTimeDly() in a task that is blocking on select();

The only time you need OSTimeDly() is in a task that is of your own construction that does not block. If you had a task:

taskBuh(iforget)
{
while(1)
{
for(int i=0;i<10;i++)
{
printf("I own the world!!!!\n");
}
}
}


This task will stop everything in its tracks. IT would need an


OSTimeDly()

before the closing brace
to allow anything else to run
Chris
Real Programmers don't comment their code. If it was hard to write, it should be hard to understand
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: Serial Input on MOD5270

Post by Ridgeglider »

I agree with Chris: avoid the OSLock. Next, during your inits, I'd recommend closing and then re-opening the serial ports using SerialClose() and then OpenSerial(). This will ensure the serial ports are using the interrupt-based drivers instread of the default polled serial drivers. See the Serial Library chapter in C:\nburn\docs\NetBurnerRuntimeLibrary\NetBurnerRuntimeLibraries.pdf. Next, be careful with the read() call. If data is available (via the serial ISR), read() will read "at least" one char. That means your code must handle varying amounts of char input and therefore depending on what you are doing, you may not want the results of the read to always go to buffer[0] and, if so, you probaby want to be sure the buffer is not over-run by controlling the number of chars to read. See the I/O System Library chapter in the same PDF for a description of read(). I think, in your case, the combination of using the polled drivers and locking the OS pretty much ensures getting only one char at a time. If you enable the interrupt-based drivers, read() will grab all the chars the ISR has rec'd. Note that in some situations this means, if no chars are available, the system may hang until one char is available. You might want to check out ReadWithTimeout to avoid an apparent "hung" system if no char has been rec'd. Then again, in your case select() will not trip unless there is a read event (ie at least one char). Note that it is also possible to use select() with a timeout. Sometimes, detecting a pause via such a short. (1-3 tick) timeout is a good way to detect receipt of a full sentence in cases where periodic blurts of data, (say from a gps) are typical. If so, if select() times out, you probably have a full sentence ready to parse.
User avatar
pbreed
Posts: 1085
Joined: Thu Apr 24, 2008 3:58 pm

Re: Serial Input on MOD5270

Post by pbreed »

Select wakes you up on every received char, you will not see more than one char unless
you've been busy elsewhere for long enough for more than one char to arrive.
At 115200 baud each max char rate is ~11Khz, I have customers that
routinely have 200Khz repetitive interrupts. If all your doing is task switching (no real work)
the you could easily average 500K task switches a second.

The byte count passed to read are the MAX it will read not the minimum.
read will return with whatever is left in the buffer, usually just one char.


In general don't use OSLock unless you have a shared data structure
you are trying to protect. in that case its probably better to use
a OS_CRIT that way you only stop task switching when some other task needs the
data struct. If your accessing the data struct from a user written interrupt, then USER_ENTER_CRITICAL/USER_EXIT_CRITICAL is
a better choice as OSLock does not block interrupts.
Post Reply