Darwin • 56:41
An in-depth look at how FireWire, the Emmy award-winning industry standard interface, works on Mac OS X. This session explains how the FireWire software stack is deployed and provides details regarding kernel and user space drivers. Make sure your products get the best possible performance with the SCSITaskUserClient, SBP-2, Isoch, digital video and Mac OS X drivers.
Speaker: Eric Anderson
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Okay, hi everybody. Welcome to 1.1.5 FireWire In-Depth. This is a gigantic room, so feel free to come forwards if you want to be a little closer. We have a lot of material to cover today, so let's get started. This session is all about writing software for FireWire devices, obviously in Mac OS X.
We're going to have a very detailed look at the software architecture, how all the parts fit together and what they do for you. We will specifically identify things that we've added since last year that you can now use in your software development. And then we'll look at things that we're still working on, things that we are going to be adding in the future to expand even further the capabilities of what you can do on FireWire. Also, this year we've added a section on how-to organized by device. So if you've got some device and you want to know how to get started, we'll list all the different options that you have.
The slides are divided into five categories. The first is probably the longest, a detailed study of how all the FireWire parts in Mac OS X work. Then, specifically list the changes to FireWire since WWDC last year. Then we cover the planned future services, do that how-to section that I talked about, and we'll wrap up with a brief review of all of the developer services that we have available to help you develop products using FireWire on Mac OS X. Plus, we'll leave plenty of time for Q&A.
Okay, in Mac OS X, FireWire is a kernel service. There's a variety of reasons why FireWire belongs in the kernel, but one that by itself is good enough is that to boot from a FireWire disk, FireWire would have to be in the kernel because of the chicken and egg problem. So it's in there.
FireWire is in the kernel in the form of I/O kits architecture, so it leverages all of the I/O Kit services that other family interfaces provide, like USB, SCSI, and so on. So lots of stuff it has in common with other services. It's implemented as a set of kernel extensions. We will go over what those are and what they do.
Now, having just explained that it's in the kernel because it has to be there, most of this presentation will be explaining how you can write your software out in user space instead of writing in the kernel. There's lots of advantages to working in user space, and for most of you, we believe we've provided the services that will make it possible to do that. So we'll talk about that at length.
I'm going to show a diagram of the core FireWire services. We're going to start at the bottom with hardware. From a FireWire point of view, that's where everything begins. If there is no FireWire hardware, then our software isn't running and nothing happens. So at the bottom of the diagram, this item marked hardware, that represents the FireWire interface in a Macintosh system.
There could be more than one, but we'll just focus on one at a time. Specifically, in 1394 terms, the interface consists of a link and a PHY. These won't be covered in detail because they're hardware, but the link is the part that knows how to form packets. It does checksums. It does DMA.
The PHY is the counterpart that knows how to actually wiggle the wires around in order to send data serially on the cable. So the two together form the FireWire interface that backs up the ports that you see on our products. So when I/O Kit discovers that the Mac has a FireWire port by looking for PCI devices, the discovery of that hardware triggers all of the processes that follow.
By the way, that interface could be... It could be a PCI card. It could be a Cardbus card. It could also be the built-in FireWire that we now have in our CoreLogic chipset on all of our currently shipping systems. For all of these, they would all load the same way, and they would all use the same software.
So when I/O Kit finds that hardware, it starts a process of filling in the core FireWire services, which will be shown in this box. And then we're going to build a bunch of other services up on top of that as the diagram grows. Strictly speaking, the part that loads first is the device driver for the hardware interface itself. In most cases, this is Apple FW-OHCI.
That's the open host controller interface. It corresponds to a PCI or PCI-like, such as Cardbus, interface link chip found in the hardware. This is the driver that takes interrupts, programs the DMA, handles physical to virtual memory issues. It does all of the lowest level software work for controlling the FireWire hardware so that we can send and receive packets and do interesting things on the bus.
The layer above that, that gets loaded in response to OHCI loading, is IOFireWire family. Technically, this should really be labeled IOFireWireController, but I've labeled it as Family because the Family is the kernel service that binds all of this together and collectively provides these services. The family is the common layer for all of the things using FireWire, to multiplex through. For example, the FireWire bus may have many different devices connected to it.
Many different drivers and applications may be loaded that want to talk to those devices. But there's only one hardware interface, so they're all going to have to share. They all have to peacefully coexist and do their thing without stepping on each other. So the family's job is to provide that multiplexing point where everybody can use the bus in their own way, but do it in a cooperative way. The family provides additional services that are bus general, such as scanning for new devices, in order to start the process of loading drivers.
As the family finds devices on the FireWire bus, it creates IO FireWire device objects. There's one of these created for each node on the FireWire bus that has a configuration ROM that we're able to read. Most nodes fall into this category. The exception would be, there's two. You could have a FireWire hub. In FireWire, the hubs are like Ethernet hubs. They're completely self-configuring and self-active. They don't require drivers. They don't require software to turn them on. So a FireWire hub on the bus wouldn't create IO FireWire device because we wouldn't find any config ROM in it.
The second exception would be some FireWire device that is turned off, and so it's acting like a hub. For example, our G4 tower, if you turn it off, its FireWire chips are all turned off, except for the PHY, which continues to run from AC power. That's so that if you've plugged in two devices like a camera and a TV, they can still talk to each other through the hub that's acting in that PHY, even though the computer's turned off.
That would be a case of a device where it is a node on the bus, but nobody can read a configuration ROM from it, so we would not create an IO FireWire device object for that. Then, for the devices where we do find a configuration ROM, we create IOFireWireUnit. This is the object that represents a unit directory discovered in the configuration ROM. Most devices will have at least one. Occasionally, a device might have more than one.
And that corresponds to a unit directory. The unit directory in the configuration ROM expresses the first level of information about what actual function some device has. So this is the layer at which things start to differentiate into disks or camcorders or printers or something else. So those four together form the core FireWire services because within this box we haven't done anything that's device-specific.
Nothing was specific to DV or to hard drives. It's all just generic FireWire services supporting multiplexing of various devices and drivers and supporting the discovery of the first level of device functions. We'll come back to this and build on it a great deal, but first let's review what those services were.
We'll start with IO FireWire family because that's, as I said, that's the part that really brings everything together. The family makes everybody get along. All the drivers, all the devices can share a single interface onto the bus and all do their thing without even knowing about each other. For example, with iMovie, you could be capturing DV video from a FireWire camcorder, recording it onto a FireWire hard drive on the same bus.
Both will be sending packets furiously to accomplish their thing, but they don't have to know about each other. The family keeps them separate and makes sure they each do their own thing. For example, iMovie is not bothered with hard drive packets, and the hard drive isn't bothered with commands for the camcorder.
They just don't see each other. In addition to keeping everyone playing well on the bus, the family does the bus scanning. So if a new device is plugged in, the family will come along and look at it and see what it is, create the device and the unit objects, and then let the matching start.
Driver matching is listed there. It's not really done by the family. The family enables it. The family finds the information that will be needed for matching, but then it hands it over to I/O Kit, so the matching happens just like any other I/O device in the kernel in Mac OS X.
The family handles GUID and topology tracking. We'll talk more about GUIDs later, but this means as devices are added to or removed from the bus, the family keeps track of where they went, so that if the user is rearranging the bus, we don't lose track of some disk, for example, and suddenly unmount its file system. We can keep track of the devices even though the bus has hot plugging activity going on. And the last item, perhaps the most important, packet transmit and receive. The family is the funnel for all packet activities between drivers and their devices.
I mentioned driver matching and loading. FireWire doesn't do its own driver loading or matching. FireWire just gathers information about the devices by reading their configuration ROMs and publishes this information in the I/O registry. Then FireWire asks I/O Kit to activate its general matching service to find drivers to load for these devices that were discovered on the bus. And this may be an iterative process if, in doing so, more information is learned about the devices.
So this means that your matching mechanism is very flexible. I/O Kit allows, for example, active probing. A driver can run, take a look at the device and make a decision on the spot as to whether it's really the best choice for that device or not. So this is really more powerful and more flexible than what we had in Mac OS 9. It's also more uniform because the actual mechanism is shared with USB, ATA, SCSI, PCI, all kinds of other interfaces.
Some of the information that we put in the IO Registry is the GUID, which I mentioned before. That stands for Globally Unique ID. It's a 64-bit serial number that we read from the device. This lets us tell one device from the next. For example, if the customer has connected four FireWire hard drives, perhaps they want to make a RAID, they might be identical in every way, except they have different GUIDs. And this way we can be sure we're sending each packet to the right drive, because nothing would work if we lost track of who was who.
Additionally, we find a vendor ID, model name. In fact, we take usually the entire configuration ROM and just put that in the I.O. registry to make it easy to access. Finally, the family scans for unit directories, that was the top object in the modules I showed you, and creates an entry in IO registry for each one of those. The unit directory is where we get the first indication of protocol information for a device, which gives us a hint as to what drivers to load or how to take a closer look at the device to really learn what it does and what the best driver is.
At the very bottom of the software stack, we had Apple FW-OHCI. On a couple of very old machines that we do support, the blue and white G3 and the very first G4 towers that had PCI graphics, we have an earlier generation FireWire chip called PCI-LINX. So we do support that in Mac OS X.
On those systems, you'd find a driver called Apple LINX instead of Apple FW-OHCI. But those two drivers both provide the same service interface up to the family, so there's no hardware-specific knowledge past that point. So, except for those systems, everything else uses Apple FW-OHCI, and that includes all the products that we sell today. OHCI stands for Open Host Controller Interface. It's the industry standard interface. It's the only interface that we have for a FireWire controller, at least in a personal computer. And there's lots of vendors that provide good quality OHCI silicon, such as on PCI cards and CardBus cards.
By the way, if you are going to use an add-in card, for example, in one of our older G3s that doesn't have FireWire, use OHCI and be sure that you've selected one that fully complies with both the OHCI standard and the 1394 standard. This is not a level at which we tolerate bugs because there's lots of perfectly good controllers out there.
This is also the only part of the stack that is not in Darwin and not open-sourced. The OHCI driver has to be shared by everybody. The camera driver, the disk driver, scanners, printers, anything that's on the bus. That means it's a really bad place to try to insert custom functionality for your particular application. There's better places to do that.
Okay, the next section is additional services. I talked about the core that were not specific to any device or protocol. Now we're going to look at the additional services that we provide for the most common kinds of device and protocol on top of the core services. First of all is the FireWire user client.
Strictly speaking, this should be called a device interface, but we've gotten stuck on the name user client, so we just use both. This is a way for application-level software to talk directly to FireWire. It's not protocol-specific, it just exports the basic commands like send a packet, allocate some address space, read the configuration ROM. That exists in a package called iofirewirelib.plugin.
We also provide a family for SBP-2. That stands for Serial Bus Protocol. It's the protocol used by mass storage devices on FireWire, most printers, all scanners that I know of, some still cameras. It is the high performance optimized protocol that takes advantage of FireWire's architecture to get really high performance.
This is provided in the kernel because, as I said, it's used for storage, so we would have to have it to boot from a FireWire disk. But there's a user client that exports all of the same services out into application space. So those two parts are listed there.
The other major protocol on FireWire is AVC, the Audio Video Command Protocol. We have a family for that in the kernel as well as a user client. And the names and the architecture are similar to SBP. Though AVC is used for things like DV cameras, TVs, DVD players, and so on.
So as you probably noticed, our motto is everything has a user client. Even though all of our services are in the kernel, we've made everything available out in user space. So it should really be possible for most of you to do all of your development in user space. And if you've tried it already, you know this, it's much easier doing this in user space. If you have some problems with your driver at first and it crashes, you'll take out an application. The system will survive.
The debugging tools for user space are much more convenient to use. And if you're doing iterative development on your driver or your app, you can reload it, rerun it as many times as you like, rather than rebooting the computer every time. So we've done a lot of work to make it possible for you to write software in user space.
That should be your target. If you find that you think you need to work in the kernel, talk with us, because you can, but maybe you've overlooked something or we've overlooked something. And there's a way to do that. do what you need to do in user space instead.
Now, let's go back to the picture. There's the core services. Now we're going to fill in all the additional things that I've talked about so you can see how they fit together. We're going to need more room, so I'm going to simplify the names and now I'm going to push things around so I can build on it.
You can see I've added a number and a letter to the device and the unit. We're going to have more of those. Let's start with the simplest case. An application that wants to talk directly to a FireWire device using the plain user-client interface. It's not SBP, it's not ABC, or for some reason you don't want to use those layers, you just want direct access.
Your application runs way up in the clouds in user land. And your application loads the FireWire lib that we showed earlier. The lib knows how to establish a connection with the kernel, crossing, here it is, the user kernel boundary. And as a result, in the kernel, the user client gets loaded and opened as a driver for the unit in that device. Now your application can use the APIs in the FireWire lib to communicate on FireWire. From application space. The user client is really just a pass-through driver that knows how to move your commands and data in and out of the kernel.
Let's suppose that your device actually is a multi-function device, and in addition to Unit A, which is doing some custom thing that you talk to from an application, you also have a Unit B. And let's say that this unit represents just an ordinary disk drive function. We would have discovered that the unit directory indicated the SBP-2 protocol. So in the kernel, the SBP-2 family loads against this part of the device. The first part of that, SBP-target, represents the unit directory itself. And every SBP device has at least one logical unit, occasionally more than one. That's represented by an SBP-LUN object.
I said this case was a disk drive. Disk drivers are in the kernel, so that will have been loaded by I/O Kit right there in the kernel doing its thing. So here you can see a case of a single FireWire device where we have one driver running in the kernel, an application running out in user space. They're both able to hook into the device and do their thing without interfering with each other.
Let's add another device to the FireWire bus. It will have a single unit. This will also be an SBP device, but let's say it's a scanner. The SBP services still load in the kernel because that's where they exist. The scanner has a logical unit. But now you come along and you run some application, say Photoshop, up in application space.
But rather than open the all-purpose FireWire lib, we can use a much more appropriate API, which is the SBP-2 user client. So the lib is the part of that that lives in application space. And when it gets opened, it establishes a connection with its corresponding user client in the kernel, which acts as the driver for that device. Now the application can communicate with the scanner, again running all of its logic up in user space, using the kernel just as a transport to move stuff in and out. of the device.
Finally, let's connect a device that is a DV camcorder. Again, it has a unit directory indicating the AVC protocol. So, we load the AVC family corresponding to that. Something new I'll talk about later is that we now do subunit enumeration, so we will create a subunit corresponding to the camcorder's specific functionality.
Now, an application like iMovie comes along. Through QuickTime, it opens up the AVC lib out in user space, which hooks into the AVC user client and is able to directly send device control commands, for example, to the camera. It doesn't fit in the picture, but in the iMovie QuickTime case, there's actually also a connection to the plain FireWire user client, which is how the isochronous data, the real-time DV, is captured or exported. So, it's a very flexible architecture.
So, as you can see from this figure, This should re-emphasize the point that everything's available in user space, but it also shows something else. What we have in user space is just glue that hooks into the kernel. If you look at the center two columns, we have a disk driver running in the kernel, and we have a scanner running out in application space, but they're both using the same SBP family in the kernel, so there's not a separate or second SBP implementation in user space. There's just one, and it's in the kernel, so it's always going to work the same way. So that helps keep things simple, even though you have the flexibility to access it from the kernel or from user space.
Okay, there's more, but it won't fit, so let's unplug two devices. You didn't see it earlier, but this was actually here all along. There just wasn't room. In addition to creating device objects for every device on the bus, we will always have one local node object attached to the family. Essentially, this represents the Mac itself. The Mac is also a node on the FireWire bus, but it doesn't discover itself as a device or load a driver for itself.
Instead, we just create this local node object as a place where you can hook in if you want to talk to FireWire in general, rather than talking to one of the devices in particular. Suppose you had an application that wants to show a picture graphically depicting the objects on the FireWire bus. That application would like to receive the topology map. It might like to read the configuration ROMs on the devices. It might even do some further dialogue with the devices.
You can run that application out in user space, use the plain FireWire lib. It will trigger the user client to get hooked into the local node. Now you can do anything that you could do to an ordinary FireWire device, but you can do it in a bus-general way.
The local node is there even if there are no devices on the FireWire bus. Your application won't be showing a very interesting picture, but you can still run and talk to the bus without having somebody else out there. So it's very general. It means that you don't have to track down some random device on the bus and try to talk through it. If you did that, you might lock out the driver that's trying to use that device. So the local node provides a second path in where you can access FireWire without getting in anybody else's way.
Okay, now let's look at some of the things we've changed since last year. We covered these at a high level on Monday. I'm going to go into more detail about them today. SCSITaaskUserclient. This is the answer to about half the questions we get on our mailing list. There's a lot of devices out there that on FireWire use SBP-2, but architecturally they are SAM compliant. That's the SCSI architecture model. This includes things like CD-ROM burners, printers, scanners, certain still cameras.
It's been possible to access these devices through the SBP-2 family in the kernel or the SBP-2 user client in application space. But that exposed you to a lot of 1394 details that may not have really been interesting if you just wanted to control your device. The SCSITaaskUserClient, in general, is a much better way to access these devices. Now, this was just finished last year at WWDC, but it's really only become available well into the year since then. So it wasn't really possible to ship things on it a year ago.
If you have a device of this type and you haven't already looked at SCSITaaskUserclient, this is probably what you should be using. It's very high level. You can ignore logins, reconnects, bus resets. You can concentrate on picking commands to send to your device to make it do its thing, rather than worrying about the FireWire details. On our mailing list, almost everybody who we send off to SCSITaaskUserclient, they report back that that's what they wanted and they stop asking about SBP-2.
Another thing where we've made big changes since last year is the isochronous services in the user client. If you're new to FireWire, isochronous is the word that describes real-time transfer on FireWire, such as the capturing of DV from a camera. The opposite is asynchronous, which is the kind of traffic we use for FireWire disk drives. It's not real-time, it just happens at any time, thus asynchronous.
The user client now is very capable of doing isochronous transfers, so you don't have to go into the kernel to accomplish that. You can send and receive these real-time streams using DCLs. DCL is Data Stream Command Language. It's an abstract DMA program that allows you to describe your real-time transfer at a very fine-grained packet-by-packet level.
It's done this way because the FireWire real-time transfer sends or receives 8,000 packets per second. So you don't want to be calling some API 8,000 times a second to send or receive a packet. Instead, you write this DMA program in advance and turn it on, and it runs at 8,000 packets per second, periodically updating you, saying that it has produced data or it needs to be refilled with more data. The same thing worked in Mac OS 9. Largely, you can copy your programs directly from Mac OS 9 to Mac OS X. There's minor changes, such as in the way the timestamps work, but nothing that should force you to re-architect.
Very importantly, even if your DCL is running, even if you're using the user client, your DCL itself runs in the kernel. And all of your memory is used directly. It's mapped right into the DMA. So even though you're out in application space, there's no penalty copying data out of the kernel. The performance can be just as good as what you get in the kernel.
In our SDK, there is sample code for the IIDC, also known as DCAM, type of web camera, such as the iBot or the ADS Pyro. We, as we talked about Monday and I think is coming up, we have a much better driver that we're including in Jaguar, but this sample code should be a very good start for writing DCLs and learning how to control them. It's not such a good sample for how to fit into QuickTime, but it's a good sample of how to work with FireWire.
Another thing we've made a lot of changes in since last year is the AVC user client. Last year it was really just a stub that iMovie could hook into, but it wasn't general purpose. Now we have made it fully the equal of the services available in the kernel, and to prove this, in Jaguar, we are moving the DV driver itself out of the kernel into user space.
This shows that we can get frame accurate, 30 frame per second DV capture over long periods, suitable for not just iMovie, but Final Cut Pro, with our driver running in user space. So if you're not convinced that this is a good idea, take a look at what we've done, because it really works pretty well.
Additionally, the ABC User Client Support, well, FCP is really strictly what this should be called. The Function Control Protocol is the bottom part of ABC. It defines how to send and receive these commands in 1394 packets. ABC defines higher level things, such as what the commands are and associated things that work with them, like the next bullet. So if you're looking for FCP, it's in here.
Significantly, we've added that you can now either send or receive these. You can send AVC commands and receive responses from some device, like controlling a camera, or you can receive AVC commands from some device and send responses to those. For example, if you wanted to implement a virtual camera or TV on your Mac.
Also in the ABC UserClient is access to plug control registers. The ABC spec defines these 32-bit registers at a certain fixed address. These registers contain information about active isochronous communication to or from a device. So any two devices exchanging data will have corresponding sets of plug control registers. The register indicates what channel it's on, how fast it's going, how many people are listening to it.
So to be fully compatible with AVC, you need these, and it's now possible to allocate them and use them in the AVC user client. CMP, shown there, is Connection Management Protocol. That's the series of procedures that you perform on plug control registers to set up and tear down connections.
As I showed in the big diagram, we now enumerate subunits in AVC devices. AVC, the designers really didn't, they weren't into the spirit of 1394. They have a config ROM with a unit directory, but only because they had to. They don't put information in there about what the device does. Instead, you have to inquire using an AVC command to ask the device, hey, what do you really do? So, since all AVC devices need that in order to get anywhere, we provide that standard. And we publish the information in the I/O registry.
So, it's similar to what SBP does in picking protocol information out of the config ROM. It just comes from a different place. But it leads to the same thing. You can use the information in I/O registry to further match and discover what the device does. Finally, we've added something called asynchronous connections.
This is sort of a poor man's SBP-2. It's a serial transport for moving blocks of asynchronous data within the framework of AVC. It's not very fast. It's somewhat clunky compared to SBP-2. But if your main thing is DV and you also want to move some still images, it's good enough.
So, we support that. There are cameras coming out that use it, for example, for still image transport. It's there, but it shouldn't be your first choice. If someone's already made a device and it requires this, fine, go ahead and use it. If you're designing something new, you should really look to SBP-2 instead if you want good performance.
Speaking of which, in SBP-2, those really old Macs I described earlier, the blue and white G3 and certain G4 towers, use an earlier generation FireWire controller. One of the reasons we aren't shipping that anymore is that it had a tendency to underflow when transmitting packets. In other words, we would ask it to send a packet, and it would start sending the packet, and then in the middle, it would run out of data, and the packet would be damaged.
That triggers what's called "ac data error" on the bus. It's not fatal, the device can recover from it, but the device will recover a lot faster in some cases if we retry the packet without being asked. So, Mac OS 9 did that. We have changed SBP-2 in Mac OS X, so it will do that too. So, the performance on those older machines should now be completely the same. We've added a bunch of stuff that is exclusive to Mac OS X in SBP-2.
We've added a flag called "Fails on ACK Busy." You shouldn't set this flag without knowing what it does, but in congested situations, some devices will get better performance if we pace their I/Os a little bit more and take some steps to avoid ACK Busy. So, for best possible performance, the disk driver, for example, will set this flag when it's appropriate. Most people won't need to set it, you'll just notice higher performance from your drives.
Physical orbs. This is pretty esoteric SPP2 stuff. We've added the option, you have a flag to control this, to use physical memory for your orbs rather than FireWire virtual memory, also known as a pseudo-address space. This takes out one interrupt in the processing of an orb because the FireWire OHCI controller can respond to the device automatically, that's why it's called physical, rather than sending the request up to software.
Depending on the dynamics of your I/Os, you may see a 5% increase in disk speed when this is turned on. So we will be using this in our disk driver. If you're doing a high-performance device, you may want to turn this on. For a low-performance device, you may want to leave this off because if you're debugging with a packet analyzer, it's much easier to spot the orbs on the bus if they're non-physical because the addresses are very regular and easy to see.
A related change to orbs is unlimited page table size. The page table for an SBP-2 orb has to be physically contiguous. So in Mac OS 9, we limited it to 4 kilobytes, and that limit carried over in Mac OS X until now. If you have a gigantic orb, which might be used, say, by a scanner that's going to scan a 100 megabyte page with a single command, we will now use a pseudo-address space to write out the entire page table, no matter how large it is, so that you can get basically unlimited transfer size in any orb.
It will be slightly slower because it's the opposite of physical orbs. The page table accesses are now going through software. But for something like a scanner that's probably not sacralized... ...or that's not saturating the bus, you'll probably prefer to have unlimited transfer size rather than 1% more performance that the scanner probably wouldn't use.
Finally, in SBP-2, we've added an automatic retry feature for logins. There are some cases in which you need to try a few times to get logged into a device. Rather than forcing every driver to do it in their own way, we've added an optional feature to do it for you. And there's a configurable delay so that if your device needs a little time to think about it, we can accommodate that.
Since last year, we have distributed five new SDKs for Mac OS X. Each one of these contains the latest binaries, the latest sample code, the latest source code, all the documentation that we have, all the tools that we have. We're now working to integrate that with the Mac OS X developer tool CD so that everybody will have it, whether they go looking for it or not. But it will continue to be available for download on our website, where you can get the very latest. It's always been free public download. You don't have to sign up for anything.
The SDKs are the biggest product for you guys, the developers, that comes out of this team. So we spend a lot of time on that. Consequently, we'd love to get your feedback, especially at the feedback forum tomorrow or today during Q&A if there's time. What in there is helpful to you? What is not helpful? What do you just not understand? What can we do to make those better? Because we spend a lot of time on those.
One thing we've done since last year is added a lot of HeaderDoc into the, well, it's in the SDK and it's also in all the files. Almost 100 classes, methods, and so on documented. This calls out some of the highlights. So hopefully this makes things a bit more clear.
I mentioned it on Monday, we also have a whole new book on user clients. There's a link in here for that. As I mentioned on Monday, we have a new driver for IIDC type cameras, also known as DCAM. It's very high performance, it's much better than what we had in the sample code in the SDK.
Now we'll go through some of the things that we're still working on, things that we'd be interested in working with you on over the next few months or the next year. There's a lot of interest in IP1394. This is the internet protocol, commonly known as TCP/IP, though that's not completely accurate.
There is a standard in as much as the IETF ever standardizes anything, which means there's an RFC available on the web. You can go to IETF.org and pick up RFC 2734 and it shows how to transport the internet protocol on FireWire. It's not super complicated. Basically, you send an ARP packet to find out somebody else who's out there, just like on Ethernet. And what you get back is a FireWire address of a FIFO, where you can send packets for a particular device.
[Transcript missing]
Here's a picture that shows how the IP1394 datagram is formed. It's encapsulated in a block write packet. The top half of the picture shows the standard block write header for a packet on 1394, including its address, so that FIFO high and FIFO low are the address that was returned from the ARP process. Then the payload portion of the packet simply has a 32-bit encapsulation header that covers things like IP fragmentation, followed by an IP datagram, which can be of variable sizes. So it's really pretty straightforward.
We're also doing active work on audio for FireWire. This generally means ISO 61883, which defines the transport from moving audio data in real time across FireWire. In case you haven't figured this out, the FireWire we have today at S400 can carry 400 channels of CD quality music, or any kind of audio. So there's tremendous potential there for audio applications.
We are working on supporting the audio subunit and the music subunit, both of which are part of AVC, supporting MIDI over this transport, and providing services for SMPTE timecode. If you're interested in developing drivers for this, we have more to talk about, so please get in contact with us.
We're also spending some time on 1394b. As I described Monday, this standard is finished. It's been published by the IEEE, or it's being published. Almost all of the changes for 1394b are in the PHY. This spec was designed by a lot of software people, so they put all the changes in the hardware. My hat's off to them.
It's very unlikely you'll have to change anything in software. We have to change a few things in the family and the OHCI driver. For example, simply to program the DMA to transmit at higher speeds, we have to program in some different speed codes. The packets can be larger in 1394B so that we get high performance. For asynchronous, that's limited to 4K. I'll show a table on the next slide.
We have to allocate some more buffer memory because if things are going twice as fast, we may get twice as much stuff piled up before we can sort it out. And we have some work to do in sorting out the topology of the devices based on the self-ID packets. I'll show some more detail about that. These are the packet sizes that are supported by 1394 at the various speeds. The top shows 100, 200, and 400. These are the sizes that have been set for years. Nothing has changed there.
As we move to the higher speeds that 1394B provides, the packet sizes keep going up. For isochronous, they continue to double. For asynchronous, it's clamped at 4096. And this was done because it's generally felt that with the optimizations in 1394B, which eliminate, for example, all of the idle gaps on the bus, it's no longer necessary to keep doubling the packet size to keep the performance up.
And it's inconvenient if packets have to be retargeted. And they're, for example, 16 kilobytes. That's an awful lot of data to throw away if just one bit went bad. So 4096 is the cap for asynchronous packets, but that should in no way limit the performance that you can get with asynchronous packets on 1394B.
I talked about topology. This figure shows a self-ID packet. This is not actually unique to 1394B. They look like this in 1394A also. The self-ID packet is the very most primitive level of information that we receive about each device, telling us how it's hooked into the bus. For example, on the right-hand side, P0, P1, P2 represent the first three ports on the device and whether or not they are connected to some other device. By receiving all these packets and doing some math, we can figure out who's plugged into who.
[Transcript missing]
There's actually two ways to do this. You can read the port registers or you can simply start sending packets to the device at faster and faster speeds and find out what works. Each one has its advantages. It's possible that you'll see both in use on the bus. This is not something you'll ever have to do. We will do this in the family, but you may see this activity in Firebug and you may wonder what's going on.
Okay, the next section we'll go through very quickly. It's the how-tos. I've got a device. I want to write software. Where do I start? Storage, probably the most common. As I described earlier, we have a built-in driver for mass storage. Most FireWire storage devices don't need more software. As you move above FireWire, the layer you hit first is called IOFireWireSerialBusProtocolTransport. Excuse me.
and there's many layers above that. If necessary, if you're adding some vendor unique feature, you could possibly subclass that text or subclass other parts of the storage class. But in most cases, you can just use our built-in driver. If you're doing custom apps, maybe some kind of jukebox controller, SCSITaaskUserClient is probably the way to go.
Just two hours ago, there was a session on the new disk recording APIs. If you're doing CD-ROM burning or something, that's probably your easiest way to go. If all else fails, you can use the SBP-2 APIs directly, preferably from the user client, or if you're a bootable disk, maybe you might have to go into the kernel. But we expect most people won't have to do that.
DV, the other really common device. Apple has a built-in DV driver. It sends and receives DV in various formats, NTSC, PAL, standard definition, extended play. It has device control. It's all available through QuickTime or through the user clients. I mentioned on Monday that we had open-sourced io-firewire-dv KEXT. That's actually obsolete because we've moved it into user space, but now you can see how it all works, and what's in user space, of course, is also similar. The name changes to io-fwdv-components in Jaguar.
The highest level API is the QuickTime Sequence Grabber. If you're trying to import video, that's what you should be using. But you could also talk to it through the ABC UserClient to have a lower level API. Or if you had to, the services are there in the kernel. You could subclass them there or you could use the plain FireWire UserClient.
For webcam-type devices, as I said, we have a standard driver in Jaguar. If that's not to your liking, you probably want to use the plain FireWire user client, starting with the sample code that's in our SDK. But be advised, it's not a good example of good QuickTime practice, so study QuickTime.
Scanners. Most FireWire scanners use the SBP-2 architecture. You should probably consider using Apple's image capture architecture. If you need to work at a lower level, since your device is probably SAM, consider using SCSITaaskUserClient. Falling back, you could use the SBP-2 user client or even the plain FireWire user client if you had to. In no case should you go into the kernel. Scanners are not something that we need to boot.
They're not kernel resources, so don't put scanner drivers in the kernel. Audio. As I said earlier, we are working on a lot of audio areas. If you want to do software for FireWire audio devices, please get in touch with us because we would like to find out what you're doing and help mold our services to meet your needs.
Printers like scanners tend to be SAM, so you can probably use SCSITaaskUserclient, but there are some deviations out there. You could use the SBP-2 user client. If you want to use PPDT, also known as IEEE 1394.3, you should be able to use the SBP-2 user client, though you'll have to add a layer on top of that. Please let us know if you're doing this, because we aren't aware of any products that actually use this.
You could use the plain FireWire user client if you have some really custom printer. Like scanners, these do not belong in the kernel. In fact, I think it would be impossible because you'd have to hook into PrintCenter, and that's an application-level service. Still cameras. There are cameras from Kodak, Nikon that take still images but transfer over FireWire. On Monday I went at length as to why they do this instead of using USB2.
Here we'll talk about driver support for them. We already support some in iPhoto and image capture, so you may not have to write anything. We are working on more. So if you have a still camera and want to write software, please get in touch with us. We might be able to save you a lot of time.
If you have an SBP-2 type camera, again, SCSITaaskUserclient or perhaps the plain SBP-2 user client. If you're not using SBP-2, you really should be. These cameras move a lot of data. That's why they're on FireWire, not USB. And SBP-2 is the good high-performance protocol for doing that. That's what we support best.
If you have a camcorder that also doubles as a still camera, it probably wants to use asynchronous connections. We're working on that, but you could access it through the ABC user client. And if all else fails... If all else fails, use the FireWire user client. Again, stay out of the kernel. Cameras are not any kind of kernel resource.
If you have a PCI card or a Cardbus card, we hope developers will be making, for example, 1394B PCI cards for all of our G4 towers out there. We support open HCI interfaces if they comply with the spec, like I talked about earlier. If you have one that doesn't and it's broken, well, you need to get one that works.
It's that simple. If, on the other hand, you are modifying OHCI silicon because you are really clever and you're adding some special function, that may be okay. Talk with us. We'd like to know about that and see what we can do to help you. Hubs. On FireWire, there is no software for hubs. This is different from, say, USB. Hubs just work. They just repeat packets. So, if you want to make a hub, just get a good hardware designer and off you go.
Protocols. This is one of the most interesting areas. Protocols are things like TCP/IP or certain kinds of audio. This is where you want to send and receive packets on Firewire, but not necessarily just to a single device. You may be communicating with lots of folks out on the bus.
Rather than loading yourself over and over again for every device that you want to talk to, if you use the local node, you can talk to everyone on the bus at once. The Firewire user client can talk to the local node, or you can do it directly from the kernel. If you're going down this path, we'd like to know, because it's something we haven't explored very much, and we'd like to help you do that.
If you have some innovative device that doesn't match anything I just talked about, you've probably figured this out by now, use the highest level API that you can, preferably one of the user clients or above. If all else fails, use the FireWire user client. Anything you can do on FireWire, you can do with the FireWire user client, although it may not be easy. And again, stay out of the kernel if you possibly can.
Okay, we're almost done. Last section is a recap of developer resources. Apple, most of you already know this, but we have a very strong developer program. There's lots of stuff available. Please visit developer.apple.com and take a look if you're not familiar with it. Specific to FireWire, we are having a plug fest tonight during the Apple Campus Bash. You can go into the quad and get some beer and then bring your devices over to the garage room. It's better than it sounds. It's above the cafeteria.
It's a fairly large room. Bring your FireWire devices. We will be plugging them in to Mac OS X. We'll try to get as many connected as we can. You can meet with the FireWire engineers. The whole team will be there. You can meet with other FireWire developers. It should be fun.
The 1394 Trade Association has plug-fests. I talked about these on Monday, if you don't already know. These are different. This is two or three days of really focused testing. You can get a ton of data, and you meet a lot of people who don't come to Apple events, so you can get a much more broad collection of data. Here's the schedule for ones that are upcoming.
We go to all of these. We get lots of great data. You should go to these, too. If you want this kind of testing, but the schedule doesn't meet your needs or you need some more privacy, consider contacting Quantum Parametrics. That's the company contracted by the Trade Association to provide some of the tools being used.
We hold FireWire kitchens. It's three or four days where we get the engineering team together with a collection of developers. We have tutorials on the latest things we've added, hands-on development and debugging, and sometimes we give some related presentations, whatever is timely. We do these two or three times a year. Often we do it when a new SDK has come out.
If you'd like to participate in one of these, use the contact information at the end. Here's the roadmap. Those first two are in the past. There's the plugfest I told you about. And tomorrow morning at 9 a.m. we have a feedback form where you can come tell us what we're doing that you like or don't like or really say anything you like.
If you'd like somebody to talk to, FireWire at Apple.com is the primary mail address. That goes to Guillermo Ortiz, who will be up here in just a moment to handle the Q&A. He is the technology manager for FireWire in developer relations. We have a public mailing list. You're all welcome to subscribe. A lot of people outside the Apple community subscribe to it. Visit that web page. Also, especially if you're into SCSITaaskUserClient, there is a mass storage mailing list. It has a slightly different subscription mechanism. You can find it here. Thank you.
All of our SDKs are posted for free public download on the web starting at this page which has other links as well. The new document I mentioned earlier, Working with FireWire Device Interfaces, is available on the web. You may want to visit the 1394 Trade Association to learn about PlugFests. Their URL is here. Finally, you can go to the IEEE itself if you need the standards.