 Hello, my name is Bakur Ghoterski, I work for a French consultancy called the Libre, and today I'm a property manager at the Ministry of Health. So, we are a small French consultancy based in the next nice. We are around 20 people now. We are involved in the whole embedded systems, and we start from a local firmer to builders that are external to the user space and build systems. We work on both software and hardware products. We contribute significantly to the upstream open-source projects, and we are the founding developers of the Federal CI project. So, yes, how long ago do you have already played with GPIOs and limits? So, the vast majority. So, you are probably familiar with the concept. So, GPIO stands for general input, general purpose input output, and it's probably the simplest way of interacting with hardware. So, it's a basically a generic thing that can be considered frontline. We can either work in input mode, or we need values that someone else is writing, or we can work in output mode when we drive the thing, and then the GPIO can have, if it's a big thing, it can take binary values, so it's either high or low, or a negative, disabled, whatever you like, and then we can use it to get it all off the computer in input mode to be sort of interactive for the system. So, it's quite simple, but it has a number of applications. So, whenever you need these small... Whenever you have to define values for you, you can use GPIOs, so when you have buttons, when you have legs, buzzers, power switches, stepper motors, or led detectors, all these devices that the GPIO can enable or disable can be driven or can drive the GPIO so that you can interact with it. And we have this concept of GPIO providers and consumers, so when these devices are the consumers of GPIOs, we have SOCs or expounders that provide GPIOs. So, most SOCs provide a number of GPIO lines, but since you don't want to waste precious SOC pins on the GPIO to use expounders that are connected over IFC or SBI, and this model of a provider and consumer is reflected in the kernel. So, in the kernel, we have kind of the two frameworks for GPIOs. One is a legacy framework that is dedicated, which uses a continuous GPIO number space for every GPIO line because a unique number is assigned in the kernel. And this GPIO is no longer accepted, so if you want to drive a native GPIO to use a new framework, a more recent framework which allows you to assign GPIO lines to devices and then in your drivers you can get access to them which also allows you, this new framework allows you to have more fine-tuning control over the guidelines. And both these frameworks support device resource management and yeah, so the drivers for GPIO chips related to drivers like PIO directly in the kernel source, while the consumers are everywhere because many devices rely on GPIOs. So usually what you should do is you should write drivers that change. Like you used the GPIO line, but in some applications it's actually preferred to do it from user space. So whenever there is a framework missing in the kernel, you don't have the possibility of writing a driver and you want to drive GPIOs from user space for power switches and relays. Then you have devices like GPS and good devices for example which communicate over serial ports and GPIOs for signal link. And then certain users, as you can be sure, play GPIOs from user space. I have noticed that a lot of intelligent components are implemented in user space and also robotics which often uses Python and GPIOs from. And up to a few recent... And under the version 4.8 of the kernel, the standard way to interact with GPIOs from user space was the SIS class GPIO interface. How many of you have used it? Yeah, so this interface has been merged in the following comic. This was during the time where the GPIO substance in the kernel had no active maintainer and someone just sent it to RECRA or HARDMUNT and it got merged. But this interface has been badly designed that it has many shortcomings. So first of all it's a global state. It's a set of RECRA using files. The state of GPIOs is not tied to any process. So anyone can just come in and explore them, try to explore them, change values, which is not a very approach. Then if your process that is going to be using GPIOs, for example, crashes, the state is left as it was, so all the GPIOs remain exported, values remain set to... Yeah, so this is it. And then the API itself, the SIS, or API which they say SISFS is quite difficult to use, so you have multiple files per API line that need to open and write to. The performance is pretty bad because you don't need to deal with string parts in the kernel. Then the problem with this system and with this interface is that the interface is a user of the legacy GPIO API in the kernel, so it uses the single number space. So as a user from user space you need to actually know the numbers that correspond with GPIO lines, and these numbers not necessarily are constant because if you have a GPIO expander that you connect dynamically over X or Z or USB, these numbers will be dynamically assigned. So then the big problem is that you try to make a two-level hierarchy where you have a chip level and a line level in a single number space. And yet you actually can't pull for events, but it's quite difficult in that in-app interview liable, so you can actually pull the value file in this class GPIO for events and when you get that whole event you need to L-seq or reopen the file and then you can read the value, but these events are not queued, so if your processing is slower than necessary then you will not use pessimism in this event. So in kernel 4.8 we have introduced a new interface for GPIOs. So now every GPIO chip registers a device file in that device file called GPIO chip 01 and so on, and these device files can be accessed and manipulated with standard limited interfaces with standard unit system also, Open, IOS, IPR, call, read, post. Now, unlike the SSFS interface you can request multiple lines at once and you can work on sets of lines. It's possible to look up lines and chip by name and for the records in SSFS it was possible as well, but it's not very well documented and it's actually not very instinctive because you have to export the line through SSFS and if it's got a name assigned to the device 3 instead of GPIO chip you export line 1 to 3 normally to pop up as GPIO 1 to 3 but if it has a name assigned we want to show up as the name so the file is going to be called the name but in this new interface as much as you can actually look up lines by name, same same same with chip and then you can affect the way that the lines are driven by the kernel so by specifying flags open source, open drain you can use consumer screens so you can actually tell the kernel or the technical user that might be interested in it who's using the line because with the previous interface the consumers always post SSFS now you can say exactly what your name is and then who's the user of every line and then now we actually get to events so we can react to the new chips holding out, we can change their permissions and so on and we have reliable polling so now we actually pull a device file like the title of the course one with the device file and these events in the red with the link system also they are actually viewed in terms of the buffer and to stimulate the user of the IELTS in the header you can include UAPI and UTIO and the header is logically split into several sections so you deal with chip information line information then request the lines for values and we can send them you get the line request you can separately request lines for reading the events and then you can pull these events and read them I'm going to go through a couple examples of how to use C code for user space to manipulate UTIO so the first important structure is that UTIO chip info contains the main label and number of lines of UTIO chip and this is what's straightforward so you just open it open the device file for reading, writing and writing and you pull the IELTS GL that fills the structure with all the information you can then read the name in the number of lines and then once you have the pilot's filter for chip, you can use it to get information about every line in this case you have to call the line for IELTS GL for every line and then analogously to the chicken info structure you have the name that comes to you and then the offset of the line I'm sorry the offset of the the flags that are filled by the kernel and the line offset is the only one that you have to set before calling the IELTS GL to actually tell you which line you want to get into about and you qualify the structure in this case so when you see the one that you got that you got returned by opening on the new slide so this is more complicated when we request a set of line for setting or reading values so we have the structure and what you do is you you specify the flags variable the kind of of the nodes in which you want to work so you have to specify IELTS GL with output or if these flags are not set it's going to be considered as is depending on how the line was set previously and then you can add additional flags so you can tell the kernel that this line is going to be active load so you're going to invert the values and then as I mentioned you can specify the open bring up or source the flags and how to write the lines which is the output mode once you enter the flags you need to tell the kernel how many lines are there so how many lines are there and then there's a array of line offsets up to 64 lines and you can specify the single request and one by one you specify the offsets of the lines that you want to request and then for values if it's output mode or you just omit this structure and then the mentioned consumer label so this is where you tell the kernel which who the consumer from the user space is and this is going to show up in the line info I also want to if you would run the line info again on this you're going to request a line like this in the consumer label if you want to meet on this thing and then again you run the the I go to BL and then as you can see there is this integer in the structure it's going to be filled by the kernel with the new file script that corresponds to the set of lines that you just requested so once you have this new file scripter you can start poking the values of the I go or read them so for that you have another two I go to the set line values and then get my values and this is pretty straightforward just an array of 8 integers and you just forward to set values you just set each field the appropriate value every index in the array corresponds with the offset that you requested in the previous I go and it's a pretty similar for reading the values where you call the I go to BL and the kernel fills the data structure with the current values and then another possibility is to request new events so this is done separately in the different I go to BL works pretty similar except that you cannot request multiple lines at once for reading events so in this case you have to do it do it one by one unless you're using the initial space in the library or you are working on your own in parallel so the flags the flags are the same as for requesting values but in this case you need to and additionally specify the event flags which is just what we're going to wait for so are you writing it or calling it or what once you have set the structure around your I go and again the file is set by the kernel and once you have it you can start calling for events which is please say for just a regular call or incoming events and once you get once your call function returns and you can just read it and when you read it you get to read into a buffer and that structure which then is the time stop of the event and the ID so the ID is just writing it so all this is it's usually complicated and the main problem with this API although it's better and more powerful and more robust than this is best is that not many people want to use it because like you should have to write C code, low level C code and deal with file skills and so my first contact with this CDIO hardware device was when we and the eGRAD these which are like extension tapes that allow you to measure power for example of external devices and we had these probes that apart from measuring the power also have power switches that you can cut off and use for power to measure devices and these probes these power switches were controlled with DPIOs from the eGRAD and I noted that this interface is not very useful and I tried to internet in the kernel so first I sent some parts to the IIO framework but this was shut down because these DPIOs were not really associated with any device and had nothing to do with the input output framework itself and then I sent another try was to use the regulators and control them from user space it was shut down as well that was a good idea and in the end I noticed that there is this DPIO hardware device framework and I decided to use it but yeah this was pretty complicated and just not very not very efficient like writing this kind of C code and I decided to make it easier and I wrote this DPIOD project which consists of a C library that wraps all these IOCs with a more robust API and a set of tools so this was written like in a span of two weeks and released in January 2017 the current stable version is all 3.2 but I noticed pretty fast that this initial API for the library was head set in short time so I started to rework it and actually I'm pretty like that next week I will probably release the 1.0 version of the project which has a reworked API in which for example we can now request multiple lines for events and use a unified interface to do many operations just to make the code much more compact also I posted on the Linux DPIO menu a request for reviews of this API if anyone is interested please take a look so what are the current features we have a C API which is fully documented and we have a set of command line tools that allow to interact with DPIOs from user space and can be used in script for example this is the thing that I think is the most important so this can actually replace using this as a test in script by using these command line tools they were inspired by Icon SQL so the names might make some familiar and then we have a custom test so this is interesting because this DPIO actually is not called DPIO DPIO but DPIO Bokap terminal module which is a DPIO chip simulator in the terminal and together with something called Yixing which is an interrupt simulator we managed to create a testing suite for both the DPIO D for the user space part and for the terminal part for the terminal user space API I I was thinking we should use some available steam testing in the testing framework but it turned out that it was actually not very not possible because we need to work with the terminal module we need to load it and load it then we need to wait for new events to be able to detect the devices to show up and yes so the test is custom but I wanted to know if we can release it to just check if there are no regressions in the user EDI and the C API can be clicked into a couple of logical parts so there is a simple EDI which actually has changed the name the name of which has been changed to Compextless because apparently it's simple it's not a very distributed name and then we have chip operations line operations which is which corresponds to the kernel user API the line operations are further split into info request, line info machine request and events and then we have something that doesn't exist in the kernel API which is iterated traitors which allow you to iterate over chips and lines associated with chips and so on so I don't want to go into detail these are a couple of examples of how the linearity can look like the name of this function has changed in current heatmaster too so they are no longer the same but the idea is the same so you can do a chip open and you can not only open the device by path but you can look up the chip by label, by name there are a bunch of providers for that and then you do a get line which gives you the line info and you can use a couple of accesses from that to get the regular information so that the consumer can label and yeah you can easily wait for events without using the system call so you can use provided helpers for that and yeah but the more important part for most people are the tools so there are six tools available the first one is dpi detect which allows you to list all the chips that are present in your system which is the name the label and number of lines of the chip and dpi or info goes a bit more into detail about a single chip or multiple chip in that it lists all the lines with their assets for each chip and then if the lines are named the name will be printed and then the current direction and the user and some other tracks will be shown and then we come to the dpi detect tool that allows you to look up lines by name which is very simple to just write dpi or find the name of the line and then it prints you with the name of the chip with which this line is associated and it's offset and actually the output of this tool can be used together with dpi or get and dpi or set commands in the label shown on the slide so now we pass the output of this dpi or find tool to dpi or get which reads the value of the specified line next we have the dpi or set tool so one interesting thing about this character device is that if lines, dpi lines are driven high or low by people in the system once you close the character device it's going to return to the default value so this is not the case as long as a line is exported even if your application is not normally running the line is driven we wrote the value so it's driven so with dpi or set you can set the values and exit but you can also specify several modes in this example we're using the weight mode which weights for user input you can specify amount you can set the value for a second for example and then exit you can wait for signals and the right couple more and then the dpi mode tool allows you to monitor line events in this case you can specify one or more lines on the dpi chip and then dpi mode will print the events as soon as they arrive from a single line and then if you want to parse these events in scripts or in programs it might be useful to use a specific format and then there are it's documented in the we can specify your custom format of how the events should be printed like yeah so this is the current state of the project and there are certain things that I still plan and so I almost finished writing object oriented C++ for the library and this is done because the stuff that allows you to do this kind of manipulation in a much more straightforward way of the new features of the language then I noticed that there are a lot of questions on my on my mail about piling vines and we have some people there is one person who generated cpiles pines but there has been a discussion on the dpi limits on the new dpi main list that the C API uses this structure the time step and this structure differs the different size on 32 and 64 bit architectures and I was not aware of that but apparently there are distros that ship pre-compiled python vines and python byte code even for like cpiles binding so it's not byte by byte like that not the c trucker byte by byte and this would be disastrous so I want to implement python bindings but I will probably decide to go for c extensions and just craft them manually and also I want them to be object oriented and based on the c++ bindings and the last thing that I plan on implementing is the dpi of a demon so in the kernel for example in the device screen you can specify dpi of holes so you can organize from good time and I thought that it would be nice to have something similar in the user space so that you can reserve the lines with a demon that starts clearly during the boot process and then nobody can pass them from user space and also this demon would be able to monitor the lines and react to events by running external scripts or doing some other actions potentially there's going to be bindings for other languages because I got a message from the guy who also wrote java bindings I don't know why but it was his name so this project is available at it's also available the source is available from the number of git and who uses can be on below the project is available in an open embedded layer for and the boot it's been packaged by made people for Fedora for Arch and the Demonets and yeah, if you notice any parts or if you don't want to continue to send patches to the linear dpi opening list by and after the dpi of the graphics I'm actually quite fast so we have plenty of time for questions I have tips for USB devices that USB devices that supply or whether I know about any USB devices that extend a regular dpi or microdip so I work with this chip of cp to 20, 21, 12 and it has an IconC controller on it over USB and I think it's also got some dpi or some sort of so this isn't the only one I work with which has a dpi of somebody but I don't know what I have to do if you get a spark and you just talk to pros if you get a spark if you get a spark if you get a spark and you just talk to pros there are a couple of other types that they can use USB if you got a little bit of you know they're supporting the electronic I actually have a question so I'm going to let you play a little bit about what's the USB device and what's the USB so the system is going to get top speed but it also has a very low free requisite style access you know the system is going ideally you would be able to not have other binary requirements which you don't have to do the full combination so what do you think what's the question what type of support would you be able to use C types C types can be quite dangerous so the question is what's the total support you're going to name I don't know what do you offer as far as other language support okay so you're going to go to the C it's just like what I said C types can be dangerous in this case because we're using C structures that differ in layouts on different architectures so C types are not the best choice and I decided to go with C extensions so the C models for piping and as far as other languages go so I know piping I know C++ so I will never write but at that point I didn't know it so I will probably not be the one writing the bindings if anyone's interested in writing bindings for this library in go one I would be glad to accept an emergency well another example might be the NodeJS where I ran a group about that and one of the staff had a transcription so I guess it's just not required to complicate the staff on the installation it's more the strengths of C++ I guess my question is how do you in your group architecture try to complicate some of the problems yeah so you can always use like in NodeJS I guess you could use the Sublight Deliciously tools which are already compiled and then you can run from your NodeJS I know much about the use case for NodeJS I have no idea how NodeJS would work I guess okay okay so yeah this is my question yeah so as far as NodeJS is going to go I don't know so this is my idea I will use the tools and run them from the script or write your own binding to the library send it to me and I will yes what yes yes and no you can multiple users can multiple users can read information about that thing but once a single user requests it another user cannot request it even from the terminal actually the terminal cannot request that thing you have to use the case no no the question is is DBI and Mongo will see how the process is going to you can't you can't do it once a single request it is requested and then you know how the program can act as it but you are too important you got a problem yes yeah this is the idea we have multiple access to the demo should have a client and be able to multiple request actually I am asking you a question so now the idea that I can remind you is to have a demo that offers like a socket or protobuf access to it and multiple access to GPIOs and then deal with permissions and stuff like that so this is something that is not going to be made in the future I do it 19 times so it's not like I I call it thank you so I didn't do I didn't do a lot of benchmarking but there was this guy ok so the question is how does it compare with S I did not benchmark it as such because the reasons for writing this interface were different it's pretty good in that there was some benchmarking and he actually fixed or improved the system interface because it was super slow because of the screen parsing which we don't do in this case and even after these improvements where we basically just check the specific bytes it's still much slower I don't know the number though so if I test it with a real-time page no because if you can access it then from CISFS and this new interface no because CISFS is another user of GPIO so if you export it then in CISFS it's going to show up in GPIO info as a user is going to be called CISFS and vice versa if you export it from from GPIO tools or this API once you try to export it from CISFS it's going to tell you you're not pretty much or busy I think yes so there is a simple idea so there is a function and you specify a call box which are called the idea of the simple API is that you don't have any resources that you need to manage so it's called complex less and you just call a function a function called GPIOD complex less and you pass it a two call box one call box allows you it's not mandatory allows you to manipulate the calling function and then the second call box allows you to react to events you can use it in your own calling so I do exactly that in this GPIO one tool because we use a signal for signals and I take this descriptor and I use this calling call box to just throw all the descriptors into a single call call system call and then the events are taken by this another call box GPIO one source code you can see how it's used exactly exactly you can both use this high level API that allows you to retrieve the descriptor and use it in your own calling and this is exactly what is done so basically it's done first in this GPIO one tool it's already done in this high level API and then it's done again in the implementation of this high level function because the high level function needs to be lower the function needs to be lower so if you look at the source code you wouldn't find that key so the question was can we retrieve the high level descriptors from using the API yes you can use it now I think you provide some kind of feedback CDL or SPI just for receiving or if you're seeing something like you can use it now like you can use the high level API because you can change the values fast enough and you can read all the events that come in so I didn't try it but I don't see why it's not possible we consider it as an input line if you can still drive it no we can't if you if you continue to be the first one you can read values if you continue to as a source of aircraft you can read the values but you can also write like that and that's only if you continue it as an output input in the same time it's possible to set the line and it's only 30 minutes so you can load it in no problem with that if it's low but some work has been done to allow certain values but yeah there's talk about certain values lines but this is an idea and many others have a lot of time to make it possible to use it