How to do unpredictable USB input
Pages: 1 2 3 4 5 6 7 8 9 10 11 12
Rick Murray (539) 13840 posts |
First call – the device has died/gone away.
You mean the DeviceFS handle for a USB device? My connection/disconnection code is untested (I’m writing it on the emulator, more comfortable, so I’ll let you know how much it blows up on real hardware ;-) ). However, here is the code to read the USB and DeviceFS handles for a USB device:
Where:
In essence, you call DeviceFS_CallDevice to call the driver with code &80000007, and the device name in R1 as well as the associated endpoint file handle in R2. It replies with some stuff, including the DeviceFS handle in R4 and the USB system handle in R5. |
Rick Murray (539) 13840 posts |
Oh, and if you are of the impression that this is an ass-backwards convoluted way to do something, I’d agree. USB is ubiquitous enough these days that the USB system really ought to be raising Service Calls for device connection/disconnection, plus, at a higher level, WimpMessages. By itself. We shouldn’t need to be looking for handles so we can watch DeviceFS to know if a USB device was disconnected… The ServiceCall can be the domain of the complicated data blocks. The WimpMessage can work on a system like the OS variables use. Well, I can hope, right? |
Colin (478) 2433 posts |
You don’t need to do you? You just need to sit on service_devicedead and wait for r3=USBxxx you don’t care when the device handle dies. It probably doesn’t send wimp messages because its not always used in the wimp. |
Rick Murray (539) 13840 posts |
I am planning to sit on DeviceDead and do a simple logic match with the device handle; for “if (this == that)” is a lot simpler / more lightweight than strcmp() calls. It’s the same call. You’re looking at R3, I’m looking at R2. |
Rick Murray (539) 13840 posts |
A driver should not be sending Wimp messages. This would probably need an additional module, called something like “USBSupport” that provides a SWI or two and also runs as a skeleton Wimp task to allow the Desktop integration (no icons, windows, etc – sort of like how VProtect appears). |
Dave Higton (1515) 3526 posts |
I don’t see why not. That would be a good level of integration. For my experiments I’m writing a module called USBNotifier. My idea is that a task can call it to request a pollword for a given device name (e.g. “USB10”) or a DeviceFS handle, or that it can pass in a pollword and a name or handle and request that the pollword be set non-zero on device removal. The first method saves the calling task from having to allocate a word of DA or RMA, but means that device removal is all the pollword can be used to signal. But it would be really neat if the USB system integrated a WIMP messaging method. |
Colin (478) 2433 posts |
I just think that that r3 is the correct way to do it – but maybe that’s because I think calldevice action codes introduced in usbdriver 0.49 (0×80000006 onwards) should never have been added. |
Colin (478) 2433 posts |
Off the top of my head :-) Register your task handle with your module – it returns the pollword. Your module can use task closed (I’m sure there’s a service call something like that) to unregister your task and free resources when the task is quit. |
Colin (478) 2433 posts |
On second thoughts the pollword needs to be supplied by your task then if your module dies it can notify your task by setting a bit in the pollword before it expires. The problem with putting information in the pollword other than setting bits for events is you could get more than 1 event happen before the task gets notified. |
nemo (145) 2546 posts |
Rant alert. No new Service Calls, please!!! Part of my motivation for writing VectorExtend was to get away from the vastly overused and misused Service Call mechanism. It’s a sorry hang-over from the BBC Micro OS and ought to have been obsoleted with RO2, never mind the optimisation fig-leaf of RO4. Given VectorExtend, there could just be a USB vector for births and deaths, so to speak, and dynamically allocated vectors for every device. Stuffing everything and its dog through Service Call really is a dreadful design. In fact it’s an abdication of design. Bah, humbug.
Yes for a notification system. And yes for something that represents those notifications as Wimp Messages when required. I’d have a little separation between those things though.
Agreed. |
nemo (145) 2546 posts |
That is the very nature of pollwords – “something has happened, ask me what”. |
Rick Murray (539) 13840 posts |
Dave:
For the same sort of reason that the Wimp should not determine its configuration by bashing out IIC calls. There needs to be a separation between the high level GUI and the low level OS1. Then we run into the problem of what is the driver supposed to do with the Wimp messages when the user is not in the Desktop? Should it just keep throwing out messages? Should it check for every notification? Should it manage a queue of messages so it can post them when the user returns to the Desktop? This means it will need to monitor the desktop activity… …you can see how it can get complicated quickly. An idea like the module you propose, fleshed out a little to be able to broadcast messages, is a viable approach. A low level driver messing with all of that non-driver stuff is… a really bad idea. nemo:
Mmm… I interpret a “vector” as something you hook in to. There may be a pile of reasons against service calls (conditions of entry and reentrancy being big ones), but it is a mechanism whereby you can be “notified” of an event having happened, as opposed to being called to handle an event. 1 Don’t get me started on the mess of co-ordinate systems in the Wimp. Logical co-ords, screen logical co-ords, absolute screen co-ords, all mashed together… |
nemo (145) 2546 posts |
With OS_Claim. Much like you “hook into” Service Calls with OS_Module… but involving much less code!
The biggest one IMO being that everyone and their dog is notified about a service call, which is mitigated but not eradicated by the “fast service call” hot fudge sauce. Plus the fact that once the OS has got around to calling your module you still have to work out which service call it was… every single time. If your code responds to a number of them (and Wimp modules have to) then that’s inefficient. Vectors are specific… but there aren’t anything like enough of them, meaning they can’t be used for some things (because of scale) and can’t be used for others (because we’ve only a few left!). So having millions of vectors is quite an improvement. :-)
You have misunderstood Vectors. They can be just as much a notification as a service call is, except it is also possible to predict and control what order handlers are called in (parametrically with VectorExtend, chronologically otherwise) and behaviour can be modified (before or after) or filtered – none of which can be done with service calls. For example, a USB system issues a notification when a device is plugged in bearing some kind of identifier. Cheap device has invalid identifier. Work-around code can recognise device by some mechanism, and so wants to correct the notification before recipients see it… If your notification system is a service call, that simply cannot be done. With vectors it can, trivially. |
Dave Higton (1515) 3526 posts |
You’d think that the DeviceFS handle given in R2 in Service_DeviceDead would be the one returned in R4 from a call to DeviceFS_CallDevice &80000007, wouldn’t you? It isn’t. The example I’ve just got is for device USB10. The DeviceFS handle returned in R4 from the call to DeviceFS_CallDevice &80000007 is &209198B4. The value passed in R2 to that call is the input pipe handle, which had the value 253. The input pipe was the first opened for that device. The value in R2 from the Service_DeviceDead call is &208A3CD4, in both cases (i.e. where R3 = 0 and where R3 points to “USB10”). |
Dave Higton (1515) 3526 posts |
It’s the value returned in R6 from DeviceFS_CallDevice &80000007. |
Rick Murray (539) 13840 posts |
The hell is R6? The Iyonix documentation says:
Is there something else, later? I looked on the Wiki and it replied "No pages contain “devicefs_calldevice”". |
Colin (478) 2433 posts |
Forget the iyonix docs |
Dave Higton (1515) 3526 posts |
I stand by my observations. The value in R2 for Service_DeviceDead when a USB device is unplugged is not the R4 value from DeviceFS_Call Device &80000007; it is the R6 value. That’s on a recent softloaded RO 5.21 on my Iyonix. I hope other people more knowledgeable can chime in to say whether it’s correct as is, or whether R4 would be correct. And if R4 would be correct, then there are lots of installations of RO out there that are faulty. I would be interested to know if the R6 value has any other uses. |
Dave Higton (1515) 3526 posts |
The later USB docs show a service call Service_USB, which has a value for “device has gone”. I may try that tonight. Its usefulness depends on how big and complex the USBServiceCall structure is and how useful its data are. |
Colin (478) 2433 posts |
When registering a device with devicefs_register, which usb does, multiple subdevices can be registered in the same call. Each subdevice is recognised by the r3 value in service_devicedead and the whole device is recognised by the r2 value which is the r6 value in gethandles2. The second call of service_devicedead with r3=0 is the whole device dead called after the notification of subdevices dead. |
Colin (478) 2433 posts |
It isn’t used. service_devicedead replaces it – see usb docs link posted earlier. Its a device header followed by the device descriptor followed by the configuration descriptor all in one block. |
Dave Higton (1515) 3526 posts |
Thanks, Colin. I really should learn to read things properly and not just skim them. :-( |
Rick Murray (539) 13840 posts |
Thanks for the document and the R6 nudge. That has saved a pile of frustrating debugging! The docs say: Returns:R4 DeviceFS stream handle Returns:R5 USB Stream handle Returns:R6 Device drivers handle for usage with DeviceFS_CallDevice For the sake of interest, what’s the difference between R4 and R6? |
Colin (478) 2433 posts |
r4 is the value returned by OS_FSControl 21 and is a FS internal handle on an open file stream (open endpoint) So if you think of it in layers you have the FS stream handle (r4), below that the DeviceFS device handle and below that the USBDriver’s stream handle (r5) Its all very messy. |
Colin (478) 2433 posts |
Ok this is where I’ve got to – any thoughts. It seems a simple modification to the usbmodule I posted could be all that is needed for module based drivers. I’ve made the buffer threshold the same as the size of the buffer. This means that any data entering an empty buffer causes a UpCall_BufferFilling upcall and removal of the last byte in a buffer (making it empty) causes a UpCall_BufferEmptying upcall So for writing you can. 1. open a write endpoint with the special fields set as required for reading 1. open a read endpoint with the special fields set as required I suppose in the module you are writing the upcalls could set a pollword to notify a foreground application. |
Pages: 1 2 3 4 5 6 7 8 9 10 11 12