 Thank you Okay, cheers everybody before we get into this Spy subsystem my name is Matt Porter as he said and let's jump into it so Of course now it quits working how about that? Well it worked just a second ago All right Exactly All right, just to De obfuscate the name of the thing our community has gotten more diverse, so people might not get hind-line references, so We're gonna understand intuitively the spy subsystem help hopefully By the time we get done with this, so if you haven't read it read Stranger in a Strangeland All right little overview. We'll talk about what spy is Okay, we'll go over some spy fundamentals because we can't truly understand the subsystem unless we really understand how spy works first So we've got to go through that first We'll talk about some fundamental Linux spy concepts So how the subsystem takes the concepts of spy itself translated in the Linux world And we'll look at some use cases to kind of drive us through the subsystem right adding a adding a device Doing a protocol driver. We'll talk about what that is how that relates to The real world of spy controller drivers user space drivers And then we'll talk a little bit about performance and then what's coming up in the future So getting into what spy is So serial peripheral interface Motorola Develop this it's a de facto standard so if you're hoping for a written spec with a committee You won't find it here It's a master slave bus Four wires. We'll talk a little bit about the signals coming up here except when it's not so Four wire sounds like the easy case everybody talks about the standard case, but there's a few others We'll get into those a little bit Options where you don't need to use all the wires and so forth or use more so There's no maximum clock speed Obviously, there's practical limits that that chips run into Then this really poorly formatted URL is obviously the usual place you can go get some information on it So if I lie about anything you can go there and find the truth. Hopefully So and one of the jokes about spy is that everybody makes a big deal about it, but at the end of the day It's just a glorified shift register All right, so what are some common uses? Where do we see spy use? Well pretty much everywhere, but just to highlight a few of them You have things like flash memory you guys often find serial flash Devices why do we do that? Why do people design those in that way? Low pin count right same reason? You see I square C e prompts right for your non-vowel storage huge advantage with that low pin count in embedded systems So again same reasons drive its use with analog digital converters a number of different sensors Thermal couples for example you might say well, what's I mean? That's just a temperature sensor I know that there's lots of i2c ones and they're low speed right but in industrial use and so forth things like Thermal couples have to be sampled at very very high rates of speed right in a process control that has Very little deviation a lot of permitted in the temperature LCD controllers You start seeing a theme here right and of course as we saw this morning the the chromium embedded controllers Can use spy as one of the the communication channels? One of the themes here when we look at all of these Okay, is that they're all fairly high speed type devices right ADC's Thermal couples in the kind of sense I gave where it would be Sampled very quickly LCD controllers can have a very high rate of speed if they're they're a Color controller and so forth all right, so Now that we've got that little overview out of the way. Let's hit our fundamentals so we start with our standard signals and Here it can get a little bit ugly when you're looking at data sheets and we're going to talk a little bit about data sheets and translating those into some reality of of Extracting the information you need out of them, but you start with mosey as I pronounce it master out slave in and What I show here is you're going to find a lot of different Names for this because it's a de facto standard every manufacturer Vendor seems to have picked some different things and I've even seen data sheets where They'll show I2C names right for the data in a in a half-2 plex type device So that's why SDA is on there as well. So you'll see all these it depends on the vendor Same thing with master input a slave output you'll see that same set of things and then your Serial clock Okay, that's an output from the master You'll see those kind of different Monikers for it and then you have the concept of a slave select that is a Master output and so that's how a spy device is actually selected should there be more than one on the bus Okay, so clock you have Output an input okay, and so that's the four wires. We talked about that's our common case right and and Keep in mind as you see this that if we've got dedicated channel for output and a dedicated channel for input It's a full duplex protocol by It's very nature So this is what it looks like in our really really trivial example, right? So we got our spy master We got our flows for each of those And if you want to do a transaction He would go ahead and assert Assert this slave select low Right, and so he wants to do a right. He would put data on there and clock that okay Now we're gonna look in detail how how that works because you can't Verbally explain it and give it justice So let's look at some timing okay, and With these wonderful timing diagrams that wave D-ROM helped me do We'll look at and don't worry about right mode zero yet. We'll explain modes Okay, but we have a typical right cycle in in zero And so what you're seeing here is just an 8-bit transfer Okay, and in this case What is usually usually the de facto standard is? MSB first on the wire, so that's why you're seeing D7 down here and So what you see is you see the data stable here boy, I can't really hold this I must be nervous, huh? Yeah, thank you for that So as you'll see It's latching that data on the rising edge is what we're showing there in a right Okay, and you see it on the map master out slave input Makes it easy with the name if you use those signals to know which direction you're going there And then on the reed case Okay, you have it latching on the rising edge here and you can see that this chip select went low Right before that first edge for that bit. All right, so that's your very basic case All right, we'll get to the modes here in a second And here we are so spy modes You have lots of options, so there are many modes, but it's pretty simple tooth table The way it breaks down is you composite of two characteristics of your of your clocking. All right relative to the data All right, so you will see C pole is is the abbreviation you'll typically see for clock polarity in most data sheets and and in the original spy description from from old Rola and then see phase the clock phase and so right here we see how those break down so If the player if the polarity is zero or C poles zero then your idle state of your clock is low Right, and so it's it's transitioning from low to high in the active state All right, and then the inverse is true if you if C pole is one So that allows options on the clock polarity for devices and then in the phase Very simple some people forget it, but your data your data is latched on falling if C phase is zero Okay, and the out and it's output on rising and then on On one it's latched on rising So this is going to vary on the type of peripherals you deal with and so forth so you end up having to program your controller to Operate with the proper phase for whatever peripherally want to talk to and so What they've come up with is a way to encode these That's a de facto standard as well. That's simply modes zero through three So if you're used to seeing mode zero through three, that's how they translate back. All right It's simply just telling you what polarity of the clock and what phase I'm latching data on. Okay All right, so now let's look at these modes, right? I showed you the basic example. It was right. It was writing and reading and mode zero. Okay, so now Let's look at each each of my individuals. We'll just look at rights Just because it doesn't matter for illustration of this concept. Okay, so what you see first Right is our chip selects going low. All right to activate the chip, right at this edge here Don't care what the data looks like here. All right, and then I have my first clock edge And so this is just like this is the original example. We looked at okay And so you see it's latching data on each rising edge and notice that it was it was idle low Right clock. So that would be the clock polarity zero right and then the phase right rising is where it's latching So then we go We still have clock idle low in mode one if you remember our truth table there whoops so when we're looking at one we're just changing the phase right and So now you see that instead of Latching on the rising edge. It's latching on this falling edge here each time you see how that lines up with each stabilized data bit Okay, and then when you go to right mode to all right now now see pole is one, right? So our clock is idle high So that's why you see this waveform. It's high and now we're you know going to a falling edge Okay, and in this case I show falling edge right falling edge Latched there remember they're all right. So that's why it was mosey and Down the line same thing here except in mode three. It's on rising edge, right? So that's All the modes okay, all right So but we only looked at this really trivial example right single slave and so forth now It gets complicated because we live in the real world So first off obviously we've got the reason we have the chip select in the first place was so we can have multiple slaves on a bus and The way to think about a chip select is from a software stance that gives us an address, right? So everything is going to have a unique chip or chip select in order to activate the chip chip Activate its buffers and so that becomes a convenient abstract way to reference multiple Multiple slaves on connected to one master, okay? the next thing the next thing to get complicated is daisy chaining and the very common The very common case that they'll show with daisy chaining is the daisy chaining of the mosey to miso on each device But there's also daisy chaining cases in fact the the anodyme Analog field program analog arrays they do chip select chaining during configuration So they shift so many bits and then it asserts another chip select So now you don't have the master controlling the chip select down the line. And so that can get ugly as well Okay, and the next area I promised you there's lots of ways you can abuse the fact that it's a four-wire bus Well in high-speed flash devices They started adding more lanes More lanes more throughput, right? So there's a balance there on pin count versus the ability to burst read data off your spy flash and So we'll see that there's there's devices that spy flash devices that do dual or quad quads popular so Essentially instead of one miso we have n number of them, right? And there's nothing preventing I can't remember if there's some eight eight lane yet, but It probably goes beyond the point of doing it And I know that the quad ones are very close to or right around the parallel nor flash speed now anyway so And so obviously like I said that increases your throughput. So every time you add another lane like that All right, and then the last one here variant is the three-wire variant Microwire and so what what they do is they combine miso and mosey and it operates in half duplex You can also do things like say that your peripheral is a right only peripheral right some LCD controllers That's all they are right and you don't you don't even need me So hooked up for those if you're not if you just caching the contents of the registers and operating from reset so a lot of Designers just won't hook up a pin if they don't need to to read back from it So essentially you're back to a three-wire bus or maybe it's your only device and you drop the chip select and it's always asserted So there are designs like that as well All right, so Looking at that more complex case, which is really The more common one that you'll run into What you see is the same type of flow Okay, and Mosey miso and the clock are all propagated to all three of these together Right, but you'll see that each one of them has a unique slave select now or chip select right SS one two and three And if you can read this eye chart, so it's hard to fit the stuff on there so what you see here now is This one here, and I know that's probably hard to see I knew this one that's gonna be tough But that's slave select one two and three and so this is just showing Excuse me three eight bit rights, okay each to each of those slaves and So when you see the timing of that how you manage that Is you drop the chip select for SS one? It's this is right mode zero And so what you're seeing is when that chip select is asserted you see it latching the data for for the first slave and Then you see slave select to right you see that unasserted that go low and Now slave select to is is receiving eight bits of data and the same thing So that just shows you what it would look like if you were dumping that on your logic analyzer Okay We're through that background now, right? So now that we understand those concepts now We can talk a little bit about the next spy subsystem so now Every subsystem the kernel has to translate this hardware into some sort of concepts that we can use and of course with the Device model in the kernel The way it's it's broken out in the the spy subsystem is we have a concept of controller and protocol drivers Okay, and those match up one-to-one with What the controller is that master that we saw? and the protocol driver is Whatever protocols needed on top of just shifting bytes out to actually do something with your peripheral, okay? and So just said the controller drivers that support spy master control both of these run on your your SOC if you will okay, and All the controller driver does right we've The subsystem is very carefully split out that protocol of the peripheral from the actual Shifting of bits out of that controller and so forth. So all it's doing is controlling when that clock comes on When the chip selects are asserted or slaves select if you will Shifting the bits and then Configuring those characteristics so that you get the right mode you get the right frequency of a clock and so forth Okay, and and and of course the polarity and phase right as we showed in coded in the modes All right, so an example would be like for Raspberry Pi 2 3 the 2035 driver So Now protocol drivers who said very carefully split that concept away. So you don't if you're writing a protocol driver You don't have to think about What is it? What what what controller am I on? What are its characteristics to a point right? That's all abstracted for you So the way to think about them is that's your slave specific functionality So if I've got an ADC it talks to whatever that ADC says for these are my registers This is how I get samples started, and this is how we read them out. That's what you're coding up in a protocol driver All right, and so fundamentally Everything every every operation in the spy subsystem is based on top of the concept of messages and transfers Okay, and we'll we'll talk about those in detail here and and Really understand that as it relates to the API's But that's that's a fundamental concept. They've added that's that's somewhat, you know outside the realm of that low-level spy Hardware but maps well to how peripherals actually use spy and functionality So remember the protocol driver relies on you having a controller driver. It doesn't care what controller driver Everything's abstracted for you. So an example would be like one of these old MCP 308 ADCs So as promised So communication This the subsystem of course it breaks everything up into transfers and messages. Okay, and so a transfer And if you think back to those timing diagrams, I'm showing right a Transfer if say my device wants an 8-bit It has 8-bit registers that it implements behind it. Okay a transfer might be a single 8-bit Read or a single 8-bit write. Okay in generic terms. It's a single operation between the master and slave Okay Part of the transfer data structures What's carried in there remember it's a full duplex wire Protocol at the low level so each transfer structure carries Both TX and RX buffer pointers. So You know one one can be consumed in the other field right within the same operation You can make either null if you're just doing a half duplex operation. Okay, and each transfer Can have its own optional Parameters set on it. So you can control what happens with the chip select after that operation ends Okay, and that that matters a lot when you go look at your peripheral data sheet It may it may say oh, you know, you can't drop the chip select After after a certain sequence of things. So you can go per transfer to find Define how that's going to behave And then you also may need to insert some delays in there to satisfy the timing and so there's ability to do that Okay. Now that said What are messages just an atomic sequence of transfers? So when you just when you build up a message you can add n Transfers all of which can have this individual behavior of how they manage a chip select a delay in between And so you can build up that message for whatever your peripheral data sheet says you need this sequence Right you can build that all up add the delays and so forth Okay, and so the message itself is the fundamental argument to all the spy subsystem Transfer calls the rewrite API's and there's a bunch and we'll talk about that But just to give you an idea if it wasn't clear verbally That's the best way to kind of look at a spy message, right? You got a chain of transfers inside of it and number of those pretty simple All right, so let's use some use cases to walk ourselves through the subsystem now So I want to hook up a spy device, right? I've already I know there's a kernel driver for it like let's say the MCP 32 X that runs MPC 308 But how do I hook the damn thing up and get it working on my board, right? So the next one I want to write a protocol driver I want to write a controller driver, right or I want to write a user space driver because I don't I've got something Odd or I want to do something different than a kernel driver for some reason or I'm lazy All right, so adding a spy device to system The first thing is you need to know the characteristics of your device need to understand the timing of it In order to properly add it in because you're gonna have to set some parameters Okay, so learn how to read a datasheet if you're gonna do that You know even if you're using off-the-shelf one if you don't understand what the max frequency is then you're not gonna be able to hook it up, right? okay, and So there's three methods to do this Device tree obviously pretty ubiquitous So we have it everywhere now The board file method that's that's basically deprecated now except x86 people tend to use it sometimes and then AC PI Which a lot of drivers are getting? AC PI ID tables now to support that All right Wow, so Learning to read datasheets right for spy. There's a few important things First off you might not even notice when you look at the datasheets. Sometimes they don't even say spy, right? And and they will they'll just say it's got a serial interface and you have to kind of go look at it And maybe they're masking because they don't want to say the the the Philips I to see Name or something right so it might be I to see but you got to look a little bit usually they'll say you know This is a spy device. So there's a few clippings out of an st. 77 is 77 35 LCD controller and What's important? This was one of those examples where where I was not kidding you They show SCL and SDA, but it's it's spy, right when they show that timing. Okay, so And and that's also example of one where I said, you know, if you're right only like this It's like know this part. Well You you have a situation where it's essentially a three wire set up, you know There's no need to have the the read path. It's optional So they actually show a four wire hookup as well if you do want to read certain status things But most designs don't even hook that up So important things here Identify the beginning. It's a spy device. Okay, you know, that's pretty obvious But then, you know, be aware of your timing diagram. You have to be able to read the timing diagrams They're not much different than the stuff I drew up They got a lot more detail though, right? So if if you're a software person that hasn't got comfortable with Data sheets now is the time to do so if you want to do something with with hardware So, you know, you need to you need to look at things like this time here right, which is the time between where you drop the chip select, right or you assert it and When that first clock edge starts, right and then they're showing things like the Period by this this high time and low time, right? So now you have the period and thus the frequency So if you can do simple math, you can figure out what your maximum frequency So that's generally how they communicate that information to you So yeah, and so you'll see, you know, they've got they've got that Setup time right and they've got hold times and so forth. And so that's where you get your frequency from There's a little bit more on that and then then what happens is all they were doing in that timing diagram is showing you a very low Level, right? So then later you're going to see more information. That's actually how their protocol works So in this this part, it's got the concept of a data or command type state And so you'll find tables like this where now you're talking protocol Okay, now it's showing me how in this case on the data line this is a data or command flag and so everything that's following in that eight bits okay is Everything following that then is either a command which could be a register access, right? Or if you're doing data, you may be just streaming your frame buffer, right? If you're using the FBTFT stuff or the the new DRM stuff they're working on for that So this is where you start seeing that so you need to look for how those registers are mapped and so forth And that's where you get What you need to do the actual protocol driver the guts of it All right, so let's look at another example real quick. That's one where it's a LCD controller. I'm gonna use this example when we go through hooking things up a little bit but Again, it tells you it says I'm a spy device Somewhere at the beginning of the document. These are just clippings. I snap shot it out again same type of timing Okay, and they show t-high and low here Add them together to get your period and you find out that you know it can do a max of four megahertz Well nominally people find that everything works out of spec, but in reality, that's your safe time so Same thing there and again just reiterating that it's one thing. It's one thing to have that low level timing It's another to go further in the data sheet and you start seeing how How the AD converter goes right when it starts doing its conversion How soon after that the data is available and D out here if you remember they use Back to I described the signals and all the different names. That's that's the MISO, right? That's master in slave out so No, this this is this is a this is a four wire It's just using the alternative naming for the things so just don't get confused by that, you know If you don't see MOS I and MISO on the data sheet, you know D out is Also MISO right that was back on that earlier slide on the signals all the different crazy names that we see used. Oh This turned out terrible, huh? Contrast is not good, huh? Well, can you guys read that at all? Yeah, you guys can't Yeah, can we turn more of the lights off because I think I think it'll be legible enough Otherwise, I don't have any examples Now this is an intimate setting Okay, so This is not Grocking DT, so I expect you to know it But this is just remember where to reference and find information for spy stuff you go if you're gonna hook things up So we're back to let's hook this thing up, right? Via DT go look at your go look at the binding, right? documentation device tree bindings, right? and sure enough we find This and I clipped a little bit out of this for the example, but one of the compatible strings is microchip mcp-3008 There's some deprecated ones in there as well, but and then there's a little example of how you would hook it up there That's for a 3002. We have a 3008 and So let's say again. I'm not showing every variant of how you can actually implement this But just as an example A DTS fragment for this device would look something like this if you don't understand DTS fragments or DT fragments and overlays That's a different talk But the the important thing here is that in the overlay the operative piece here is that This this reg here is a chip select or your slave select So that's your unique ID I said you can use it like an address and that's how the subsystem uses it Okay, you got that compatible string that we saw in the In the binding on the previous slide and then We figured out what our max frequency was from our data sheet because we're smart and we're gonna plug it in there Okay, so four megahertz there Now this is how you do it the wrong way So if you've got a board filer you're on something like maybe a middle board, right? typical developer board where you don't have DT handy and ACPI doing doing Overrides is really a pain You do this type of thing Which is it's well documented in this subsystem docks. This is the old way So normally you'd see in a board port you also see this This structure and so forth in the old days before DT You'd see all the board files in the kernel registering all their devices this way, right? So just in a in a big array here So this is just an example of one again same data that we needed, right? We know we're bus number one chips like zero and This four megahertz rate and we also need to tell it what module Doing it by ACPI Is almost unreadable As with most ACPI stuff, but you see they're basically the same things are there And it mixes a bit up here You've got the clock polarity and so forth you've got The the max frequency it well that's that's this one here So that's your four megahertz In well in machine readable form so that's what that looks like so three ways to get there It just depends on your platform, right? So you'll see these type of constructs on Bay trail type if you dump their ACPI you'll see some of the stuff for spy devices. It looks mysteriously like that All right So that's how we hook one up basic example Time check. All right. We're good. So now Let's talk about a protocol drivers, okay, and Now we're getting in the media things we're gonna kind of come back to the whole messages and transfers and and so forth because We're now gonna use some of that as we get into these so If I do a protocol driver Standard Linux driver model. Okay, you find these same patterns throughout the kernel so you have to instantiate a struck spy driver, okay, and So there's a few important fields. Okay Once once the probe fires so again, we assume that you know the driver model first off They're not gonna cover all that here But just is a highlight of what you've got to fill out to do your protocol driver. Okay You have your optional PM ops that you probably want and you got a probe and remove which all standard hooks You're gonna find and everything that works in the driver model on the important thing operationally with a spy protocol driver Is that as soon as as soon as it probes you can start using the kernel APIs to do messages Okay, so so that's immediate and so yeah, so once you implement that probe You can start banging on the device using the in kernel APIs So what are these APIs? These are the APIs you're gonna use to build a protocol driver, right? We said the subsystems carefully architected to Separate out that controller thing. So all we have available to us are these neat little transfer APIs, so the first is spy async and it's not really an obfuscated name It means what it says, right? So that's an asynchronous message request Okay, and when when that message completes you get a callback executed All right the key with async and when you're using these is that it can be issued in any context and Explain what the other side of that is in a moment, but you can execute that for example in IRQ context Since it does not sleep. Okay Now spy sync and I will say that when you look you look at the type of drivers that use spy async You find it's not heavily used directly Okay, and we'll get back to that in a second, but so now let's talk about spy sync Okay, again synchronous message request, right? It does exactly what it says one thing implementation note is that Everything all of these synchronous family calls are all wrapped around spy async, right? So the same back ends used but they guarantee That that it will return on completion so You can only issue this in a context that can sleep, right? So if you need to be in IRQ context, you're gonna have to use this guy, okay? and as I already said, it's a wrapper around those and so you can build up complex messages and then issue them with the spy sync, okay, and Then there's some helper calls where you can just hand a buffer and do a write and a read And so there's a just wrapped around there What you'll find is You'll see things like some of the network drivers will use spy async They're more optimized around throughput And so they can they can drive everything off of callbacks that way things that want low latency All right, are gonna want to use something based off of spy sync They may have a short little command to send and they don't want to have some Arbitrary amount of time and handle the callback coming back. They want to do it sequentially Then you have some specialized APIs well just just this first one this is kind of out of order Fortunately, so spy read flash you've got an API if you deal with with spy flash devices they have a a standardized set of commands, okay, and So that's actually optimized For that set of commands. It's also optimized around specialized engines Like some of the some of the quad spy controllers on the newer SOC's They'll they'll they'll IPL out of that quads by flash And so they have memory mapped IO and it actually triggers A spy transactions on the bus by accessing that so they'll they'll kind of they'll they'll demand page in chunks of the spy Of that spy flash device into that MMIO area and execute the code XIP there So that that supports those those types of things and then When you do need to build up the message, right? We show how you have all these transfers There's there's API's to do that and so Not surprisingly you can spy message unit and that that initializes empty message so you deal with that kernel structure and then you can spy message add tail and just add Transfers onto that list that we saw in that diagram earlier So you can put any arbitrary type of transfers together different characteristics how they leave their Chip select everything by using that API there Alright that Covers API is that you're gonna use with protocol drivers with a controller driver again standard driver model Not everybody's gonna be writing one of these every day, right? Usually you're gonna be touching protocol drivers for most people But it works again like a lot of other subsystems, right? We have those strong concepts of master, right a master device and And and also called a controller in the subsystem And so you're gonna spy Alec master and then once you've done that you need to set a whole bunch of methods, right and so Set up configure spy parameters clean up prepares you for removing the driver and then you have for four different that are the meat of it, right and so one is prepare transfer hardware So you have to implement You you may need to do some prepare Preparation for a message is going so when the message pump in the in the core spy subsystem is About to send you a message to be processed by your driver. It lets you know Before he calls Transfer one message or before so that you can get ready so you can call transfer one message so so you get a hint there that a message is going to arrive into your driver, okay and Transfer one message does exactly what it says you dispatch a message there So when you get called by that and then transfer one is just trans dispatch a transfer, right? So you implement all those and then you you register it with the subsystems spy register master Okay Okay, so user space drivers Obviously, this is a popular one with all the the developer type boards and the maker community likes to to do the user space type Drivers and and wiring pie and stuff like that over top of things the way that's done is through a Protocol driver a special one called spy dev, right that exposes a simple character device out to user space, okay, so When you bind that spy dev driver to an actual device Using methods that we showed earlier. Okay, you get these instantiated So you have spy dev and whatever your bus dot your chip select so that gives you that unique address per bus remember and So same thing you'll see you'll see information on it under under sysfs and then you see that character device there and Usage of it is very straightforward So simple open clothes you've got Half duplex read and write commands just by their nature using the standard calls And then if you want to do more complex things Yes So if you look at the actual transfer struct when you're just doing a right It by being half duplex that that just means that you can't set up a full duplex Transfer using that API Yeah so that that would be the case you would do this very commonly even in kernel space where You just set say you want to you want to do a right? You would set the RX buffer to null right so that's a common pattern if you were building it up You know by scratch and so that's what happens underneath those types of calls, right? Good question So to get more complicated it does spydeb does support very complex Drivers so to get at that you have to go beyond read write that aren't sufficient and use your your IO controls And so there's a few Don't show all of them here But the important thing is and you can read the docs on it yourself But the important thing you've got there is the spy IOC message you can do raw messages full duplex You can you can control the chip select everything and then you have a whole family of read write IOCs where you can set all the same spy parameters that you would in the kernel API so you have full control You can build up complex messages with lots of different transfers just like you can in kernel space Best place to go to get more details on that is in that spy dev doc Okay, and then what's great is the kernel has and sometimes people aren't aware in the tools directory a couple great examples So you want to see that thing used you know in a raw way. There's a full duplex example There's a test piece that a lot of people use and their examples But then once you move beyond that I can recommend Jack Mitchell's Libsoc library has a higher level It fits into his whole Libsoc API. So you have a uniform API makes it easier to work with spy dev Maybe a lot of times you want to use GPIO to if you're doing user space stuff. So you have a common API. So that's helpful It's a very very familiar standard C Library and then a lot of people I think Landon Avi was talking about you know Python and stuff and the maker community and his talk and a lot of people are using this Python binding to spy dev All right All right, we're almost there. We'll talk a little bit about performance so This is all well and good. You got all this abstraction. You've got these standard API's and everything but at the end of the day you need to understand how to use them properly, right and so First thing that happens When you have bad performance is you probably miss some characteristic of the controller driver So we got all this nice separation, but there's always going to be some things that aren't fully abstracted, right? And you find one of those Where down in the controller driver the mix by driver on omap that's used on pretty much all the ti parts Right they actually they have hard-coded because of DMA overhead It doesn't use DMA until you get beyond 160 byte threshold, right? So it doesn't use heuristics or anything so you have to be aware. Maybe you're doing a test You know a simple test and you're like well, you know, why is this you know taking so long or you know You're looking at it and there's the pause, but they're they're using pio So if you do like a simple 128 byte thing you might not see the DMA routine Well, you won't fire and so forth. So just a that's a specific example But you you do need to know some of the characteristics of what's going on underneath to kind of understand What how that got translated into the real world? Okay from those abstracted apis the The other big thing and we kind of touched on that already is you need to know where to use Sync versus async, okay, so I said network drivers Typically that are already driving off of callbacks where they're recycling SKB's and so forth You already have that model where you're optimizing for throughput. So You typically use asyncs there. You don't you don't care exactly when it goes But as long as it just completes and you do your housekeeping off of the the callbacks, okay? But you're gonna have some latency there, right? With the synchronous, okay One of the one of the nice things now, and I don't when which kernel of that come in Where we tries to do immediate Yeah, yeah, I it's too lazy to go Run get and check its that it was somewhere in there Like water something it's really old. Yeah. Yeah, so yeah old unless you're on some crappy vendor kernel from Exactly Exactly so the point there is if you're on a newer kernel or if you're stuck on an older one There's some great optimizations in there where you want to have very low latency It will try to execute in caller context and you can avoid A context switch, right you avoid to sleep and reduce latency Now here's the eye chart and I want everybody to see this and probably Somebody would take a patch to maybe get it in the docs itself, but I always found Had to explain this to a couple people before you will find this in include Linux spy spy dot h but the the Spy overview docs are a little bit more terse about this behavior and this is very very good, okay One of the optimization things when you're working on on protocol drivers Is that you want to be very careful about the behavior of the chip select because the back-end controller? Often will have a very long delay If your chip select is unasserted and then you do another transfer and it's got to reassert it, okay And it can handle just having the chip select asserted the whole time you can you can change some flags In the transfer to keep keep that asserted all the time There's default case and so you you use CS change to do that. This is where you can go read the full explanation of that, okay, and Also, you can use it as a hint that if if you're dispatching a lot of transfers, right? You can have a hint that the next Transfer is going to the same device and so it doesn't have to drop the chip select that can save you if you go look at it On your logic analyzer or scope can save you a lot of time right in between those so when you're optimizing You need to be aware of these things All right quick thing on tour on on tools and then we're done You want a logic analyzer go take it the take a look at these things sig rock has a great great comparison of Everything and and what it supports and it's pretty comprehensive the spy loopback test module Is is a nice little tester if you want to look at your performance with something that's a canned test And and then the the spy subsystem statistics that came in a couple years ago or so Really great stuff. You'll find them under under You know your bus dot chip select statistics and what's great about those is when you're thinking about that spy sync stuff right and Did did I actually how many times am I actually sleeping right or actually executing in the context of the caller? You start having visibility of that Per device right by you see how many messages you sent transfers you sent oh how many times I did spy sync immediate right which executed in my caller context versus how many times did I did I fall asleep right? Timeouts so forth, and then this is really awesome. There's a histogram Cisfs attributes now so you have buckets of size of transfers so you can actually look and see with a histogram what your Day looks like so that'll help you out a lot when you're optimizing all right last thing future slave support is coming and It's useful in some limited use cases because we have the hard real-time nature of slave support where it's a full duplex bus and you're gonna have to respond with something as soon as you get that first bit clocked in right and so a lot of Cases you can't do but you can do things with pre-existing responses Things that are just a one-way command to your Linux system. So good gear Deuter oven has a rfc v2 patch series He's working on some bug fixes and He's got a couple examples in that where he has Basically when you register a slave you get this this class slave device you can at runtime Bind a slave protocol driver into that slave controller And he's got two example ones one that that does the latest uptime that it's got pre-existing Cashed and it can respond back with a time packet and another one where he can power off reboot halt the system just one-way command so That's coming. I think he's got a new version coming soon Real soon now I put him on the spot That's it So I think we do have time for a question if people could be courteous to Matt who's given us a great talk hopefully we can Be still just for this one question if there's one go ahead