This chapter provides a summary of USB device architecture and describes how USB devices are represented in OS X. It also presents a few specific guidelines for working with USB devices in an application.For details on the USB specification, see http://www.usb.org.
USB Device Types and Bus Speeds
The USB specification supports a wide selection of devices that range from lower-speed devices such as keyboards, mice, and joysticks to higher-speed devices such as scanners and digital cameras. The specification lists a number of device classes that each define a set of expected device behaviors. Table 1-1 lists some examples of USB devices, categorized by class.
Download Apple Mobile Device Support 126.96.36.199 Apple Inc. 84.2MB - Freeware. If Apple Mobile Device USB driver is corrupted or missing in your Windows computer, the iOS devices, such as iPhone would not be detected or recognized by the host or the virtual machine. At this moment, in order to successfully connect iPhone etc Apple device to host computer or VMware Mac OS X, it is necessary to check and install or update.
Table 1-1 Examples of USB devices
USB device class
USB devices in class
Chip Card Interface Device Class
Smart cards, chip cards
A device in which all class-specific information is embedded in its interfaces
Keyboards, mice, joysticks, drawing tablets
Hubs provide additional attachment points for USB devices
Mass storage class
Hard drives, flash memory readers, CD Read/Write drives, digital cameras, and high-end media players
A device that doesn’t fit into any other predefined class or one that doesn’t use the standard protocols for an existing class
Digital camcorders, webcams, digital still cameras that support video streaming
Version 1.1 of the USB specification supports two bus speeds:
Low speed (1.5 Mbps)
Full speed (12 Mbps)
Version 2.0 of the specification adds another bus speed to this list:
The USB 2.0 specification is fully compatible with low-speed and full-speed USB devices and even supports the use of cables and connectors made to meet earlier versions of the specification. Apple provides USB 2.0 ports on all new Macintosh computers and fully supports the new specification with Enhanced Host Controller Interface (EHCI) controllers and built-in, low-level USB drivers.
For the most part, you do not have to change existing applications to support the faster data rate because the speed increase and other enhancements are implemented at such a low level. The exceptions to this are some differences in isochronous transfers. For information on how the USB 2.0 specification affects isochronous transfers, see USB 2.0 and Isochronous Transfers.
USB Device Architecture and Terminology
The architecture of a generic USB device is multi-layered. A device consists of one or more configurations, each of which describes a possible setting the device can be programmed into. Such settings can include the power characteristics of the configuration (for example, the maximum power consumed by the configuration and whether it is self-powered or not) and whether the configuration supports remote wake-up.
Each configuration contains one or more interfaces that are accessible after the configuration is set. An interface provides the definitions of the functions available within the device and may even contain alternate settings within a single interface. For example, an interface for an audio device may have different settings you can select for different bandwidths.
Each interface contains zero or more endpoints. An endpoint is a uniquely identifiable portion of a USB device that is the source or sink of information in a communication flow between the host and the device. Each endpoint has characteristics that describe the communication it supports, such as transfer type (control, isochronous, interrupt, or bulk, described in USB Transfer Types), maximum packet size, and transfer direction (input or output).
Communication with a USB device is accomplished through a pipe, a logical association between an endpoint and software running on the host. Endpoint and pipe are often used synonymously although an endpoint is a component of a USB device and a pipe is a logical abstraction of the communications link between endpoint and host.
USB Device Component Descriptors
Each layer of a USB device provides information about its attributes and resource requirements in its descriptor, a data structure accessible through device interface functions. By examining the descriptors at each layer, you can determine exactly which endpoint you need to communicate successfully with a particular device.
At the top layer is the device descriptor, which has fields associated with information such as the device’s class and subclass, vendor and product numbers, and number of configurations. Each configuration in turn has a configuration descriptor containing fields that describe the number of interfaces it supports and the power characteristics of the device when it is in that configuration, along with other information. Each interface supported by a configuration has its own descriptor with fields for information such as the interface class, subclass, and protocol, and the number of endpoints in that interface. At the bottom layer are the endpoint descriptors that specify attributes such as transfer type and maximum packet size.
The USB specification defines a name for each descriptor field, such as the
bDeviceClass field in the device descriptor and the
bNumInterfaces field in the configuration descriptor, and each field is associated with a value. For a complete listing of all descriptor fields, see the USB specification at www.usb.org. The USB family defines structures that represent the descriptors defined by the USB specification. For the definitions of these structures, see
USB in Kernel Framework Reference.
USB Composite Class Devices
The USB specification defines a composite class device as a device whose device-descriptor fields for device class (
bDeviceClass) and device subclass (
bDeviceSubClass) both have the value
0. A composite class device appears to the system as a USB device using a single bus address that may present multiple interfaces, each of which represents a separate function. A good example of a composite class device is a multifunction device, such as a device that performs printing, scanning, and faxing. In such a device, each function is represented by a separate interface. In OS X, the I/O Kit loads the
AppleUSBComposite device driver for composite class devices that do not already have vendor-specific device drivers to drive them. The
AppleUSBComposite driver configures the device and causes drivers to be loaded for each USB interface.
Although most multifunction USB devices are composite class devices, not all composite class devices are multifunction devices. The manufacturer of a single-function USB device is at liberty to classify the device as a composite class device as long as the device meets the USB specifications. For more information on how OS X represents USB devices and interfaces, see USB Devices on OS X.
USB Transfer Types
The USB specification defines four types of pipe transfer:
Control—intended to support configuration, command, and status communication between the host software and the device. Control transfers support error detection and retry.
Interrupt—used to support small, limited-latency transfers to or from a device such as coordinates from a pointing device or status changes from a modem. Interrupt transfers support error detection and retry.
Isochronous—used for periodic, continuous communication between the host and the device, usually involving time-relevant information such as audio or video data streams. Isochronous transfers do not support error detection or retry.
Bulk—intended for non-periodic, large-packet communication with relaxed timing constraints such as between the host software and a printer or scanner. Bulk transfers support error detection and retry.
Pipes also have a transfer direction associated with them. A control pipe can support bidirectional communication but all other pipes are strictly uni-directional. Therefore, two-way communication requires two pipes, one for input and one for output.
Every USB device is required to implement a default control pipe that provides access to the device’s configuration, status, and control information. This pipe, implemented in the
IOUSBDevice nub object (described in USB Devices on OS X), is used when a driver such as the
AppleUSBComposite driver configures the device or when device-specific control and status information is needed. For example, your application would use the default control pipe if it needs to set or choose a configuration for the device. The default control pipe is connected to the default endpoint (endpoint 0). Note that endpoint 0 does not provide an endpoint descriptor and it is never counted in the total number of endpoints in an interface.
The interfaces associated with a configuration can contain any combination of the three remaining pipe types (interrupt, isochronous, and bulk), implemented in the
IOUSBInterface nub objects (described in USB Devices on OS X). Your application can query the interface descriptors of a device to select the pipe most suited to its needs.
Stalls and Halts
Although a stall and a halt are different, they are closely related in their effect on data transmission. Halt is a feature of an endpoint and it can be set by either the host or the device itself in response to an error. A stall is a type of handshake packet an endpoint returns when it is unable to transmit or receive data or when its halt feature is set (the host never sends a stall packet). When an endpoint sends a stall packet, the host can halt the endpoint.
Depending on the precise circumstances and on how compliant the device is, the halt feature must be cleared in the host, the endpoint, or both before data transmission can resume. When the halt is cleared the data toggle bit, used to synchronize data transmission, is also reset (see Data Synchronization in Non-Isochronous Transfers for more information about the data toggle). For information on how to handle these conditions in your application, see Handling Stalls, Halts, and Data Toggle Resynchronization.
Data Synchronization in Non-Isochronous Transfers
The USB specification defines a simple protocol to provide data synchronization across multiple packets for non-isochronous transfers (recall that isochronous transfers do not support error recovery or retry). The protocol is implemented by means of a data toggle bit in both the host and the endpoint which is synchronized at the start of a transaction (or when a reset occurs). The precise synchronization mechanism varies with the type of transfer; see the USB specification for details.
Both the host and the endpoint begin a transaction with their data toggle bits set to zero. In general, the entity receiving data toggles its data toggle bit when it is able to accept the data and it receives an error-free data packet with the correct identification. The entity sending the data toggles its data toggle bit when it receives a positive acknowledgement from the receiver. In this way, the data toggle bits stay synchronized until, for example, a packet with an incorrect identification is received. When this happens, the receiver ignores the packet and does not increment its data toggle bit. When the data toggle bits get out of synchronization (for this or any other reason), you will probably notice that alternate transactions are not getting through in your application. The solution to this is to resynchronize the data toggle bits. For information on how to do this, see Handling Stalls, Halts, and Data Toggle Resynchronization.
USB 2.0 and Isochronous Transfers
The USB 2.0 specification supports the same four transfer types as earlier versions of the specification. In addition to supporting a higher transfer rate, the new specification defines an improved protocol for high-speed transfers and new ways of handling transactions for low-speed and full-speed devices. For details on the protocols and transaction-handling methods, see the specification at http://www.usb.org.
For the most part, these enhancements are implemented at the host software level and do not require changes to your code. For isochronous transfers, however, you should be aware of the following differences:
Earlier versions of the specification divide bus time into 1-millisecond frames, each of which can carry multiple transactions to multiple destinations. (A transaction contains two or more packets: a token packet and one or more data packets, a handshake packet, or both.) The USB 2.0 specification divides the 1-millisecond frame into eight, 125-microsecond microframes, each of which can carry multiple transactions to multiple destinations.
The maximum amount of data allowed in a transaction is increased to 3 KB.
Any isochronous endpoints in a device’s default interface must have a maximum packet size of zero. (This means that the default setting for an interface containing isochronous pipes is alternate setting zero and the maximum packet size for that interface’s isochronous endpoints must be zero.) This ensures that the host can configure the device no matter how busy the bus is.
For a summary of how these differences affect the OS X USB API, see Changes in Isochronous Functions to Support USB 2.0.
USB Devices on OS X
When a USB device is plugged in, the OS X USB family abstracts the contents of the device descriptor into an I/O Kit nub object called an
IOUSBDevice. This nub object is attached to the
IOService plane of the I/O Registry as a child of the driver for the USB controller. The
IOUSBDevice nub object is then registered for matching with the I/O Kit.
If the device is a composite class device with no vendor-specific driver to match against it, the
AppleUSBComposite driver matches against it and starts as its provider. The
AppleUSBComposite driver then configures the device by setting the configuration in the device’s list of configuration descriptors with the maximum power usage that can be satisfied by the port to which the device is attached. This allows a device with a low power and a high power configuration to be configured differently depending on whether it’s attached to a bus-powered hub or a self-powered hub. In addition, if the
IOUSBDevice nub object has the “Preferred Configuration” property, the
AppleUSBComposite driver will always use that value when it attempts to configure the device.
The configuration of the device causes the USB family to abstract each interface descriptor in the chosen configuration into an
IOUSBInterface nub object. These nub objects are attached to the I/O Registry as children of the original
IOUSBDevice nub object and are registered for matching with the I/O Kit.
Important: Because a composite class device is configured by the
AppleUSBComposite driver, setting the configuration again from your application will result in the destruction of the
IOUSBInterface nub objects and the creation of new ones. In general, the only reason to set the configuration of a composite class device that’s matched by the
AppleUSBComposite driver is to choose a configuration other than the first one.
For non-composite class devices or composite class devices with vendor-specific drivers that match against them, there is no guarantee that any configuration will be set and you may have to perform this task within your application.
It's important to be mindful of the difference between a USB device (represented in the I/O Registry by an
IOUSBDevice nub object) and its interfaces (each represented by an
IOUSBInterface nub object). A multifunction USB device, for example, is represented in the I/O Registry by one
IOUSBDevice object and one
IOUSBInterface object for each interface.
The distinction between interface and device is important because it determines which object your application must find in the I/O Registry and which type of device interface to get. For example, if your application needs to communicate with a specific interface in a multifunction USB device, it must find that interface and get an
IOUSBInterfaceInterface to communicate with it. An application that needs to communicate with the USB device as a whole, on the other hand, would need to find the device in the I/O Registry and get an
IOUSBDeviceInterface to communicate with it. For more information on finding devices and interfaces in the I/O Registry, see Finding USB Devices and Interfaces; for more information on how to get the proper device interface to communicate with a device or interface, see Using USB Device Interfaces.
Finding USB Devices and Interfaces
To find a USB device or interface, use the keys defined in the Universal Serial Bus Common Class Specification, Revision 1.0 (available for download from http://www.usb.org/developers/devclass_docs/usbccs10.pdf) to create a matching dictionary that defines a particular search. If you are unfamiliar with the concept of device matching, see the section “Finding Devices in the I/O Registry” in Accessing Hardware From Applications.
The keys defined in the specification are listed in the tables below. Each key consists of a specific combination of elements in a device or interface descriptor. In the tables below, the elements in a key are separated by the ‘+’ character to emphasize the requirement that all a key’s elements must appear together in your matching dictionary. Both tables present the keys in order of specificity: the first key in each table defines the most specific search and the last key defines the broadest search.
Before you build a matching dictionary, be sure you know whether your application needs to communicate with a device or a specific interface in a device. It’s especially important to be aware of this distinction when working with multifunction devices. A multifunction device is often a composite class device that defines a separate interface for each function. If, for example, your application needs to communicate with the scanning function of a device that does scanning, faxing, and printing, you need to build a dictionary to match on only the scanning interface (an IOUSBInterface object), not the device as a whole (an IOUSBDevice object). In this situation, you would use the keys defined for interface matching (those shown in Table 1-3), not the keys for device matching.
Table 1-2 lists the keys you can use to find devices (not interfaces). Each key element is a piece of information contained in the device descriptor for a USB device.
Table 1-2 Keys for finding a USB device
bcdDevice contains the release number of the device
Use this key only if the device’s
bDeviceClass is $FF
Use this key only if the device’s
bDeviceClass is $FF
Use this key only if the device’s
bDeviceClass is not $FF
Use this key only if the device’s
bDeviceClass is not $FF
Table 1-3 lists the keys you can use to find interfaces (not devices). Each key element is a piece of information contained in an interface descriptor for a USB device.
Table 1-3 Keys for finding a USB interface
Use this key only if
bInterfaceClass is $FF
Use this key only if
bInterfaceSubClass is $FF
Use this key only if
bInterfaceSubClass is not $FF
Use this key only if
bInterfaceSubClass is not $FF
For a successful search, you must add the elements of exactly one key to your matching dictionary. If your matching dictionary contains a combination of elements not defined by any key, the search will be unsuccessful. For example, if you create a matching dictionary containing values representing a device’s vendor, product, and protocol, the search will be unsuccessful even if a device with those precise values in its device descriptor is currently represented by an
IOUSBDevice nub in the I/O Registry. This is because there is no key in Table 1-2 that combines the
USB Family Error Codes
As you develop an application to access a USB device or interface, you will probably encounter error codes specific to the OS X USB family. If you are using Xcode, you can search for information about these error codes in the Xcode documentation window.
To find error code documentation, select Documentation from the Xcode Help menu. Select Full-Text Search from the pull-down menu associated with the search field (click the magnifying glass icon to reveal the menu). Select Reference Library in the Search Groups pane at the left of the window. Type an error code number in the search field, such as 0xe0004057, and press Return. Select the most relevant entry in the search results to display the document in the lower portion of the window. Use the Find command (press Command-F) to find the error code in this document. Using the example of error code 0xe0004057, you’ll see that this error is returned when the endpoint has not been found.
For help with deciphering I/O Kit error codes in general, see Technical Q&A QA1075, “Making sense of I/O Kit error codes.”
Determining Which Interface Version to Use
As described in USB Devices on OS X, the OS X USB family provides an
IOUSBDeviceInterface object you use to communicate with a USB device as a whole and an
IOUSBInterfaceInterface object you use to communicate with an interface in a USB device. There are a number of different versions of the USB family, however, some of which provide new versions of these interface objects. (One way to find the version of the USB family installed in your computer is to view the Finder preview information for the
IOUSBFamily.kext located in
/System/Library/Extensions.) This section describes how to make sure you use the correct interface object and how to view the documentation for the interface objects.
The first version of the USB family was introduced in OS X v10.0 and contains the first versions of the interface objects
IOUSBInterfaceInterface. When new versions of the USB family introduce new functions for an interface object, a new version of the interface object is created, which gives access to both the new functions and all functions defined in all previous versions of that interface object. For example, the
IOUSBDeviceInterface197 object provides two new functions you can use with version 1.9.7 of the USB family (available in OS X v10.2.3 and later), in addition to all functions available in the previous device interface objects
As you develop an application that accesses a USB device or interface, you should use the latest version of the interface object that is available in the earliest version of OS X that you want to support. For example, if your application must run in OS X v10.0, you must use the
IOUSBInterfaceInterface objects. If, however, you develop an application to run in OS X v10.4 and later, you use the
IOUSBDeviceInterface197 object to access the device as a whole and the
IOUSBInterfaceInterface220 object to access an interface in it. This is because
IOUSBDeviceInterface197 is available in OS X version 10.2.3 and later and
IOUSBInterfaceInterface220 is available in OS X v10.4 and later.
Note: When you view the documentation for these interface objects, notice that each version is documented separately. For example, the documentation for
IOUSBDeviceInterface197 contains information about the two new functions introduced in this version, but does not repeat the documentation for the functions introduced in
Tasks and Caveats
This section presents some specific tasks your application might need to perform, along with some caveats related to USB 2.0 support of which you should be aware.
Handling Stalls, Halts, and Data Toggle Resynchronization
As described in Stalls and Halts , stalls and halts are closely related in their effect on data transmission. To simplify the API, the USB family uses the pipe stall terminology in the names of the functions that handle these conditions:
ClearPipeStall function operates exclusively on the host controller side, clearing the halt feature and resetting the data toggle bit to zero. If the endpoint’s halt feature and data toggle bit must be reset as well, your application must do so explicitly, using one of the
ControlRequest functions to send the appropriate device request. See the documentation for the
USB.h header file in I/O Kit Framework Reference for more information about standard device requests.
In OS X version 10.2 and later, you can use the
ClearPipeStallBothEnds function which, as its name suggests, clears the halt and resets the data toggle bit on both sides at the same time.
Using the Low Latency Isochronous Functions
In OS X, the time between when an isochronous transaction completes on the USB bus and when you receive your callback can stretch to tens of milliseconds. This is because the callback happens on the USB family work loop, which runs at a lower priority than some other threads in the system. In most cases, you can work around this delay by queuing read and write requests so that the next transaction is scheduled and ready to start before you receive the callback from the current transaction. In fact, this scheme is a good way to achieve higher performance whether or not low latency is a requirement of your application.
In a few cases, however, queuing isochronous transactions to keep the pipe busy is not enough to prevent a latency problem that a user might notice. Consider an application that performs audio processing on some USB input (from a musical instrument, for example) before sending the processed data out to USB speakers. In this scenario, a user hears both the raw, unprocessed output of the instrument and the processed output of the speakers. Of course, some small delay between the time the instrument creates the raw sound waves and the time the speaker emits the processed sound waves is unavoidable. If this delay is greater than about 8 milliseconds, however, the user will notice.
In OS X version 10.2.3 (version 1.9.2 of the USB family) the USB family solves this problem by taking advantage of the predictability of isochronous data transfers. By definition, isochronous mode guarantees the delivery of some amount of data every frame or microframe. In earlier versions of OS X, however, it was not possible to find out the exact amount of data that was transferred by a given time. This meant that an application could not begin processing the data until it received the callback associated with the transaction, telling it the transfer status and the actual amount of data that was transferred.
Version 1.9.2 of the USB family introduced the
LowLatencyWriteIsochPipeAsync functions. These functions update the frame list information (including the transfer status and the number of bytes actually transferred) at primary interrupt time. Using these functions, an application can request that the frame list information be updated as frequently as every millisecond. This means an application can retrieve and begin processing the number of bytes actually transferred once a millisecond, without waiting for the entire transaction to complete.
Important: Because these functions cause processing at primary interrupt time, it is essential you use them only if it is absolutely necessary. Overuse of these functions can cause degradation of system performance.
To support the low latency isochronous read and write functions, the USB family also introduced functions to create and destroy the buffers that hold the frame list information and the data. Although you can choose to create a single data buffer and a single frame list buffer or multiple buffers of each type, you must use the
LowLatencyCreateBuffer function to create them. Similarly, you must use the
LowLatencyDestroyBuffer function to destroy the buffers after you are finished with them. This restricts all necessary communication with kernel entities to the USB family.
For reference documentation on the low latency isochronous functions, see the
IOUSBLib.h documentation in I/O Kit Framework Reference.
Errors Reported by the EHCI Hub
The EHCI hub that supports high-speed devices (as well as low-speed and full-speed devices) provides coarser-grained error reporting than the OHCI hub does. For example, with an OHCI hub, you might receive an “endpoint timed out” error if you unplug the device while it is active. If you perform the same action with an EHCI hub, you might receive a “pipe stalled” error instead.
The Apple EHCI hub driver cannot get more detailed error information from the hub, so it alternates between reporting “device not responding” and “pipe stalled” regardless of the actual error reported by the device. To avoid problems with your code, be sure your application does not rely on other, more specific errors to make important decisions.
Changes in Isochronous Functions to Support USB 2.0
Recall that the USB 2.0 specification divides the 1-millisecond frame into eight, 125-microsecond microframes. The USB family handles this by reinterpreting some function parameters (where appropriate) and adding a couple of new functions. This section summarizes these changes; for reference documentation, see documentation for
IOUSBLib.h in I/O Kit Framework Reference.
The functions you use to read from and write to isochronous endpoints are
WriteIsochPipeAsync. Both functions include the following two parameters:
If you need to handle high-speed isochronous transfers, you can think of these parameters as referring to “transfer opportunities” instead of frames. In other words, numFrames can refer to a number of frames for full-speed devices or to a number of microframes for high-speed devices. Similarly, frameList specifies the list of transfers you want to occur, whether they are in terms of frames or microframes.
WriteIsochPipeAsync functions also have the frameStart parameter in common, but it does not get reinterpreted. This is because all isochronous transactions, including high-speed isochronous transactions, start on a frame boundary, not a microframe boundary.
To help you determine whether a device is functioning in full-speed or high-speed mode, the USB family added the
GetFrameListTime function, which returns the number of microseconds in a frame. By examining the result (
kUSBHighSpeedMicrosecondsInFrame) you can tell in which mode the device is operating.
The USB family also added the
GetBusMicroFrameNumber function which is similar to the
GetBusFrameNumber function, except that it returns both the current frame and microframe number and includes the time at which that information was retrieved.
To handle the new specification’s requirement that isochronous endpoints in a device’s default interface have a maximum packet size of zero, the USB family added functions that allow you to balance bandwidth allocations among isochronous endpoints. A typical scenario is this:
GetBandwidthAvailable (available in OS X version 10.2 and later) to determine how much bandwidth is currently available for allocation to isochronous endpoints.
GetEndpointProperties (available in OS X version 10.2 and later) to examine the alternate settings of an interface and find one that uses an appropriate amount of bandwidth.
SetAlternateInterface (available in OS X version 10.0 and later) to create the desired interface and allocate the pipe objects.
GetPipeProperties (available in OS X version 10.0 and later) on the chosen isochronous endpoint. This is a very important step because
SetAlternateInterface will succeed, even if there is not enough bandwidth for the endpoints. Also, another device might have claimed the bandwidth that was available at the time the
GetBandwidthAvailable function returned. If this happens, the maximum packet size for your chosen endpoint (contained in the
maxPacketSize field) is now zero, which means that the bandwidth is no longer available.
In addition, in OS X version 10.2, the USB family added the
SetPipePolicy function, which allows you to relinquish bandwidth that might have been specified in an alternate setting.
USB Device Access in an Intel-Based Macintosh
This section provides an overview of some of the issues related to developing a universal binary version of an application that accesses a USB device. Before you read this section, be sure to read Universal Binary Programming Guidelines, Second Edition. That document covers architectural differences and byte-ordering formats and provides comprehensive guidelines for code modification and building universal binaries. The guidelines in that document apply to all types of applications, including those that access hardware.
Before you build your application as a universal binary, make sure that:
You port your project to GCC 4 (Xcode uses GCC 4 to target Intel-based Macintosh computers)
You install the OS X v10.4 universal SDK
You develop your project in Xcode 2.1 or later
The USB bus is a little-endian bus. Structured data appears on the bus in the little-endian format regardless of the native endian format of the computer an application is running in. If you've developed a USB device-access application to run in a PowerPC-based Macintosh, you probably perform some byte swapping on data you read from the USB bus because the PowerPC processor uses the big-endian format. For example, the USB configuration descriptor structure contains a two-byte field that holds the descriptor length. If your PowerPC application reads this structure from the USB bus (instead of receiving it from a USB device interface function), you need to swap the value from the USB bus format (little endian) to the PowerPC format (big endian).
The USB family provides several swapping macros that swap from USB to host and from host to USB (for more information on these macros, see
USB.h). The Kernel framework also provides byte-swapping macros and functions you can use in high-level applications (see the
OSByteOrder.h header file in
libkern). If you use these macros in your application, you shouldn't have any trouble developing a universal binary version of your application. This is because these macros determine at compile time if a swap is necessary. If, however, your application uses hard-coded swaps from little endian to big endian, your application will not run correctly in an Intel-based Macintosh. As you develop a universal binary version of your application, therefore, be sure to use the USB family swapping macros or the macros in
libkern/OSByteOrder.h for all byte swapping.
Although you may need to perform byte swapping on values your application reads from the USB bus, you do not need to perform any byte swapping on values you pass in arguments to functions in the USB family API. You should pass argument values in the computer's host format. Likewise, any values you receive from the USB family functions will be in the computer's host format.
The lowest layer of OS X includes the kernel, drivers, and BSD portions of the system and is based primarily on open source technologies. OS X extends this low-level environment with several core infrastructure technologies that make it easier for you to develop software.
The following sections describe features in the Kernel and Device Drivers layer of OS X.
XPC Interprocess Communication and Services
XPC is an OS X interprocess communication technology that complements App Sandbox by enabling privilege separation. Privilege separation, in turn, is a development strategy in which you divide an app into pieces according to the system resource access that each piece needs. The component pieces that you create are called XPC services.
You create an XPC service as an individual target in your Xcode project. Each service gets its own sandbox—specifically, it gets its own container and its own set of entitlements. In addition, an XPC service that you include with your app is accessible only by your app. These advantages add up to making XPC the best technology for implementing privilege separation in an OS X app.
XPC is integrated with Grand Central Dispatch (GCD). When you create a connection, you associate it with a dispatch queue on which message traffic executes.
When the app is launched, the system automatically registers each XPC service it finds into the namespace visible to the app. An app establishes a connection with one of its XPC services and sends it messages containing events that the service then handles.
For more on XPC Services, read Creating XPC Services in Daemons and Services Programming Guide. To learn more about App Sandbox, read App Sandbox Design Guide.
libcache API is a low-level purgeable caching API. Aggressive caching is an important technique in maximizing app performance. However, when caching demands exceed available memory, the system must free up memory as necessary to handle new demands. Typically, this means paging cached data to and from relatively slow storage devices, sometimes even resulting in systemwide performance degradation. Your app should avoid potential paging overhead by actively managing its data caches, releasing them as soon as it no longer needs the cached data.
In the wider system context, your app can also help by creating caches that the operating system can simply purge on a priority basis as memory pressure necessitates. The
libcache library and Foundation framework’s
NSCache class help you to create these purgeable caches.
For more information about the functions of the
libcache library, see libcache Reference. For more information about the
NSCache class, see NSCache Class Reference.
In-Kernel Video Capture
I/O Video provides a kernel-level C++ programming interface for writing video capture device drivers. I/O Video replaces the QuickTime sequence grabber API as a means of getting video into OS X.
I/O Video consists of the
IOVideoDevice class on the kernel side (along with various related minor classes) that your driver should subclass, and a user space device interface for communicating with the driver.
For more information, see the
IOVideoDevice.h header file in the Kernel framework.
Beneath the appealing, easy-to-use interface of OS X is a rock-solid, UNIX-based foundation that is engineered for stability, reliability, and performance. The kernel environment is built on top of Mach 3.0 and provides high-performance networking facilities and support for multiple, integrated file systems.
The following sections describe some of the key features of the kernel and driver portions of Darwin.
Mach is at the heart of Darwin because it provides some of the most critical functions of the operating system. Much of what Mach provides is transparent to apps. It manages processor resources such as CPU usage and memory, handles scheduling, enforces memory protection, and implements a messaging-centered infrastructure for untyped interprocess communication, both local and remote. Mach provides the following important advantages to Mac computing:
Protected memory. The stability of an operating system should not depend on all executing apps being good citizens. Even a well-behaved process can accidentally write data into the address space of the system or another process, which can result in the loss or corruption of data or even precipitate system crashes. Mach ensures that an app cannot write in another app’s memory or in the operating system’s memory. By walling off apps from each other and from system processes, Mach makes it virtually impossible for a single poorly behaved app to damage the rest of the system. Best of all, if an app crashes as the result of its own misbehavior, the crash affects only that app and not the rest of the system.
Preemptive multitasking. With Mach, processes share the CPU efficiently. Mach watches over the computer’s processor, prioritizing tasks, making sure activity levels are at the maximum, and ensuring that every task gets the resources it needs. It uses certain criteria to decide how important a task is and therefore how much time to allocate to it before giving another task its turn. Your process is not dependent on another process yielding its processing time.
Advanced virtual memory. In OS X, virtual memory is “on” all the time. The Mach virtual memory system gives each process its own private virtual address space. For 64-bit apps, the theoretical maximum is approximately 18 exabytes, or 18 billion billion bytes. Mach maintains address maps that control the translation of a task’s virtual addresses into physical memory. Typically only a portion of the data or code contained in a task’s virtual address space resides in physical memory at any given time. As pages are needed, they are loaded into physical memory from storage. Mach augments these semantics with the abstraction of memory objects. Named memory objects enable one task (at a sufficiently low level) to map a range of memory, unmap it, and send it to another task. This capability is essential for implementing separate execution environments on the same system.
Real-time support. This feature guarantees low-latency access to processor resources for time-sensitive media apps.
Mach also enables cooperative multitasking, preemptive threading, and cooperative threading.
As of v10.8, OS X requires a Mac that uses the 64-bit kernel. A 64-bit kernel provides several benefits:
The kernel can support large memory configurations more efficiently.
The maximum size of the buffer cache is increased, potentially improving I/O performance.
Performance is improved when working with specialized networking hardware that emulates memory mapping across a wire or with multiple video cards containing over 2 GB of video RAM.
Because a 64-bit kernel does not support 32-bit drivers and kernel extensions (KEXTs), those items must be built for 64-bit. Fortunately, for most drivers and KEXTs, building for a 64-bit kernel is usually not as difficult as you might think. For the most part, transitioning a driver or KEXT to be 64-bit capable is just like transitioning any other piece of code. For details about how to make the transition, including what things to check for in your code, see 64-Bit Transition Guide.
Darwin offers an object-oriented framework for developing device drivers called the I/O Kit framework. This framework facilitates the creation of drivers for OS X and provides much of the infrastructure that they need. Written in a restricted subset of C++ and designed to support a range of device families, the I/O Kit is both modular and extensible.
Device drivers created with the I/O Kit acquire several important features:
If your device conforms to standard specifications—such as those for mice, keyboards, audio input devices, modern MIDI devices, and so on—it should just work when you plug it in. If your device doesn’t conform to a published standard, you can use the I/O Kit resources to create a custom driver to meet your needs. Devices such as AGP cards, PCI and PCIe cards, scanners, and printers usually require custom drivers or other support software in order to work with OS X.
For information on creating device drivers, see IOKit Device Driver Design Guidelines.
Network Kernel Extensions
Darwin allows kernel developers to add networking capabilities to the operating system by creating network kernel extensions (NKEs). The NKE facility allows you to create networking modules and even entire protocol stacks that can be dynamically loaded into the kernel and unloaded from it. NKEs also make it possible to configure protocol stacks automatically.
NKE modules have built-in capabilities for monitoring and modifying network traffic. At the cellspacing='0' cellpadding='5'>Table 6-1 Network protocols
802.1x is a protocol for implementing port-based network access over wired or wireless LANs. It supports a wide range of authentication methods, including TLS, TTLS, LEAP, MDS, and PEAP (MSCHAPv2, MD5, GTC).
DHCP and BOOTP
The Dynamic Host Configuration Protocol and the Bootstrap Protocol automate the assignment of IP addresses in a particular network.
Domain Name Services is the standard Internet service for mapping host names to IP addresses.
FTP and SFTP
The File Transfer Protocol and Secure File Transfer Protocol are two standard means of moving files between computers on TCP/IP networks.
HTTP and HTTPS
The Hypertext Transport Protocol is the standard protocol for transferring webpages between a web server and browser. OS X provides support for both the insecure and secure versions of the protocol.
The Lightweight Directory Access Protocol lets users locate groups, individuals, and resources such as files and devices in a network, whether on the Internet or on a corporate intranet.
The Name Binding Protocol is used to bind processes across a network.
The Network Time Protocol is used for synchronizing client clocks.
The Printer Access Protocol is used for spooling print jobs and printing to network printers.
For dial-up (modem) access, OS X includes PPP (Point-to-Point Protocol). PPP support includes TCP/IP as well as the PAP and CHAP authentication protocols.
The Point-to-Point Protocol over Ethernet protocol provides an Ethernet-based dial-up connection for broadband users.
The Secure/Multipurpose Internet Mail Extensions protocol supports encryption of email and the attachment of digital signatures to validate email addresses.
Service Location Protocol is designed for the automatic discovery of resources (servers, fax machines, and so on) on an IP network.
The Simple Object Access Protocol is a lightweight protocol for exchanging encapsulated messages over the web or other networks.
Apple Mobile Device Usb Driver Download Pc
The Secure Shell protocol is a safe way to perform a remote login to another computer. Session information is encrypted to prevent unauthorized access of data.
TCP/IP and UDP/IP
OS X provides two transmission-layer protocols, TCP (Transmission Control Protocol) and UDP (User Datagram Protocol), to work with the network-layer Internet Protocol (IP). (OS X includes support for IPv6 and IPSec.)
XML-RPC is a protocol for sending remote procedure calls using XML over the web.
OS X also implements a number of file-sharing protocols; see Table 6-4 for a summary of these protocols.
OS X supports the network technologies listed in Table 6-2.
Table 6-2 Network technology support
For the Ethernet ports built into every new Macintosh.
Also known as Gigabit Ethernet. For data transmission over fiber-optic cable and standardized copper wiring.
This Ethernet format uses 9 KB frames for interserver links rather than the standard 1.5 KB frame. Jumbo Frame decreases network overhead and increases the flow of server-to-server and server-to-app data.
Supports modem and ISDN capabilities.
Supports the 802.11b, 802.11g, 80211n, and 802.11ac wireless network technologies using AirPort Extreme and AirPort Express.
IP routing provides routing services for small networks. It uses Routing Information Protocol (RIP) in its implementation.
Enables a computer host to be physically connected to multiple data links that can be on the same or different networks.
Allows a network administrator to assign multiple IP addresses to a single network interface.
Allows computers to share a single System folder, which is installed on a centralized server that the system administrator controls. Users store their data in home directories on the server and have access to a common Applications folder, both of which are also commonly installed on the server.
Personal web sharing
Allows users to share information with other users on an intranet, no matter what type of computer or browser they are using. The Apache web server is integrated as the system’s HTTP service.
Network diagnostics is a way of helping the user solve network problems. Although modern networks are generally reliable, there are still times when network services may fail. Sometimes the cause of the failure is beyond the ability of the desktop user to fix, but sometimes the problem is in the way the user’s computer is configured. The network diagnostics feature provides a diagnostic app to help the user locate problems and correct them.
If your app encounters a network error, you can use the diagnostic interfaces of
CFNetwork to launch the diagnostic app and attempt to solve the problem interactively. You can also choose to report diagnostic problems to the user without attempting to solve them.
For more information on using this feature, see Using Network Diagnostics.
The file-system component of Darwin is based on extensions to BSD and an enhanced Virtual File System (VFS) design. The file-system component includes the following features:
Permissions on removable media. This feature is based on a globally unique ID registered for each connected removable device (including USB and FireWire devices) in the system.
Access control lists, which support fine-grained access to file-system objects.
URL-based volume mounts, which enable users (via a Finder command) to mount such things as AppleShare and web servers
Unified buffer cache, which consolidates the buffer cache with the virtual-memory cache
Long filenames (255 characters or 755 bytes, based on UTF-8)
Support for hiding filename extensions on a per-file basis
Journaling of all file-system types to aid in data recovery after a crash
Because of its multiple app environments and the various kinds of devices it supports, OS X handles file data in many standard volume formats. Table 6-3 lists the supported formats.
Table 6-3 Supported local volume formats
Mac OS Extended Format
Also called HFS (hierarchical file system) Plus, or HFS+. This is the default root and booting volume format in OS X. This extended version of HFS optimizes the storage capacity of large hard disks by decreasing the minimum size of a single file.
Mac OS Standard Format
Also called hierarchical file system, or HFS. This is the legacy volume format in Mac OS systems prior to Mac OS 8.1. HFS (like HFS+) stores resources and data in separate forks of a file and makes use of various file attributes, including type and creator codes.
Universal Disk Format, used for hard drives and optical disks, including most types of CDs and DVDs. OS X supports reading UDF revisions 1.02 through 2.60 on both block devices and most optical media, and it supports writing to block devices and to DVD-RW and DVD+RW media using UDF 2.00 through 2.50 (except for mirrored metadata partitions in 2.50). You can find the UDF specification at http://www.osta.org.
The standard format for CD-ROM volumes.
The NT File System, used by Windows computers. OS X can read NTFS-formatted volumes but cannot write to them.
UNIX File System, a flat (that is, single-fork) disk volume format, based on the BSD FFS (Fast File System), that is similar to the standard volume format of most UNIX operating systems; it supports POSIX file-system semantics, which are important for many server applications. Although UFS is supported in OS X, its use is discouraged.
The FAT file system is used by many Windows computers, digital cameras, video cameras, SD and SDHC memory cards, and other digital devices. OS X can read and write FAT-formatted volumes.
The ExFAT file system is an extension of the FAT file system, and is also used on Windows computers, some digital cameras and video cameras, SDXC memory cards, and other digital devices. OS X can read and write ExFAT-formatted volumes.
HFS+ volumes support aliases, symbolic links, and hard links, whereas UFS volumes support symbolic links and hard links but not aliases. Although an alias and a symbolic link are both lightweight references to a file or directory elsewhere in the file system, they are semantically different in significant ways. For more information, see Aliases and Symbolic Links in File System Overview.
Note: OS X does not support stacking in its file-system design.
Because OS X is intended to be deployed in heterogeneous networks, it also supports several network file-sharing protocols. Table 6-4 lists these protocols.
Table 6-4 Supported network file-sharing protocols
Apple Filing Protocol, the principal file-sharing protocol in Mac OS 9 systems (available only over TCP/IP transport).
Network File System, the dominant file-sharing protocol in the UNIX world.
Web-based Distributed Authoring and Versioning, an HTTP extension that allows collaborative file management on the web.
SMB/CIFS, a file-sharing protocol used on Windows and UNIX systems.
The roots of OS X in the UNIX operating system provide a robust and secure computing environment whose track record extends back many decades. OS X security services are built on top of BSD (Berkeley Software Distribution), an open-source standard. BSD is a form of the UNIX operating system that provides basic security for fundamental services, such as file and network access.
The CommonCrypto library, which is part of
libSystem, provides raw cryptographic algorithms. It is intended to replace similar OpenSSL interfaces.
Note: CDSA (Common Data Security Architecture) and OpenSSL are deprecated and their further use is discouraged. Consider using Security Transforms technology to replace CDSA and CommonCrypto to replace OpenSSL. Security Transforms, which are part of the Security framework, are described in Security Services.
OS X also includes the following security features:
Adoption of Mandatory Access Control, which provides a fine-grained security architecture for controlling the execution of processes at the kernel level. This feature enables the “sandboxing” of apps, which lets you limit the access of a given app to only those features you designate.
Support for code signing and installer package signing. This feature lets the system validate apps using a digital signature and warn the user if an app is tampered with.
Compiler support for fortifying your source code against potential security threats. This support includes options to disallow the execution of code located on the stack or other portions of memory containing data.
Support for putting unknown files into quarantine. This is especially useful for developers of web browsers or other network-based apps that receive files from unknown sources. The system prevents access to quarantined files unless the user explicitly approves that access.
For an introduction to OS X security features, see Security Overview.
Darwin includes all of the scripting languages commonly found in UNIX-based operating systems. In addition to the scripting languages associated with command-line shells (such as
csh), Darwin also includes support for Perl, Python, Ruby, Ruby on Rails, and others.
OS X provides scripting bridges to the Objective-C classes of Cocoa. These bridges let you use Cocoa classes from within your Python and Ruby scripts. For information about using these bridges, see Ruby and Python Programming Topics for Mac.
OS X provides full support for creating multiple preemptive threads of execution inside a single process. Threads let your program perform multiple tasks in parallel. For example, you might create a thread to perform some lengthy calculations in the background while a separate thread responds to user events and updates the windows in your app. Using multiple threads can often lead to significant performance improvements in your app, especially on computers with multiple CPU cores. Multithreaded programming is not without its dangers though. It requires careful coordination to ensure your app’s state does not get corrupted.
All user-level threads in OS X are based on POSIX threads (also known as pthreads). A pthread is a lightweight wrapper around a Mach thread, which is the kernel implementation of a thread. You can use the pthreads API directly or use any of the threading packages offered by Cocoa. Although each threading package offers a different combination of flexibility versus ease-of-use, all packages offer roughly the same performance.
In general, you should try to use Grand Central Dispatch or operation objects to perform work concurrently. However, there might still be situations where you need to create threads explicitly. For more information about threading support and guidelines on how to use threads safely, see Threading Programming Guide.
The X11 windowing system is provided as an optional installation component for the system. This windowing system is used by many UNIX applications to draw windows, controls, and other elements of graphical user interfaces. The OS X implementation of X11 uses the Quartz drawing environment to give X11 windows a native OS X feel. This integration also makes it possible to display X11 windows alongside windows from native apps written in Cocoa.
Software Development Support
The following sections describe some additional features of OS X that affect the software development process.
Binary File Architecture
The underlying architecture of OS X executables was built from the beginning with flexibility in mind. This flexibility became important as Mac computers have transitioned from using PowerPC to Intel CPUs and from supporting only 32-bit apps to 64-bit apps. The following sections provide an overview of the types of architectures you can support in your OS X executables along with other information about the runtime and debugging environments available to you.
When OS X was first introduced, it was built to support a 32-bit PowerPC hardware architecture. With Apple’s transition to Intel-based Mac computers, OS X added initial support for 32-bit Intel hardware architectures. In addition to 32-bit support, OS X v10.4 added some basic support for 64-bit architectures as well and this support was expanded in OS X v10.5. This means that apps and libraries can now support two different architectures:
32-bit Intel (
64-bit Intel (
Although apps can support all of these architectures in a single binary, doing so is not required. The ability to create “universal binaries” that run natively on all supported architectures gives OS X the flexibility it needs for the future.
Supporting multiple architectures requires careful planning and testing of your code for each architecture. There are subtle differences from one architecture to the next that can cause problems if not accounted for in your code. For example, some built-in data types have different sizes in 32-bit and 64-bit architectures. Accounting for these differences is not difficult but requires consideration to avoid coding errors.
Xcode provides integral support for creating apps that support multiple hardware architectures. For information about tools support and creating universal binaries. For information about 64-bit support in OS X, including links to documentation for how to make the transition, see 64-Bit Support.
OS X was initially designed to support binary files on computers using a 32-bit architecture. In OS X v10.4, however, support was introduced for compiling, linking, and debugging binaries on a 64-bit architecture. This initial support was limited to code written using C or C++ only. In addition, 64-bit binaries could link against the Accelerate framework and
Starting in OS X v10.5, most system libraries and frameworks are 64-bit ready, meaning they can be used in both 32-bit and 64-bit apps. Frameworks built for 64-bit means you can create apps that address extremely large data sets, up to 128 TB on the current Intel-based CPUs. On Intel-based Macintosh computers, some 64-bit apps may even run faster than their 32-bit equivalents because of the availability of extra processor resources in 64-bit mode.
There are a few technologies that have not been ported to 64-bit. Development of 32-bit apps with these APIs is still supported, but if you want to create a 64-bit app, you must use alternative technologies. Among these APIs are the following:
The entire QuickTime C API (deprecated in OS X v10.9; in a 64-bit app, use AV Foundation instead)
HIToolbox, Window Manager, and most other user interface APIs (in general, use Cocoa UI classes and other alternatives); see 64-Bit Guide for Carbon Developers for the list of specific APIs and transition paths.
OS X uses the LP64 model that is in use by other 64-bit UNIX systems, which means fewer headaches when porting from other operating systems. For general information on the LP64 model and how to write 64-bit apps, see 64-Bit Transition Guide. For Cocoa-specific transition information, see 64-Bit Transition Guide for Cocoa.
Object File Formats
OS X is capable of loading object files that use several different object-file formats. Mach-O format is the format used for all native OS X app development.
For information about the Mach-O file format, see OS X ABI Mach-O File Format Reference. For additional information about using Mach-O files, see Mach-O Programming Topics.
Debug File Formats
Whenever you debug an executable file, the debugger uses symbol information generated by the compiler to associate user-readable names with the procedure and data address it finds in memory. Normally, this user-readable information is not needed by a running program and is stripped out (or never generated) by the compiler to save space in the resulting binary file. For debugging, however, this information is very important to be able to understand what the program is doing.
OS X supports two different debug file formats for compiled executables: Stabs and DWARF. The Stabs format is present in all versions of OS X and until the introduction of Xcode 2.4 was the default debugging format. Code compiled with Xcode 2.4 and later uses the DWARF debugging format by default. When using the Stabs format, debugging symbols, like other symbols are stored in the symbol table of the executable; see OS X ABI Mach-O File Format Reference. With the DWARF format, debugging symbols are stored either in a specialized segment of the executable or in a separate debug-information file.
For information about the DWARF standard, go to The DWARF Debugging Standard; for information about the Stabs debug file format, see STABS Debug Format. For additional information about Mach-O files and their stored symbols, see Mach-O Programming Topics.
Since its first release, OS X has supported several different environments for running apps. The most prominent of these environments is the dynamic link editor (
dyld) environment, which is also the only environment supported for active development. Most of the other environments provided legacy support during the transition from Mac OS 9 to OS X and are no longer supported for active development. The following sections describe the runtime environments you may encounter in various versions of OS X.
dyld Runtime Environment
dyld runtime environment is the native environment in OS X and is used to load, link, and execute Mach-O files. At the heart of this environment is the
dyld dynamic loader program, which handles the loading of a program’s code modules and associated dynamic libraries, resolves any dependencies between those libraries and modules, and begins the execution of the program.
Apple Mobile Device Usb Driver Download Mac Os
Upon loading a program’s code modules, the dynamic loader performs the minimal amount of symbol binding needed to launch your program and get it running. This binding process involves resolving links to external libraries and loading them as their symbols are used. The dynamic loader takes a lazy approach to binding individual symbols, doing so only as they are used by your code. Symbols in your code can be strongly linked or weakly linked. Strongly linked symbols cause the dynamic loader to terminate your program if the library containing the symbol cannot be found or the symbol is not present in the library. Weakly linked symbols terminate your program only if the symbol is not present and an attempt is made to use it.
For more information about the dynamic loader program, see the
dyld man page. For information about building and working with Mach-O executable files, see Mach-O Programming Topics.
Install Apple Mobile Device Usb
The tools that come with OS X provide direct support for developing software using the Swift, C, C++, Objective-C, and Objective-C++ languages along with numerous scripting languages. Support for other languages may also be provided by third-party developers. For more information on the key features of Swift and Objective-C, see Development Languages
Apple Mobile Device Usb Driver Download Mac 10 11