I have an ADC device, I wrote a driver for it, the driver works well. I want to send the sample data from the driver to the application.
I choose fasync way, using a SIGIO signal to notify the application can read data from the driver. But I found sometimes the application does not respond to the signal, especially the signal frequency is high(about 1000hz). And when I do some other work such as using chrome, it will influence the signal response.
In summary, my method is very unstable.
Do you have some stable method or advice about transferring data to the application in a high-frequency situation?
Related
My team has been struggling with a pretty strange issue while using the WinRT/C++ APIs for Windows to connect to both a MIDI port and receive BLE notifications through a proprietary service on the same device.
The WinRT/C++ library itself is really nice and provides easy and modern C++ interfaces to access the managed Windows runtime classes.
I've pushed a sample repo to Github where we've replicated the issue with a minimal example.
The repo's readme goes over the problem in detail, but I'll post the relevant bits here for completeness.
The sample program is performing roughly these steps:
Check for available MIDI devices using a DeviceWatcher.
Check for available Bluetooth LE devices using another instance of a DeviceWatcher.
Match discovered MIDI and BluetoothLE devices on their ContainerId property (see DeviceInfo for details). This is the method JUCE employs in the native WinRT code for their library, and works as expected.
Open the MIDI port and attach a handler to the MessageReceived event (see the code).
This causes the system to create a connection to the Bluetooth LE device. The program detects this state change, creates a BluetoothLEDevice, we perform GATT service discovery and attach a handler to the ValueChanged event for the characteristic we're interested in notifications from (see the code).
The program then counts how many MIDI messages are received on each port and how many BLE notifications are received from the corresponding device.
The behaviour we notice is that data from the most recently connected device streams just fine, while the throughput for the others is severly limited. We are at quite a standstill regarding this issue, and are not sure where the problem may lie.
We are at quite a standstill here. I'd be more willing to accept it if all the devices would exhibit this behaviour, but that's not the case. Is there any reason that creating both a MidiInPort and an BluetoothLEDevice from the same peripheral should cause this issue?
A BLE radio can only receive or send at any given time. And therefore only communicate with one device at any given time. It uses a scheduler to allocate radio time for every device when you have many devices. That way a second connection can "interrupt" a connection event from another device, decreasing the throughput for that device. See https://infocenter.nordicsemi.com/topic/sds_s132/SDS/s1xx/multilink_scheduling/central_connection_timing.html
I have multiple processes that need to run simultaneously: reading and reporting data coming from serial device (plugged into OSDK device), transmitting telemetry data to MSDK device, and receiving and parsing incoming data from MSDK device. I believe that data transmission is supposed to be in the main thread, so would it be proper to separate the serial read into another thread?
This is my first time working with threading.
Thank you.
You don't have to use a separate thread, you can also use non blocking functions to try to read from the serial port. However a separate thread makes some things simpler, but the needed locking again makes it more complicated. What is easier depends on the details of your task.
I'm working on a virtual audio/midi driver and although its already working, I'm wondering whether my implementation is ... proper..
Usually, the midi hardware triggers interrupts in the driver to send / receive / process data, however as my driver is virtual, there is no hardware that could trigger the interrupts.
The way I handled this is that I set up a DPC timer for 100ms that calls the processing / sending routines, data received is still handles via interrupt from the OS.
Now that obviously isn't quite what DPCs are for, are they. However I cannot think of another implementation that works as well.
So.. any suggestions would be greatly appreciated :)
Regards,
Xaser
In KEXT, I am listening for file close via vnode or file scope listener. For certain (very few) files, I need to send file path to my system daemon which does some processing (this has to happen in daemon) and returns the result back to KEXT. The file close call needs to be blocked until I get response from daemon. Based on result I need to some operation in close call and return close call successfully. There is lot of discussion on KEXT communication related topic on the forum. But they are not conclusive and appears be very old (year 2002 around). This requirement can be handled by FtlSendMessage(...) Win32 API. I am looking for equivalent of that on Mac
Here is what I have looked at and want to summarize my understanding:
Mach message: Provides very good way of bidirectional communication using sender and reply ports with queueing mechansim. However, the mach message APIs (e.g. mach_msg, mach_port_allocate, bootstrap_look_up) don't appear to be KPIs. The mach API mach_msg_send_from_kernel can be used, but that alone will not help in bidirectional communication. Is my understanding right?
IOUserClient: This appears be more to do with communicating from User space to KEXT and then having some callbacks from KEXT. I did not find a way to initiate communication from KEXT to daemon and then wait for result from daemon. Am I missing something?
Sockets: This could be last option since I would have to implement entire bidirectional communication channel from KEXT to Daemon.
ioctl/sysctl: I don't know much about them. From what I have read, its not recommended option especially for bidirectional communication
RPC-Mig: Again I don't know much about them. Looks complicated from what I have seen. Not sure if this is recommended way.
KUNCUserNotification: This appears to be just providing notification to the user from KEXT. It does not meet my requirement.
Supported platform is (10.5 onwards). So looking at the requirement, can someone suggest and provide some pointers on this topic?
Thanks in advance.
The pattern I've used for that process is to have the user-space process initiate a socket connection to the KEXT; the KEXT creates a new thread to handle messages over that socket and sleeps the thread. When the KEXT detects an event it needs to respond to, it wakes the messaging thread and uses the existing socket to send data to the daemon. On receiving a response, control is passed back to the requesting thread to decide whether to veto the operation.
I don't know of any single resource that will describe that whole pattern completely, but the relevant KPIs are discussed in Mac OS X Internals (which seems old, but the KPIs haven't changed much since it was written) and OS X and iOS Kernel Programming (which I was a tech reviewer on).
For what it's worth, autofs uses what I assume you mean by "RPC-Mig", so it's not too complicated (MIG is used to describe the RPC calls, and the stub code it generates handles calling the appropriate Mach-message sending and receiving code; there are special options to generate kernel-mode stubs).
However, it doesn't need to do any lookups, as automountd (the user-mode daemon to which the autofs kext sends messages) has a "host special port" assigned to it. Doing the lookups to find an arbitrary service would be harder.
If you want to use the socket established with ctl_register() on the KExt side, then beware: The communication from kext to user space (via ctl_enqueuedata()) works OK. However opposite direction is buggy on 10.5.x and 10.6.x.
After about 70.000 or 80.000 send() calls with SOCK_DGRAM in the PF_SYSTEM domain complete net stack breaks with disastrous consequences for complete system (hard turning off is the only way out). This has been fixed in 10.7.0. I workaround by using setsockopt() in our project for the direction from user space to kext as we only send very small data (just to allow/disallow some operation).
I'm writing a windows utility that communicates to a a USB Device. The driver is a custom driver, supplied by Analog Devices (the manufacturer of the controller chip used in the device).
I've adapted one of their example Windows apps for communcicating with the device. Communication is done via named pipes, and can be synchronous or asynchronous. The problem I've found during testing is that calls to the WriteFile api function can sometimes fail to return if the device is switched off during a write (the device has a hard power switch). The same thing is observed using async or sync calls - I see no timeout happening when using aysnc.
After this has happened, I need to restart my app, as the thread dealing with USB communications is hung.
Is there a way I can prevent the WriteFile from failing to return in this case?
Thanks
Tom Davies.
You can cancel IO operations using CancelSynchronousIo and CancelIoEx. You could do this if you detect that your comm thread is unexpectedly blocking during writes.
Possible deal breakers:
Available only in Windows Vista and newer
Driver has to support cancellation