Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Windows COM access delays?

Status
Not open for further replies.

Styx

Active Member
I have a project where I am reading and writing to the COM's port
All was going well, got a nice GUI showing the status of a FPGA's internal registers as well as being able to modify them.

We had an idea to provide a logging function so that we could capture a load of data and basically plot it.

Sounds good... Problem is we can only display reasonably waveforms of around 30Hz. Concidering we were hoping for around 500Hz...

I have the baud set at 115200 and if we probe at the pins data does come in at around that rate, but the next read request there is a 20ms delay...

effectively the program goes

read address
read address
...

Since I am coding via the Windows API to access the COM's port does anyone know of any extra overhead that windows imposes? (the data goes at the correct baud, its just the time between packets)


I am tempted to boot a linux CD to give it a try (with code modifications of course)
 
That could be the computer doing housekeeping, memory refresh etc. I run stepper motors from LPT1 with DOS 5 and windows and can hear rhythmic pauses. You can inhibit interrupts but only for short periods.
 
Its not clear, is the problem sending data from the PC or is it sending data from the FPGA ?

Is there any flow control being used ?
Is your app multithreaded ? Are you doing blocking I/O ?

Windows is quite capable of doing high speed serial comms, but it's a bit of a programming minefield.
 
StopGo said:
Its not clear, is the problem sending data from the PC or is it sending data from the FPGA ?
The problem is the PC-side

StopGo said:
Is there any flow control being used ?
if you mean the RTS/CTR flags then sort of, 1/2 way through setting those flags at the right times

StopGo said:
Is your app multithreaded ? Are you doing blocking I/O ?
in as far as there is a COM thread that services the COMS and populates a structure and there is a GUI thread that reads that struct to populate the txt boxes

Windows is quite capable of doing high speed serial comms, but it's a bit of a programming minefield.
Good to known its just getting it to do it
 
Nigel Goodwin said:
You mention 500Hz, does this mean you're only trying to transfer 500 samples per second? - 5000 baud.

no our datapackets are 7bytes

1st == control (address,...)
next 4 are data
6th is checksum of bytes 1 & 2
7th is checksum of bytes 3-5

at the moment if I issue the command to read TIME and SIN I get sent back 14bytes

I continually request the "memory map" and keep getting back 14bytes which I then breakdown and append to an array.

When looking at the timesteps between samples it is 20ms which really limits us to ~25Hz
500Hz would be nice but we really need ~200Hz for it to start being useful


We have scope to read back 7 channels (ie 56bytes for one timestep) obviously this would need to take a hit on the time between samples
 
Right, so you're requesting the data is sent, and one packet at a time, not just sending continuous data?. Obviously this is slowing things down greatly compared to continuous data being sent.

Windows isn't a real time OS, nothing like it, and Windows processes have far higher priority than your programs do!.

Why two checksums? - it seems an extra byte for very little reason?.
 
well the only reason why we were requesting on-packet basis was simply that the FPGA is well going to be the fastest componenet in this setup and even if it just popped data onto the port every 1ms there could of been the risk that the buffer filled up so when I then emptied it there would of been a large gap in between packets.

I have been looking around and it does seem that once an I/O occurs (ie when windows allows it) it kind of switches to its other tasks before allowing another burst.
Having a massive stream of data would be better.
We are looking into implementing the FPGA buffering all the data and then it gets streamed to me when I want it.

as to the double checksum, this was the FPGA's blokes idea. This is for a controller-board for a motor-driver and on the last project we had some serious COM's issues, he is just being overly caucious. with one checksum there is a 1 in 255 chance that a corrupted message gets through this way its greatly improved.

if a packet gets interupted that isn't a problem BUT if a register gets updated with something rediculous (say very high Kp) then its not worth the risk


thanks anyway. I might actually look into booting a custom Linux LiveCD that I am 1/2 way through. By killing off nearly all the services should be able to improve latancy
 
this is interesting. i just wrote small VB program to test it out. no matter what I do, new send can be issued only after 10ms delay. this is regardless of amount of data being sent and baud rate. if i send more data but trigger just one send message, stream of data is continuous...
 
Ok when I don't return control to system (just pump out serial port 7-byte long messages) everything else on PC locks up until this loop is finished.
It does put 10000 sends out in 6 seconds on 115.2kbps meaning one send every 0.6ms or full utilization of port speed (10000*7byte*10bit/115200=6.076 seconds).
VB has built in timer function which can be set to 1ms but in reality it's still the mentioned 10ms. I didn't try using interrupts (never tried them on Windoze till now)...

--- EDIT ----

I don't use linux actively but I remember reading somewhere than in latest kernels Linux tasks are scheduled on 10ms tick (it used to be 1ms).
 
Last edited:
panic mode said:
--- EDIT ----

I don't use linux actively but I remember reading somewhere than in latest kernels Linux tasks are scheduled on 10ms tick (it used to be 1ms).

I think by default they did drop the tick, but at compile-time (don't think it is exported to /proc as RW) it can be set to 100Hz,250Hz or 1000Hz.
it is recomended that for desktops that it is set to 1000Hz


Well the only way round this for me I think is make use of the buffer on the windows side it is ~4000bytes which should be big enough for some decent resolution
 
I think windows scheduler ticks at 10ms yes.

Without knowing every detail of your requirements it is hard to designing a comms system to fit, but I think you have got several good leads already.

Quick question.. have you set your comms thread priority to Realtime ?

Make the comms thread high priority (priority realtime). This should cut the task switch in time to it's absolute minimum, but bear in mind that if it does not yield it's timeslice it could freeze up your PC well and good.

Do as little else as possible in the comms thread.

Use ample buffering. The size of the windows receive buffer can be adjusted with a function call. (can't remember the name sorry don't have Win32.hlp on this PC)

It should be possible to send a continuous stream of data from your FPGA and have windows receive it all at 115200 baud, set up the read (call read first), then send the request for data to the FPGA. It might help to use a different TX thread for this, or you would have to use overlapped I/O.
Windows will look after things from then, you just need to check for framing or overrun errors at the end.

Thinking aloud here, the windows buffer should keep buffering characters for you while you setup the next read command. Come to think of it.. the windows comms buffer probably does not need to be huge, just big enough to buffer whatever comes in while your task is faffing about setting up reads etc..
 
Last edited:
StopGo
I did look into upping the priorty of the COMM's process, realy problems occured (as you suspected)

We ended up using the Windows buffer, but then we got greedy, really greedy
4000bytes really isn't enough

the FPGA instanciated a 8Mbit RAM as a FIFO and when the read is kicked off it dumps into me at the maximum baud as much as it can (until it gets a buffer-full signal), it then starts filling its buffer
meanwhile (within the 10ms windows tick) I just read out as much data is in the buffer and just concatinate into a long string (as another buffer, for post-proccessing later)
FPGA keeps dumping into the PC and I keep reading out until either
1) teh total number of requested packets has been recieved
2) the FPGA's FIFO wraps around (to much data requested) at which point it just pads out the final packages with the same message

I am looking into building a Gentoo-based LiveCD with the tick at 1ms, that will improve our maximum bytes alot (atm that stands at ~500kbytes)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top