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 <fpc-pascal-boun...@lists.freepascal.org> On Behalf Of Stefan 
V. Pantazi
Sent: Sunday, August 18, 2019 3:12 PM
To: fpc-pascal@lists.freepascal.org
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  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to