I am trying to unmount/eject usb device programmatically on macOS.
Using IOkit I tried to register to IOServiceMatching(kIOUSBInterfaceClassName) and iterate over all devices and for each device i tried getting the BSD name and go from there:
IORegistryEntrySearchCFProperty(usbDevice,kIOServicePlane,CFSTR(kIOBSDNameKey),kCFAllocatorDefault,kIORegistryIterateRecursively);
But i found that on Intel based devices that regestry search dosnt work.
I do have Vendor id, product id etc..
So my quistion:
Is there diffrent alternative?
Is there a syscall i can use?
Maybe diffrent approch and not use IoKit?
Thanks
I tried to register using Iokit to:
IOServiceMatching(kIOUSBHostDeviceClassName)
and
IOServiceMatching(kIOUSBInterfaceClassName);
and
IOServiceMatching(kIOUSBDeviceClassName);
First of all, there's no concept of "ejecting" in USB itself. Mounting, unmounting, ejecting, etc. are all storage device/volume concepts, and USB mass storage devices are just one type of storage device on which you can perform these operations.
You therefore need to look at the Disk Arbitration framework, specifically the DADiskEject function for ejecting. There is a certain mapping between I/O Kit and Disk Arbitration objects, but not all DADisk objects will necessarily have corresponding I/O Kit objects, as they also exist for APFS snapshot volumes, network mounts, etc. If looking for the device via I/O Kit is natural (for example because you're interested in a specific vendor+product ID pair) then you can easily find an IOMedia object's corresponding DADisk using DADiskCreateFromIOMedia.
For searching the I/O Kit registry for USB devices, use one of the documented matching dictionary formats.
For example, something like:
#{
#kIOProviderClassKey: #kIOUSBHostDeviceClassName,
#kUSBVendorID : #1234,
#kUSBProductID: #5678,
}
Related
I have a computer that needs to constantly scan online information and then in accordance to what has been found, the micro controller ( assume an ardunio ) will act in a particular way.
However it seems that most micro controllers cannot be dynamically updated via USB cable. Is there a way to constantly give new instructions or commands to a previously uploaded program into the processor to make it do corresponding actions?
Thank you (I'm sorry if this isn't the right forum to post this question, but I couldn't find one for micro controllers :( )
However it seems that most micro controllers cannot be dynamically updated via USB cable
if you mean programming the microcontroller via usb then it is possible but not at all necessary. you could just send predefined instructions via USB (using LUFA for example) or UART (supported on most microcontrollers) or other data transfer protocols in order to change the state of your program on the hardware side.
if you're new to microcontrollers you should read one of many online tutorials on the subject. arduinos are specially designed for beginners and they have their own forums where you could ask questions. if you choose to go with AVR, i would recommend avrfreaks.
Use serial communications. Install a special driver found on mbed, and then also use PySerial to be able to constanly update the mbed (Any other microcontroller would work)
Would using multi-GPUs in Vulkan be something like making many command queues then dividing command buffers between them?
There are 2 problems:
In OpenGL, we use GLEW to get functions. With more than 1 GPU, each GPU has its own driver. How'd we use Vulkan?
Would part of the frame be generated with a GPU & the others with other GPUs like use Intel GPU to render UI & AMD or Nvidia GPU to render game screen in labtops for example? Or would a frame be generated in a GPU & the next frame in an another GPU?
Updated with more recent information, now that Vulkan exists.
There are two kinds of multi-GPU setups: where multiple GPUs are part of some SLI-style setup, and the kind where they are not. Vulkan supports both, and supports them both in the same computer. That is, you can have two NVIDIA GPUs that are SLI-ed together, and the Intel embedded GPU, and Vulkan can interact with them all.
Non-SLI setups
In Vulkan, there is something called the Vulkan instance. This represents the base Vulkan system itself; individual devices register themselves to the instance. The Vulkan instance system is, essentially, implemented by the Vulkan SDK.
Physical devices represent a specific piece of hardware that implements the interface to a GPU. Each piece of hardware that exposes a Vulkan implementation does so by registering its physical device with the instance system. You can query which physical devices are available, as well as some basic properties about them (their names, how much memory they offer, etc).
You then create logical devices for the physical devices you use. Logical devices are how you actually do stuff in Vulkan. They have queues, command buffers, etc. And each logical device is separate... mostly.
Now, you can bypass the whole "instance" thing and load devices manually. But you really shouldn't. At least, not unless you're at the end of development. Vulkan layers are far too critical for day-to-day debugging to just opt out of that.
There are mechanisms, core in Vulkan 1.1, that allow individual devices to be able to communicate some information to other devices. In 1.1, only certain kinds of information can be shared across physical devices (namely, fences and semaphores, and even then, only on Linux through sync files). While these APIs could provide a mechanism for sharing data between two physical devices, at present, the restriction on most forms of data sharing is that both physical devices must have matching UUIDs (and therefore are the same physical device).
SLI setups
Dealing with SLI is covered by two Vulkan 1.0 extensions: KHR_device_group and KHR_device_group_creation. The former is for dealing with "device groups" in Vulkan, while the latter is an instance extension for creating device-grouped devices. Both of these are core in Vulkan 1.1.
The idea with this is that the SLI aggregation is exposed as a single VkDevice, which is created from a number of VkPhysicalDevices. Each internal physical device is a "sub-device". You can query sub-devices and some properties about them. Memory allocations are specific to a particular sub-device. Resource objects (buffers and images) are not specific to a sub-device, but they can be associated with different memory allocations on the different sub-devices.
Command buffers and queues are not specific to sub-devices; when you execute a CB on a queue, the driver figures out which sub-device(s) it will run on, and fills in the descriptors that use the images/buffers with the proper GPU pointers for the memory that those images/buffers have been bound to on those particular sub-devices.
Alternate-frame rendering is simply presenting images generated from one sub-device on one frame, then presenting images from a different sub-device on another frame. Split-frame rendering is handled by a more complex mechanism, where you define the memory for the destination image of a rendering command to be split among devices. You can even do this with presentable images.
In vulkan you need to enumerate the devices and select the one you want to work with. There will be nothing stopping you from trying to work with 2 different ones separately. Each vulkan call needs at least 1 parameter as context. The loader layer will then forward the call to the correct driver. Or you can load the functions for each device separately to avoid the loader's trampoline.
A generated frame will need to be forwarded to the card that is connected to the screen for display. So it's more likely that 1 GPU is responsible for graphics and the others are used for physics.
Only a single device can be connected to a specific surface at a time so that device needs to get the rendered frame to copy it into the renderable image that gets pushed to the screen.
Device group is the way to go. Look at the vulkan specification for documentation. Vulkan handle all the dispatch to the others GPUs (when they are connected by sli/crossfire). All you need to do is to tell vulkan how the dispatch is done (for example dispatch one frame on a GPU and the next on another one). If you need to do compute work you will need to address each GPU individually. Please find a link for a reference: https://www.ea.com/seed/news/khronos-munich-2018-halcyon-vulkan
I need to write a number of drivers for both HID USB devices as well as some old serial devices. The drivers are to pull data off the device and then send the data over to an application that then consumes it. Since the Apple Docs mention that a lot of USB and HID communication can be done from the user space I had assumed that I would not need to write a kernel extension, at least not for the HID devices. Could some one tell me a more solid way to determine this?
Thanks!
If you're writing a single application that must talk to one or more USB HID devices you may well find you can just access the devices straight from the application using the application-level USB APIs.
A kernel driver would be more for something like a networking or mass storage device that needed to integrate with the kernel to be be available to multiple applications.
This Apple document Common QA and Roadmap for USB Software Development on Mac OS X goes into some detail on the matter and links to example code too.
I want to write a usb touchscreen kext for usb touch screen .
I have read the Kernel Extension Programming Topics and the I/O Kit Fundamentals etc,
My question is,
1 . how to get the input report messages from touch screen ?
2 . how to post the coordinate info to system ?
I have no idea, anybody help?
It depends on the hardware; moreover, this question is quite broad - you'll need to be more specific in your question to get more specific answers. I'll try to provide a broad overview:
A touchscreen has 2 parts:
Output: showing the image coming from the computer on the display
Input: the touch events to feed back into the computer
As you haven't asked about (1) at all, I assume your device just plugs into a display port on the Mac and is already displaying correctly. If not, you'll want to look into the IOFramebuffer API.
For (2) - Pretty much all USB input devices are HID devices of some form. If you're new to HID in general, you'll probably want to read and understand the USB HID specification and related documentation as you'll be using that information throughout.
OSX already comes with comprehensive support for the standard HID device classes such as keyboards, mice, touchpads, graphics tablets, etc. If your device claims to be any kind of HID device, OSX should already be detecting it and attaching its generic HID driver to it. You should see a IOUSBHIDDriver instance in the I/O Registry (eg. using Apple's IORegistryExplorer tool, or ioreg on the command line).
I'd also expect your device to conform to HID's absolute pointing device profile, so at least single touches should already be working properly. If it's a multitouch device, or you need other extra features, you'll probably want to implement a IOUSBHIDDriver subclass that generates or converts the necessary multitouch events.
If your device for some reason isn't already a HID USB device, you'll need to write a custom USB driver for it, and convert the events coming from it into HID events, as the HID events are passed directly into userspace and processed there. You can actually write USB drivers and generate HID events from userspace, so you might be able to avoid writing any kernel code at all if you prefer.
Apple provides some documentation on HID:
The HID Class Device Interface Guide covers some general concepts and the userspace interfaces.
The Kernel Framework Reference has API documentation for the various IOHID* classes in the kernel.
If you're going to be writing your own kernel HID device driver, your best bet is probably the IOHIDFamily source code. You can probably also find some open source examples around the web.
Apple's USB mailing lists is probably also worth checking, both for the archives and if you have questions. The darwin-kernel and darwin-drivers lists are also relevant.
I've been looking for a detailed description for how USB protocol and cabling works for a long time with no luck. I am looking for a detailed yet not overcomplicated explanation of how things work on the software and hardware side of USB. Links and explanations would be appreciated. I've really run out of ideas, so it would be great if you can help me out.
This is what I do know:
USB hardware carries 4 lines- 5V power, ground, and 2 full duplex lines.
When connecting, the device can ask for a specified amount of current.
The transfer speeds for USB are quite fast compared to traditional serial connections.
When connecting, a device will output descriptors to the host describing itself. These descriptors will also be used for data.
What I don't know:
How does a program in C/C++ write directly to a USB port? Does it write to an address in the port?
How do some devices describe themselves as HID?
How do drivers work?
Everything else...
Thank you!
Identification
Every device has a (unique) Vendor and Product ID. These are provided (sold) by usb.org to identify a device. You can use a library like libusbx to enumerate all connected devices and select the one with the Vendor and Product ID you are looking for.
HID Descriptors
The point of HID descriptors is actually to do away with drivers. HID descriptors are a universal way of describing your device so you don't need to waste time on a driver for every system/architecture/etc/. (Same concept as the JVM.)
Reports
You will use either the input, output, or feature reports to read or write to your device. You send a stream to your device on the input or feature report. This is typically 8 bytes I believe. Only one of which is a single character you wish to write. The HID descriptor contains all the information you need to put together a report. Although I'm struggling to find a related link to clarify this.
Potential Libraries
In an effort to be open-minded here are all the libraries I am familiar with and some info about them.
libusb-0.1
First off is libusb-0.1. This used to be the go to and was built in to many Linux kernels and Windows I believe. It is very easy to use and there is a lot of documentation. However, the owner never updated and it wasn't edited for many years. It supports only synchronous transfers. (If an error occurs, the program can wait infinitely while it expects a transfer.)
libusbx
Next is libusbx. This is what most people would suggest today and I agree. It was published by those frustrated by the owner of libusb-0.1. The code is much more lightweight, up-to-date, and importantly does not require root privileges like libusb-0.1 and libusb-1.0 (Discussed in a second). It supports synchronous or asynchronous transfers.
libusb-1.0
Then there is libusb-1.0. This was the first update to libusb-0.1 in some number of years. It is not compatible with libusb-0.1. This was published the same day as libusbx as a retaliation (I assume) and an attempt to rectify the lack of updated content and conserve a user-base. It supports synchronous or asynchronous transfers.
hid.h
Finally, there is the hid library. This was built on top of libusb as another layer of abstraction. But honestly, I think it's just really confusing and it just adds more overhead than necessary.
Some Good Resources
Understanding HID Descriptors
Control Message Transfer Documentation (Very Good Link IMO)
Rolling Your Own HID Descriptor
Good Visual of HID Reports for Transfers
Great List of bmRequestType constants (You will need this or similar)
A simple terminal app for speaking with DigiSpark using libusbx and libusb-0.1
I know this isn't exactly what you are looking for, but maybe it will get you started!
This website has a general overview of how USB devices work:
https://www.beyondlogic.org/usbnutshell/usb1.shtml
Particular sections give answers to things from the list of things you don't know yet about USB.
E.g. to find out how USB devices identify themselves, read about USB descriptors:
https://www.beyondlogic.org/usbnutshell/usb5.shtml#DeviceDescriptors
To learn how a C/C++ program can talk to a USB device, see examples on using the libusb library:
https://github.com/libusb/libusb/tree/master/examples
To learn how USB drivers work, see a tutorial from Bootlin:
https://bootlin.com/blog/usb-slides/