As far as reading it goes, things are going pretty well.. I still have yet to
write to the display.. I can't get any of my attempts to send data to it to be
successful at all.. I get "control transfer to usb device failed!"
Thanks for the advice on a thread safe queue!
For the moment I've been trying to do the math inside thread reading the usb
device... it's pretty simple, and that allows me to read the totals at any
time.. but I can see what you mean that if I just read the device and dump
everything into maybe some kind of ring buffer without bothering to try to
process it at all, and increment the buffer position then it could be ready to
read again even faster. I could have my other slow process crunch the buffer.
I have two of these devices, one is wireless, the other has a USB cable
attached to it.. they both work a little differently.. the wireless one only
responds to my interrupt read when some data has been generated... the wired
version always responds to my request whether any data has been generated or
not. For that one I would have to do a compare on the data to see if anything
changed before adding to the buffer otherwise the buffer would always be
overrun.
Still I can't image my math is taking very long.. here is what I am doing:
Read device
If wheel moved then add wheel counts to appropriate variable then read
device
Else
Update other variables if they changed then read device
So when the wheel is moving I have very few instructions between reads.. I
don't bother checking for buttons or anything else.. I just keep accumulating
the total, and that's all I care about, and then I read again.. I only bother
with the buttons if the wheel didn't move.
One thing I'm really not sure how to handle with threads is this.... ok so I
have my main fast read thread going in the tightest loop possible... but now I
want to write something to the display (assuming I ever figure that out and
don't just put a sticker over the display and look at the screen instead :D )
It seems I would have to stop reading to get a chance to write something.. I
did a little test and I can do a suspend(Thread_ID) and resume(Thread_ID) but
what if it's in the middle of a read.. but only got 6 of the 8 bytes when I do
the suspend?? Now I am not really ready to write..... so what method can I use
to do a suspend_thread_just_before_the_next_read_happens() ? so that when the
thread is suspended, the read is completed and the buffer updated.. etc.. and
the USB system and libusb are all ready for me to send my write commands?
Resuming would be no problem.. because it was suspended at the correct
position.. I can just resume when I am done with the write and everything
should be fine.
I also still am hoping to find a method of making the device wait for me to
read it... even with threads in my program, the operating system could go off
and do something that takes all the processor time for a second and I would
just not know about events that happened during that time.
James
-----Original Message-----
From: fpc-pascal <[email protected]> On Behalf Of Stefan
V. Pantazi
Sent: Sunday, August 18, 2019 3:12 PM
To: [email protected]
Subject: Re: [fpc-pascal] USB Human Interface Devices
James,
From the looks of it you made good progress reading the hardware and using a
dedicated thread for it. Congrats! Seems you're in the thick of it now ready to
get the minute details sorted out.
Anyway, just a heads up that concurrent programming (threads, synchronization,
etc) has many pitfalls.
My armchair guess is that your program is just not reading fast enough to keep
up with the rate of data that the hardware is generated. Having time sensitive
code in a separate thread is a good idea but you should also store the report
data in an adequately sized and thread safe data structure such as a
thread-safe list/queue. FreePascal has something you could use
(https://www.freepascal.org/docs-html/rtl/classes/tthreadlist.html) and
although dynamically allocated, it may be fast enough for your purposes.
Thread safety is crucial to avoid multiple threads overwriting the data
structures they share. The way I see it, your timing sensitive hardware reading
thread would fill up the queue and then, every so often, your main thread would
consume the data from it. You have to also imagine mechanisms to check that one
can keep up with the other and signal errors when that is not the case.
Hope this helps, and good luck!
_______________________________________________
fpc-pascal maillist - [email protected]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal