 Okay. Hello. I think we can get started. My name is Matt Rannis today. I think it's kind of my talk. It's about industrial IO sub-system and how you can use it for sensors and other applications. So I've been a contributor to INO for about two years. Pretty much any of the weird chemical sensors you've seen on the list. That's me. Also pH gas sensors. Feel free to ask questions during the talk. I generally talk pretty fast. So for those that don't know what the industrial IO sub-system is, it's a sub-system mainly for sensors that don't fit into a hardware monitor or sub-system. Mainly stuff that's very high frequency updates like ADCs. It also has triggers, sampling, and also FIFO buffers. In advantage of using IO, instead of like miscellaneous devices, there's a stable ABI for user-space health. LIB IO is the official preferred one. I have a demo later on using LIB IO, communicating to a digital oxymeter. It's a simple API. Of course, that's an IV holder, I guess, to each development of sensors. A lot of boilerplate code exists. And since most sensors are I2C or SPI, generally there's a lot of reuse. And like I said, it only needs generally slight modifications. So basically these are all mostly sensors, but there's a few things that aren't sensors that actually have IO drivers. Example would be potentiometers. There's a few of those. DAX and clock generators. These would generally end up in dev miscellaneous, but since the ABI there changes like per device, it's better to use IO. Also Android devices have been slowly going from dev misc and dev input, drivers input, to using IO. So here's some of the examples of sensor types that IO has support for, various drivers. Accelerometer, stereoscopes, and meganometers, IMU devices, wide temperature and humidity devices that don't fit into a hardware monitor, basically have high updates, like 100 hertz a second. Otherwise you should go into hardware monitor. A lot of ambient light sensors, gesture sensors, so that's kind of like a thing that would normally go into input, but there's a lot of high speed data coming off that needs processing in user space. Some chemical sensors, health sensors like my demo later on is Ximeter. What's hardware monitor? That's coming up, but it's basically LM sensors that's using hardware monitor. So it's pretty limited to humidity and temperature sensors inside of like a server chassis. For IO you wouldn't use that. You would use it for something more like a thermocouple that has like a probe. This can be updated really fast. There's also some sensor hub code. So here's a little overview that I'll go over, is IO channels. The triggers that you can use for IO, they're software and hardware based ones. The data buffers, since these are coming off a spy in ITC, there's a good chance that some data can get dropped. So this allows it to be gracefully dropped. If you lose it, you lose it. It's like from ADC's data. Also there's single shot data access for like just temperature. You don't need to set up a buffer or any triggers to actually start reading. There's IO events for like a fall detection from an accelerometer from a phone. So you can have it interrupt. There's also IO channel consumers. So other devices, other drivers from different kernel subsystems can access IO channels, which is useful for like battery chargers. You get a voltage from an ADC and you can tell it to stop charging, to increase charging. For users that need really low latency, would you recommend channel consumers? Well, it's not really... I mean, you can have triggers set up, but it's more to keep it more of a concise API versus writing a one-off ADC driver. So, yeah. Did they answer your question? Nope. Later on. So basically IO driver, the steps is you should really think, can this be a hardware monitor driver? Because on the list, generally, if there's no good reason, you'll generally get rejected and you'll need to re-rise a hardware monitor. So basically anything that's doing an update every couple seconds or like once a second, that should not be IO driver for temperature or humidity sensors. Now, for anything else, that could be debatable, but yeah. You should also deduce what interface the chip is. If it's I2C, SPI, GPIO bit banging, there's a few of those temperature sensors. Also, you should use RegMap or you should just do overall I2C or SPI reads. Generally, you shouldn't. And if there's any interrupt lines, you can use that as a trigger for signaling to user space. There's data that needs to be read from the buffer. So that would be a hardware trigger, for example. Software trigger, there's a high resolution timer one. So basically you can pull the sensor which is using, but using an HR timer. So you can have kind of a deterministic reading. That's what you use in lieu of an interrupt line or if you don't want to have like interrupt flooding. And also another IO driver can trigger another IO driver. Just a few examples of that. Also ADCs generally should export, they export their channels so other consumers can use it like example of a battery charger. You should do their single shot readings or there's a triggered KF FIO buffers. And you should determine if this will need a new channel type for instance IO, for the chemical sensors we need to add IO, pH, channel modifier, channel type, and a few modifiers. Yeah. So this test is it basically like the capability of the sensors? Let's say you use sensors that are created at two mega sensors per second versus use case. I mean maybe you can use that fast. Yeah. Well if you need the samples in a buffer trigger really fast, if you're doing like single shot read only, you could probably just do a hardware monitor. But that's only if it's a temperature or humidity sensor or something that goes into LM sensors effectively. Yeah. Yeah. So there's no there's no requirement to use the you know the buffer itself. I don't think there's like a written rule, but if it's like over a couple hertz, yeah, it's gonna go, you should probably use IO. Okay. Because otherwise you're just pulling SIFS entry in Harbormon. So that's generally a lot of latency. Yeah. Like I said, so if the HMON subsistence doesn't fit into the sensor usage, just like I said, typically low speed sensors, yeah, use that. Otherwise IO is probably the best bet for you. Like I said, if the sensor data needs to be terministic because you can't really know how long it's going to take to read from, you know, SIFS entry how what the timestamp is. IO allows to have like soft timestamp and a hard timestamp, a part of the sample. So you can kind of which is important for certain ADCs and other applications. And also it'll start dropping samples instead of trying to keep up into the FIFO. So that so like if you lose ADC samples, it's you can't really yet they recover gracefully. So the best way is just just to ignore them. Except battery chargers as an example of using IO that's also okay. So this is this is the struct that you how you define channels. So a channel would be like one temperature elements or one humidity element like or one voltage, a couple of voltage elements for ADC. So and the the naming is backwards compatible with hardware monitor. So it's so there's an advantage of that. Here's like said examples like there's a modifier type modifiers for what kind of data you want temperature humidity like IO temp and also modifiers up on top of that. So for instance in the for IO for IO concentration has modifier for CO2 gas and also for volatile organic compounds to to to to to allow you to know what what this channel actually means. And also there's a bit mask for the enumeration of the features. So there's generally you want to have the data sent out raw and the user space does the processing. But there's sometimes or that's not possible because there's some coefficient that's only valid then. So then you would do IO channel for processed or if the debt or if that the raw data is in the right unit for IO and ABI. And there's usually sometimes there's an offset value that's like from a data sheet. Also a scaling value that you multiply the actual raw value by to get the actual result in user space. Generally the direction of the channels are inputs but there's a few example of outputs. One is like a heater control for a humidity sensor. I think it's the only one currently but it can be bi-directional. You generally get that from the data sheet of the sensor. Yeah, yes. No, no, that's that's why you write an entirely different driver for that or you have a different like chip struck just for that one. The filters generally do that in user space. So you don't you don't want to touch that. That's why you generally do the stuff in raw and not processed unless you need to. Yeah. So here's an example of a channel structure that would you find an IO driver. So this is a thermal couple. So you see the type is a temperature. The address is just kind of like internal internal to the struct. It could be the address of you know ITC address or I mean ITC register. I think in this case it's by offset. Then it's saying it's the mask is separate between this data type IO temperature. It's raw data and there's a scaling value which you would find later in your driver in one function. And it tells you the scan index which since generally this is a block of data. You need to know what the data is pushed to the buffer to user space. What offset in the data is that information. And the scan type says all the data is coming in. You need to process as a signed bit signed 14 bit value but it takes 16 bits of storage in the actual read. So you need to shift it to to the right and it tells you the end in this. So you know which processing you need to do on your CPU if you need to change NDS or not. So here's the second channel. It's similar to the first one but you notice there's a modifier. So the ambient modifier in this case we used it for the cold junction temperature since thermal couples have the probe temperature and they also have the cold junction temperature. It's not really useful but it's nice to have. It's not really useful for user space to know that but it's nice to have. And you can see there's also soft timestamp so it's just what the clock has at that time. That's actually defined in the ABI what the raw value times the scale value what that equals. The scaling value should match to what to make it to every data type the same. Some of it's kind of arbitrary because it's middle of Celsius to be backwards compatible with a Harbor monitor. It's all document whatever the ABI says. So there's a few different kind of triggers. The hardware-based one could be GPIO interrupt or some other sort of hardware-based interrupt. The software-based ones there's a SIFS inch one which is just echo one into a trigger. It's not really that useful. It's more for debugging. The HR timer is for ones that don't have interrupt line or if you just want to pull it a certain interval to have to have be pushed into the buffer. And triggers can be mapped to multiple devices like in the example HR timer can be used on multiple IO devices. And yes they can send signals to each other and also they can yes with the IO trigger pull call. And a driver can be a provider or a consumer of a trigger as well. Okay so the buffers the overview is the data is usually not processed so so channels need to have some configuration to describe a few points. That was the part in the destruct before the scan types. So you need the storage size, the real size, the left actually the right shifting of data that shouldn't be left shifting. The endianess the buffer data is usually a herald read. It's past the user space and it's up to the user space how to decode it which LibIO does for you. So the buffers are okay five-foot back so stuff will start being dropped until you start reading from it again. So trigger buffers from you know software hardware events as well. You can you can configure the sample size for the for the buffer. It's got to be a power of two I think. So how many samples you want? There's per device buffers so it's there's triggered buffers and there's just buffers that don't have triggers that are externally visible. Example will be a device this doesn't have one because it's a FIFO that just gets interrupt and pushes it into that. So there's no hard HR timer support or anything that you can use. There's callback buffers. This this allows IO drivers to send data processed to another driver. I don't think it's really used except for like one sensor I think because it's getting data from ADC and it's doing a conversion because it has some configuration that needed if I remember correctly. Okay so here's a here's a buffer trigger handler. So it's basically you have this is a GPIO so no actually this is one of the HR timer ones. So you set generally set the polling to 100 Hertz and so 100 times a second this gets called so it gets a lidar measurement to the buffer then it pushes it with the timestamp soft timestamp and it notifies user space that it's completely the trigger so it can read then it notifies it's handled. Single shot access in the case of you can read the temperature and humidity directly or the voltage of ADC but obviously it's it's not deterministic when that happened and it's generally not good to pull it. Some data can't be a single shot like for the exam examiner here the ADC data doesn't mean anything to you if you're reading one sample. It's got to be deterministic and it's got to be a ton of samples and sometimes you want to list the secondary channels I have no real application like the cold junction temperature doesn't hurt to have it so and you have to read the entire spy block for that chip if I remember correctly so you might also tell what it is. It could be okay but I'm just saying there's I'm just saying there's samples where you don't need it at all though some some some sensors okay so here's an example of a capture so we got an IO device zero which is this is the thermocoupler so there's the raw temperature from the probe and there's ambient temperature raw and you can see the two scaling values so so yeah you multiply it's like 98 by 250 and 416 by 62.5 and that gives you the middle Celsius reading there so yeah so then you needed the conversion obviously divided by 1000 then you have your unit in Celsius and there was a few examples of units being this way because it's just backwards compatible with hardware monitor you don't worry about floating points. There's an example of IO events that's usually used for like accelerometers for freefall interrupts you get or rising and falling of certain direction inner let me think yeah for like humidity sensors there's there's some sensors that have trip points also they're different than the buffers because they don't come up they don't come through a buffer they're just an iOctole event yeah so you need a so use-based application needs to pull for it and here's an example of one so there's a threshold of rising and also that has a mass separate value and enable okay so IO consumer channels so it allows a channel to be a lot it provides a channel that can be consumed by others inside the kernel so generally ace yeah well when you're when if you're doing the processing like that in code it's better to do that in the user space yes yeah I mean you could you could write the driver however you wanted but it's just you generally do the processing in user space if it doesn't if it doesn't have a like a interrupt for like freefall or yeah so the consumers so there's some API calls to read like ADC data so there's a channel read that reads it raw and read processes generally what you want to use because you don't necessarily know the scaling value of the ADC so that relies on the ADC having its own IO info channel process to do the scaling to millivolts and Harbor Monitor actually has a driver that can use the IO and IO ADC for reporting which like LOM sensors so yeah scaling will be handled transparently yeah so data like said should be unprocessed when possible because that's not the part of the kernel and to keep the time spent in the kernel to a minimum in case there's another interrupt that happens and also a lot of this stuff is floating point calculations which obviously you can't do in the kernel there's times when like I said channel process is required because example this one the BMP280 has a temperature coefficient that affects the humidity and the pressure readings so you need to do a processing then so SI units are typically used it depends what's if it's like meters or centimeters it really depends on I think we yeah we use meters but the example of weird ones would be a mill Celsius and millivolts that also ohms so you kind of have to look at the ABI to make sure that your scaling values matches what is in the ABI documentation and that's documented yeah in testing assist FS FOS IO so there are a few utilities mostly for debugging but also to help LIS IO just basically lists all the available triggers channels their types and what devices there are there's an event monitor so you can test your driver for freefall generic buffer so you can just read the raw data coming off the buffer or you can have a processed from a devices buffer so here's an example of an output thermal couple and you can see at the temperature raw that you can read and ambient raw you can read using a single shot reading and also there's a chemical sensor so you can in concentration and underscore input backwards compatible with hardware monitor that that means that that information is processed so that's the raw data so that'll that'll come back and parts per billion if remember correctly for co2 and yeah also the resistance there so here's an example of how you would set up a buffer data capture so you so the hardware type software trigger is actually config of s created so you know make directory with the true trigger name there trigger zero you can you can configure how many hertz you want like how many updates a second so did we set it to 50 and the sampling frequency then we then we echo trigger one to the that device to tell that's the current trigger we want to use we we see what we enable the scan elements we want to see we want to see the temperature the ambient temperature and the timestamp then we hit echo one to buffer enable and that will start the sampling and this is like this is the raw data depending on what scan elements you enable the padding will be different so you have to take that into effect so the last eight bytes there is a timestamp the first four are yeah the first four are the actual temperature reading and you would you would use to scan the the data the enumeration of how you need to shift it and what indian it is yeah and it's also padded to eight since the timestamp is eight not exactly no it's it's if it'll if k fifo you keep pushing to it it'll it'll it'll not add until you start removing stuff so yeah so here's an example of how you would process that data so the stuff the stuff in bold so you see that's the index zero the scan elements so that that tells you so it's big indian so only 14 14 bits of that is what we actual data is but stored in 16 so shift shift over two so like that gives you 188 hex shifted over two 98 times 250 then you get your that's the scaled value then that's in middle celsius so it's 24.5 so yeah here's the generic buffer so it's a little more it's doing the same it's doing the same thing but it's obviously more readable so you can see the 24 you can see the two first two numbers are the temperature and the cold junction temperature and the timestamp the soft timestamp oh okay so i get to my demo here so i got a beagle bone x-exameter chip and i'm using a libo aio use space application actually over the network to my mac it's a iodamons running on it so it basically allows you to connect it's it's the libo is OS agnostic so you can use it from any system mac windows linux the back end obviously isn't it's obviously linux uh then i'll stream graphs with the new plot probably not the best way but so let's see if i can get this it takes a lot of load because it needs to do a baseline of so right now this reading off the two uh it's an adc but it has um 18 bit adc it's reading the values off two leds one infrared and one uh red the red ones for the heart rate uh the infrared ones for uh doing a ratio to calculate the blood oxygen so the blood oxygen is about 99 percent and the heart rates about 42 which might not be correct but yeah yeah the problem is it's uh it's doing a sampling it's doing an averaging over like 20 seconds so and if i'm moving or talking it changes it so let's see if it averages out yeah okay so that's probably more accurate there yeah yep okay so yeah here is in case it didn't work at all so yeah that's the data plotted plotted okay so in conclusion um the industrial i o is a good solution for as fast updating sensors and giving data to user space um there's really no limit to what i o can do sensor wise uh and it's much more stable than just using another miscellaneous uh uh driver so uh also patches welcomes so quite anyone have any questions sure yeah so there's there's a python mining for obviously libyo um yes so that's just the uh that's just um the um data keeps it keeps to the averaging but as the buffer here is um let's see just search for so so basically it's looking for a network context so i have a hard coded uh it's finding a device which is defined already the driver name uh you could have an issue if there's multiple device with the same name but you would just use the i o device zero and or i o device one uh enabling both both adc channels so it's zero and one uh then got a function to read and just reading it just sets up a buffer uh then it tells you how many it tells how many samples and once before it returns and adds to the buffer then it just uh just averaging to display the chart uh any more questions so you said there's no other output devices currently besides maybe just one kind of hot ball i didn't know which one you said uh yeah just heating control for so what are people using oh wait i'll take it back but the potentiometer is an output yeah because uh no no it's for configuration of the potentiometer it's not that yeah yeah you're you're you're you're echoing the own value you want so it's an output yeah okay yeah yeah okay and like uh so like motor how are people doing motor uh i haven't heard of anyone doing it so okay yeah i could be wrong but i don't think i've heard it's all done in user space i'm trying to figure out the balance between user space and i o because i have a lot of users that just don't believe in using even kernel drivers they could try to do everything in user space including accelerometers want to do everything in user space yeah uh so is it is it the DAC or that they're using control some of the stuff or for the motor control or yeah like to control of pwms wow controlling user space they're controlling drivers and user space yeah well they're mapping the control registers of of the pwms and they're mapping those and then yep just um and doing i gc dev or to talk to i am use rather than using i o to talk to i am use yeah and they're they're convinced that that gives them the lowest latency uh no it doesn't there's no way it could yeah yeah and they've tried using the the i o drivers for i am you and which i am you uh i can be 90 to 50 that one's pretty well supported as far as they have an issue it's a two millisecond interloop and doing quadcopter balancing sounds like there's something else at play there i think in user space running rt preempt but they don't record they're doing with just rt scheduling without rt preempt as well and it still works their biggest like the two millisecond loop but the longest time period is the i a over eight of the i am you which is like over like like around one and a half milliseconds there's probably a bug in the driver somewhere or yeah yeah are they using a recent kernel or an old kernel uh four four it's not not too new but not too old so any more questions you mentioned one of your early slides sensor house yeah what do you mean by that well there's there's microcontrollers effectively that you know basically do fusion code they can read from multiple sensors they're usually proprietary so some of that stuff i really haven't looked into but yeah so it's it's more of a fusion code thing that's offloads having it on the cpu itself because this a lot of that stuff is very cpu intensive if you're doing a ton of like 100 itc reads a second or spy reads you mean in software or an actual actual actual sensor hubs and i don't i don't think there's any use case for that right now also that's goes into the you generally do that processing in user space unless there's unless there's a reason to do it yeah because you're not saving any cpu time really that is true but uh there's no plans for that uh sample that was just interrupt or yeah you could just use like one of the you just use interrupt to trigger a reading because a lot of these sensors actually have a power management already support yeah yeah a lot of it's either it's in the sensor itself or it's in iio doing it directly yeah now let's generally use the interrupts for that but i yes i don't know how you would do that program okay uh any more questions what about sending information back to the sensor that the sensor has a calibration command uh you would write something generally it's a vicetree i mean if it's static you use a device tree to uh well that you can now that's i don't think it's actually come up to actually are we what kind of data are you talking just uh you'd probably have to use the one of the reg map interfaces or but yeah i i don't think i have no any examples of that currently yeah uh yeah uh using pwm or using like interrupt uh well you're not gonna have it's not gonna be deterministic so i don't know yeah yeah i don't think you could you couldn't deterministically have a you know the the pulse be correct any more questions uh yeah i don't think actually yeah i think analog devices has a few examples of yeah i don't think i think it's all that stuff's in staging but yeah yeah analog devices the one that actually did most of the uh blue bio work so that's one way to do it i mean yeah i mean sensor hubs is basically a microcontroller so yeah uh any more questions all right thanks for coming