I'd like to create a virtual HID device (emulate it with a driver).
It must be visible to clients that implement standard HID detection:
Call HidD_GetHidGuid() – Get the HID
device class GUID
Call SetupDiGetClassDevs() – Get a
handle to a set of devices which
implement the HID interface
Call SetupDiEnumDeviceInterfaces() –
For each device in the returned set
of devices, obtain the interface
information for all exposed HID
interfaces.
Call
SetupDiGetDeviceInterfaceDetail() –
For each interface obtained in the
previous call, get the detailed
information block for that interface.
This detailed information includes
the string that can be passed to
CreateFile() to open a handle to the
device
Call SetupDiDestroyDeviceInfoList() –
Free up the device information set
that was obtained in the call to
SetupDiGetClassDevs().
The device should also support reading, so CreateFile / ReadFile would return data supplied by me from the driver.
I don't really know where to begin, as I don't have a lot of exp. in kernel dev. :(
Some people have had luck with the vmulti project as a base http://code.google.com/p/vmulti/
You sholud write a driver, then use DevCon (Device Console Tool) with install option.
cmdInstall:
A variation of cmdUpdate to install a driver when there is no associated hardware. It creates a new root-enumerated device instance and associates it with a made up hardware ID specified on the command line (which should correspond to a hardware ID in the INF). This cannot be done on a remote machine or in the context of Wow64.
http://code.msdn.microsoft.com/windowshardware/DevCon-Sample-4e95d71c
http://msdn.microsoft.com/en-us/library/windows/hardware/ff544707%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff544780%28v=vs.85%29.aspx
see the vhidmini ddk sample driver. It was in the version 1830 DDK but is not in the latest version. alternatively the hidfake sample in Oney's book.
See http://www.microsoft.com/mspress/books/sampchap/6262.aspx
Related
I would like to use Drake to control a real robot (Franka panda or Kuka iiwa). For simulation, the standard workflow would be build a diagram first and then use the Simulator to simulate the diagram. However, for the usage in real robot, I haven't found an example on how to run the built diagram. A close example would be ManipulationStationHardwareInterface. However I haven't found code on how to actual use this interface. Do I need to manually generate the context and run the diagram in a while loop? Or maybe I still need to use the Simulator and use the AdvanceTo method? If I use the Simulator, would there be addtional setting for synchoronization? What's more, how to control the loop frequency of the running diagram?
Thank you in advance!
The ManipulationStationHardwareInterface is indeed a reasonable example to look at. We have an updated version of the coming to Drake soon, too.
The basic steps are:
Run the robot's driver as a different process. Some of the drivers we use are public and are hosted here: https://manipulation.csail.mit.edu/station.html .
Send / Receive messages from your main controller thread to/from your driver. The LCMPublisherSystem and LCMSubscriberSystem are right in Drake. The ROS/ROS2 equivalents are here: https://github.com/RobotLocomotion/drake-ros (The ManipulationStationHardwareInterface + manipulation_station_simulation file in Drake shows an example of splitting up a Diagram for control + simulation into two processes using this message passing.
Timing: in the simplest case (typically ok for hardware) all of the executables are running with simulator.set_target_realtime_rate(1.0) and then simulator.AdvanceTo(big number). In other words, they all synchronize their clocks to the cpu clock, and don't try to synchronize explicitly to a clock passed via message passing. That sort of synchronization is possible, too, but I recommend the simpler version first. In this simple version, each system (e.g. your controller) is set to update with some periodic update -- say 100Hz -- and will run its computation using the most recently received subscribed messages and publish at that rate.
I have a system with multiple subsystems communicating with CANOpen. There is a main unit with a screen (for men-machine interface and stuff) and sub-units for minor operations(like sample button status, manage power, take measurements...).
We defined a CANOpen based communication protocol for this system. Subsystems share their conditions periodically with TPDO messages and do stuff according to main unit's commands sent with RPDO messages. And also some NMTs are in use too.
So I've been asked to add a new command to this protocol, zeroize. This command shall be sent broadcast and it shall cause everybody to delete softwares. What is the right way to do this?
Maybe I can use a RPDO? Are we allowed to define new NMT commands in CANopen? Maybe I can do it with NMT but by using a new commandt hat is not in use already?
Thanks in advance
Ip.
It is a bit confusing what you mean with TPDO and RPDO since the main unit's TPDO is going to be the peripheral units' RPDO and vice versa. But yes, the correct way to send out some custom broadcast message would be with a PDO.
Although, depending on what you mean with "delete software", CANopen might provide a mean for it. There are the save (OD 1010h) and load (OD 1011h) registers in the object dictionary. Save is to be used for the purpose of storing all CANopen communication (PDO configuration, mapping etc) in non-volatile memory. And load is used to restore CANopen parameters to factory defaults. These should however not be used to save/load application-specific settings.
You are not allowed to define new NMT commands.
Objects 1010h and 1011h can be used to reset the values in the object dictionary. If you really want to delete the software, the firmware upgrade protocol from CiA 302-3 might help. Writing 00h (Stop program) followed by 03h (Clear program) to object 1F51h sub-index 1 on the slave will delete the application. Whether it's actually "zeroed out" depends on the implementation. You'll need two SDO requests per slave for this though. The standard specifies that object 1F51h cannot be PDO mapped. Although that requirement may not be enforced for your devices, in which case you could achieve broadcast "zeroing" with two PDOs.
I'm trying to debug the sound system on a amlogic device. amixer and alsamixer aren't working as expected and amixer can crash the system. What I'm struggling with is that the drivers pass methods for accessing the hardware registers by constructing a snd_kcontrol object all as described in Writing an ALSA Driver on the ALSA website. But amixer cset calls snd_ctl_elem_write from control.c which refers to element_write in a snd_ctl_t object.
I can't see any link between the defined snd_kcontrol and any snd_ctl_t objects so can't see how amixer is supposed to be writing to the hardware. How is it normally done?
In user space, a control device is represented by snd_ctl_t, which contains the file handle of the device node. element_write points to snd_ctl_hw_elem_write(), which issues a system call.
In the kernel, an opened device file is represented by a struct snd_ctl_file, which is linked to the struct snd_card.
There is a piece of code that does DNS lookups using CFHostStartInfoResolution(). However this is synchronously and thus blocks anything before it returns - it's bad and I also think it causes crashes due to timeouts when connection is weak (when its bad it fails out safely directly)
So I want to do this asynchronously, as it's supposed to in the docs https://developer.apple.com/library/ios/documentation/CoreFoundation/Reference/CFHostRef/Reference/reference.html
New docs URL 20190227: https://developer.apple.com/documentation/cfnetwork/cfhostref
Specifically it says:
If you want to resolve the host asynchronously. call CFHostSetClient
to associate your client context and user-defined callback function
with the host. Then call CFHostScheduleWithRunLoop to schedule the
host on a run loop.
However this put me off because I haven't coded C in ages and can't get callbacks and runloops/threading right.
How am I supposed to call CFHostSetClient, CFHostScheduleWithRunLoop, and how do I implement those callbacks? Do I need to start a new thread?
Actually CFHost has a bug since on macOS since 10.7. Up to 10.7 it was possible to cancel a synchronous lookup calling CFHostCancelInfoResolution() on a second thread but since 10.7 this is not possible any longer (it just won't cancel the lookup). I reported that to Apple in 2013 (bug number is 13672880) but despite confirming it, Apple has never fixed it up to today.
Yet the more interesting part was what Apple suggested in their reply:
The best API for host name resolution is DNSServiceGetAddrInfo
and that's asynchronous and cancelable.
This API is documented to exist on macOS since 10.11.4, on iOS since 9.3, on tvOS since 9.2 and on watchOS since 2.2 - yet I think this cannot be correct, it must have existed, otherwise how could Apple recommend it in 2013 (10.11 was released 2015). I can confirm that this API also existed on iOS 8 and on macOS 10.9 and probably even earlier on both systems.
This API is internally using an undocumented asynchronous version of the otherwise synchronous C call getaddrinfo() which is found on all POSIX like systems today.
One advantage over other APIs is that you can choose if you only want to retrieve IPv4, IPv6, or both kind of addresses or you can let the system decide to pick the address family for you, depending on which addresses the system considers reachable at the moment (this is the default for most other resolving APIs).
Also in case a system has multiple active network interfaces (e.g. cable + WiFi or WiFi + mobile), you can pick the interface to use as different DNS settings may be set on different interfaces (and different DNS servers can deliver different results for the same domain name). If you don't pick one, the system will always use the current default server (this is the default for most other resolving APIs).
Should be something like this
CFHostSetClient(host, callbackFunction, hostContext);
CFHostScheduleWithRunLoop(host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFHostStartInfoResolution(host, kCFHostAddresses, 0);
And callbackFunction
void callbackFunction(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info) {
// Do something
}
You don't need to start a new thread, system will do it for you.
I 'm using coremidi all right, but I want to also support an external USB function.
I 've tried an app called Midi Monitor which indeed finds my USB interface when connected.
The problem is how to enable this interface through my own app. As said in MIDIGetNumberOfExternalDevices documentation, "Their presence is completely optional, only when a UI (such as Audio MIDI Setup) adds them."
How am I supposed to add them?
Best Regards.
"External devices" are not what you want. Those are the things that a user can create in Audio MIDI Setup in OS X, to represent a synthesizer or keyboard or other device that is connected to the computer via a MIDI cable. The system does not automatically create them. (It can't, because MIDI is terribly primitive and has no device discovery protocol.)
External devices are only for the user's benefit in naming and arranging things. They can't be used to do MIDI input or output. They're especially useless in iOS, since there's no Audio MIDI Setup app.
Instead, use MIDIGetNumberOfSources and MIDIGetSource to find sources of MIDI data.
To actually get input, use MIDIInputPortCreate to create an input port, then MIDIPortConnectSource to connect one or more sources to that port. Then your port's MIDIReadProc will be called when MIDI comes in.
Similarly, for output, you would use MIDIGetNumberOfDestinations and MIDIGetDestination to find destinations, create an output port using MIDIOutputPortCreate, and MIDISend to send data through a port to a destination.
For reference, see the MIDIServices documentation.