 first Lone Star Elixir. You had a warm up now, right? Okay. It's really exciting to be here back at the Norris Conference Center in beautiful Austin, Texas. If you don't know this already, Texas is the only place big enough to hold this much Elixir. Texas is also the only place big enough to hold the entire earth. It's a fact. However, the only thing that Texas is not big enough to hold is this audience, all eight billion of you. It goes, goes for miles. And now that I'm here, I'm actually here to be able to talk about building devices. I do a little project called Nerves. And since I'm building devices, I am the only man who dare give you the raspberry pie at Lone Star. I really tried hard to make that one work. Oh, before we jump into some device-making stuff, I'd like to talk about some of the great accomplishments and the reasons why everybody's actually here. The number of packages available on Hex, as we can see here over the course of the year, growing from 2014 to 2015 to 2016. I have a tiny little sliver of it in 2017. It's not that impressive. It's just started. So I kept that one out. We can also see here a number of package downloads that we have in Hex. And this is a really tall graph. If you can see that little sliver there in 2014, it just scales upwards massively. So the community is growing. So much so that the Nerves project, which actually just started getting a lot of great leverage, the package, when I asked for those statistics from Eric, from Hex, I said, hey, let me know how many downloads the Nerves project had last year this time. He goes, there wasn't a Nerves package last year at this time. So this is one of my fun little statistic brag slides here. I'm really excited with this here. We've crossed over the 10,000 downloads mark for the package in less than a year. And one of my favorite parts about that is that puts us at the 310th package for downloads in the top 8%. All right. But really the reason that we're all here is because we decided to rally around great tools to build some great software. We all decided that we want to be able to use Elixir for creating amazing new experiences like customer-facing websites, some elastic middleware that can really perform and also devices using the Nerves project. So when working through these, I looked at all the other stuff. I took inspiration from as many places as I could, most of which in case were from Phoenix for this talk, because when developing devices using Nerves, it should be really comfortable. And up until now there's been some sort of disconnects that's been happening. The hardware wasn't really always accessible. And in the case of programming on Elixir, you feel comfortable and confident on your host environment, on your laptop, because you can just hammer away code and try it out. And if it doesn't work, everything's fine. So that's why I decided that it's about time that we tried to address this. And I put together a talk today that I'm going to be talking about called King of the Hill, most appropriately displayed right here. And for those of you who aren't familiar, I dropped an L off of there, because in the hardware world, Hill means hardware in the loop. And so what we're trying to do is we're trying to be able to bring the hardware closer to your host machine to be able to make it so that you can have that faster iteration, that faster debugging, and not have to wait, you know, the tragedy of seconds to be able to get to your... It adds up after a while, it does, gets monotonous. For those of you who don't know me, my name is Justin Schneck. I develop hardware and hardware accessories. I work for a company called Latote. And we're hiring, actually. We're always looking for people to join us in the beautiful area of San Francisco. It's not far from here. Probably get a plane. Yeah, but with Latote, I really need to thank this company. I've had the pleasure of working with some of the smartest, funniest, not as good looking as me kind of people. But it's been a wonderful experience. And without them, we wouldn't have been able to get nerves to even to where it is now. So with where we're at, we're at a .4 release right now. And that includes some great additions from the last time I spoke about this. I believe last time I spoke was in ElixirConf in Orlando. And we talked about what was going to be shipping. Well, then is now. We have a new feature that we have out right now. It's called the Docker provider. And the Docker provider basically allows you to on your Mac or Windows machine, maybe, untested. See me afterwards if you can't get working. I need one of you. You can actually use Docker to be able to produce the Linux user land pieces, the actual Linux machine that's going to wrap your code and distribute it out onto the devices. Up until now, this was sort of something that you could only do on a Linux host. And so instead of only being able to do it on your Linux host, now at this point, you can actually run it on your Mac. In addition to that, we have released global artifacts. That's for HEC packages. And this was a fun one and an important one, I felt, because when it came to running NERVs projects, for every single project that you had, you have to download a system and a tool chain. The system can sometimes weigh upwards of 100 to 120 megabytes. And the tool chain could be 80 to 150. And that was not only per project, that was per environment. So you run in dev, then you run in test, then you run in prod. Now you're up to half a gigabyte worth of stuff to be able to produce a system that can run on this tiny, little SD card for some reason. So all of those things add up after a while. And, well, we decided that for stuff that we trust that we can compute the actual hashes for, we're going to globalize that. And we're going to make it so that it downloads it to a shared location in your home directory that you can actually go back and clean out later. And then the reason that we could do that is because we were able to synchronize everything up. We had several packages that have become deprecated now. The NERVs system package and the NERVs tool chain package, they both contain their own compilers. And as it turned out, those compilers were basically the same. So we've sort of made everything now moved upwards into the NERVs package. There's a lot of them when you look at there. The main top one has this package compiler now. So we can have everything sort of point to all the same versions. Everything's in sync. Everything's nice and compact. And everything moves quickly also because we were able to dump XRM and move to distillery. It's really fast. All right, so what do we need to do to be able to do hardware in the loop? So this is sort of what we're going to be talking about today. What does it mean for NERVs to have hardware in the loop? We're also going to talk about the changes that were required in NERVs to be able to get to accomplish this task. And then in addition, I'll show you a cool demo. I'm excited for the demo. It's really cool. So as I said before, we took a lot of inspiration from different places. And one of the places we looked at was Phoenix Reload. And in the case of Phoenix Reload, you have a pretty easy mechanism. You have a browser. And then on the back end, you have your terminal window. And what you do is you press Reload on your web page. And then that sends a request to the running beam. And the running beam, what it does is it checks to see if there's any code changes on the files. And if there are, then it recompiles the modules. And then if everything's cool, then it sends the request back to the browser. And the browser is like, hey, here's your new stuff. And you're like, this is awesome. Where has this been my whole life? So Phoenix Reload also, the code reloader features in Phoenix also has this ability of handling errors pretty well because of its ability to keep the VM running and in a state where it tries to compile it. If you, same way, try to be able to reload a site and it says it fails, well, then it just gives you this pretty-looking error page that says stuff went wrong. And then you go on your way and you're like, I fixed it. Yay. And you don't have to do any more work. And it's great. Now, the issues here that we can't just be like, oh, let's just take what Phoenix did and like, you know, just apply it right to what NERVs needs to do. There was a little bit more work that needed to be done. Here's an example of which. Well, we have disconnected pieces. You have your host computer, let's say that's this terminal window on the left here. And then you have some device, Raspberry Pi, Bucamon Black, whatever, over here on the right side. And that device, it might have some connections that is being made to some accessories. You probably are doing something interesting with it and it's not just sitting there computing stuff because we have much more powerful computers to be able to just sit and do computation. It's probably connected to some sensors or some displays or other devices. And so in this situation, when we would want to be able to reload code, we would actually be synchronizing the state of two different virtual machines. And inevitably then, the code that's being used to run on the target, typically in the case of NERVs devices, it has processes that are running port drivers or interfacing with some low-level C code. And that port driver, that C code, needs to be re-initialized so that it can utilize the new code paths that are present. So what we need to do is, on the remote machine, we basically need to tell it to re-initialize the application stack. And if everything's cool, then we'll just send a message back to the terminal. No big deal. We'll just synchronize two VMs. The problem in this case, though, is that if everything is not good, then we're left in a situation where when restarting the application stack, you're sort of restarting the initialization procedure. And if the initialization procedure fails, then the VM fails, then the network fails, and you're basically left with this equaling this. It's not a good state to be in. We want to try to eliminate the need for SD card swapping. And in this case, you're going to have to go get the SD card out of the box and then plug it in your computer and re-burn it. And that's fine for somebody like yourselves, but maybe not for an engineer in the field or a customer. So we decided that there's three different areas that we need to be able to focus on to be able to make this robust enough to work. We have a section of host tools that are required that need to run locally on your host development machine. We need stability in the network because we thought about this one for a while. We thought, you know, what's the way that we can connect these devices the easiest? Well, Airlang is beautiful for Airlang distribution protocol. We can just strap together these nodes and then everything's going to be great. We can make RPC calls. Everybody's got the network. Not everybody has these like SpyBus or UArts and they're slow. So we'll just have a really solid network. And then a set of target tools that needs to be on the target to allow us to do some air handling so that way we don't turn into the brick state. So this journey sort of unfurled into this magical web of mystery. And let me take you down that chaotic path. And let's start with some of the target tools. Some of the things that I discovered while building this were pretty interesting. So the target requires us to be able to do a couple of things. We need to be able to always boot. All right. Now what this means is like with NERVs, when you build a release, when you build firmware on your machine, you're building an OTP release. And when you plug that SD card into your NERVs device, into like your Raspberry Pi, and it starts up basically it starts Linux and then Linux starts a little shim program called Erlenit that knows how to be able to start Erlang. And then Erlang goes through its initialization procedure and then your application is running. The mantra of NERVs is that we want you to spend as most of your time inside of the VM as possible, because there's no better place on these machines to run than in that VM. I mean, we get a lot of help from Linux on the outside world, but for the most part you'll be more comfortable by staying inside the virtual machine. So in addition to always being able to boot that initialization procedure that happens, you'll know that if you try to fire up a machine on your, you try to fire up code on your local machine that fails initialization, it crashes the VM. And then that's the brick state. If we crash the VM on the target, we basically crashed the OS. And if we have no OS that's running and we're not rebooting, then we're just sitting there with nothing and no ability to talk to it. In addition, it's important that by passing the initialization, that if we were to restart services, that we make sure that critical services stay alive, like networking. So that way we can always continue to communicate with it. And then the last thing that we need on the target is some helpers and some abilities for us to be able to sync code and priv files. Now, we went down a couple different paths with this that were cool. One of which Francesco mentions inside of his new book that talks about using a code server. And there's actually, Erlang has the ability of saying like, oh, I've got these two VMs. I'm going to make this one a code server. And then there's these other VMs that are going to connect to it and they're going to get all their code from it. And it was a really promising looking thing for being able to use for debugging. Unfortunately, it doesn't handle priv files. So when it comes time for you to try to load a port or a nif or some sort of file that lives in the priv folder of your application, it would be looking at a path that doesn't exist because the path would be that of the one on the actual code server. So we had to decide of going a different way here. We needed to be able to sort of scaffold something from the ground up. So in this case, I look for more inspiration. Well, what does a regular system boot sequence look like when you turn your laptop on? Or when you turn a Raspberry Pi on a boot into Linux? So you've got this tiny little shim program that's called a bootloader. The bootloader lays down just enough train track in front of yourself to be able to know how to be able to boot into the Linux kernel. And then that knows how to be able to lay just enough more track down to be able to get to the point where it can start booting your applications and doing something interesting. This is pretty much how most of our computer systems all work today. So that's the interesting part. Well, I knew it there. I needed a bootloader. We got to shim the VM so that we have control over bypassing the default behaviors of the airline initialization sequence. So this led down a path of trying to be able to break apart and understand how releases work. This is where things got a little bit more interesting. So some of you may or may not be familiar with how an actual OTP release gets put together or what the pieces and components of it actually are. But essentially what happens is when you start Erlang on the other side, you pass it a boot file. And that boot file is a series of instructions that tells the VM where to find assets and what to start, what applications to start as part of the initialization sequence. So to make a boot file, you need to do a couple things. You need to start with a rel file. So this is a sample rel file. This is something that you can pretty much easily put together. All it is is it's a, it's actually a four, a four tuple. Yeah. The first part being the atom release. And this is an Erlang syntax because all the rel files are just the Erlang terms. It starts with a release atom and then you tell it what the application is which is its own two tuple with the version. You tell it what version of the Erlang runtime you're going to be using for it and it should look for. And then you pass it as the last parameter, a list of applications and their start types. So when building bootloader what we knew we needed to do was during the process that we create an OTP release in addition to creating the rel file that Distillery will make for you that knows how to automatically bring up your application in a default state. We're going to make another one called the bootloader rel file that in this case, this continues by the way, I trunk this off a little because it's quite long. In this case, our rel file, it, it, it knows just enough, it loads just enough applications to be able to get a usable system running and itself and then all of the rest of the applications and the third parameter here, this is the start type. It just says don't start this application but what that does is it automatically wires all the code paths for us so that it's available for us to start. So we trick the rel, the, the release system into being able to produce this bootloader rel file and then using this you can, you can then pass it to the sysfs tools and say take this rel file make me a start script and then that produces this massive amount of output. I mean this is like super truncated right here. It's just this never-ending file of, instruction after instruction after instruction that basically one at a time gets fed into the, into the, in it system and then just brings up the machine during that sequence and the reason for all of this insanity is because we need to ensure that the initialization sequence always passes and then once we know that it always passes and we boot to the bootloader then the bootloader's responsibility is to triage any errors that we get from then on but as long as that initialization passes we're good. So we want to make sure that we have the minimum amount of code in place that is pristine and working. So here's some information on how to make those files as part of distillery you can actually use the mix release utils right term. We put a couple PRs out to be able to open up some of the stuff in distillery so that we can start leveraging it as well and then the deeper level call once you have a rel file which is that first one then you can just pass it to sys tools tell it to make a script and then that script basically gives you both the script and the binary version of it which is the one that you pass to the initialization command. So we shim this easily with using a plug-in you can see down here for distillery this is a configuration file for distillery all we do is we just say hey when you're running your release I want you to execute the bootloader plug-in and then what bootloader does is it generates those files so that you can use it you can use this with or without nerves it doesn't matter this isn't a nerve specific thing it's supposed to be a little bit broader and then now we're left with this we have a VM that's that boots to the bootloader and then we use the bootloader to boot our applications. So the second part of bootloader is that it handles code updating for us we put some helper files and functions in to be able to do the stuff where we're talking about synchronizing the important pieces modules applications and priv files and so how we do this is we have some functions we we have an application controller and that loads all the applications that knows about and you just say hey application controller give me a hash and the hash is essentially it's it's a hash of all the hashes of all of the important files and so that way we know with just one little cache line did anything change if something changed since we're on since in nerves we're on a read-only file system we want to be able to do something that we're calling applying an overlay so instead of just loading these new modules what we want you to do is we want you to execute a strategy where you write the files over to this read write partition because the ones that you have are read-only and then we want you to update the code paths so that when you apply the overlay that's going to just go and lay on top of it so then we prepend the code paths so that when it goes looking for the modules and the priv files it'll find them there first and if it doesn't find them because we're only putting in a partial fragment of an overlay it falls through to the old ones that way we can then reversion our stuff over and over again we can reload the applications and then everything's back to where we were so the second component of this now we have the target in place we can update it we can keep it running the second component of this a steady network well when I got to this step I thought to myself how hard could this be it's networking and then I remembered oh there's a package called interim Wi-Fi yeah now not interim Wi-Fi as a matter of fact it just so happens that the interim part of the interim Wi-Fi package meant that it's still being worked on not the matter of that on the Raspberry Pi 3 that you see here it only works an interim amount of times like I had two boards from two different manufacturers both Raspberry Pi 3 and one of the two of them would when booting bring up the Wi-Fi properly load the Wi-Fi stack properly one out of five times the other one zero out of five times yeah I caught wind that in the channels we have for support that people were saying that they just did essentially tell their customers to keep plugging it back in until it works I mean even windows you only have to reboot three times to get at the work right all right so here's a yak here's a Raspberry Pi 3 here is me fixing Wi-Fi so there's this term I learned recently called yak shaving you're probably familiar with it if you're not basically the idea of yak shaving can be summarized in this statement I said this now here I am recompiling GCC on my Mac just so I can burn an SD card so I can test out the new Linux kernel so I can see if Wi-Fi might work better yeah it's a series of tasks essentially that lead you to the point where you're like I just wanted to do this thing over here and now all of a sudden I'm shaving a yak I don't understand how I got here so as a nice response Lance says to me the irony of this fact is that I'm probably the person that he both vote most likely to shave a yak at any time and of any size that was pretty funny until I had the sad realization that working in hardware is kind of like that so I'm putting my entry in for the elixir yearbook most likely to shave a yak so what did this problem turn out to be well I we investigated it for a while we tried to update the Linux kernel essentially what happens is the Broadcom module we were compiling into the Linux kernel there's two ways that you can run module Linux modules you can compile them into the kernel or you can compile them as a module and then you can just load them in at runtime apparently the Broadcom module doesn't like to be compiled into the kernel and that our tests showed that when running against Raspbian even Raspbian doesn't have it compiled into the kernel probably for you know portability sake but in their case they're just doing a mod probe on start and mod probing it on start seems to yield the results that it always works so problem solved we're gonna pull the Broadcom module out of there and this whole experiment because I was looking for like toys to play with you know how you do development right you're like oh I need a little pet project I can build so that it'll drive me to building this feature got me one step closer to ice cold beer in my in my kegerator so that I could monitor the temperature and have a beer I needed it after this the path was getting deep I figured oh one yak's not enough let's shave more on top of that we decided that interim Wi-Fi was too inter me and it needed to have some things go here's a PR that we just merged recently to rip gen event out and replace it with registry so another thing next version of nerves one four plus on elixir yeah cutting edge that we like it registry was needed because we we wanted a consumable way to be able to monitor event changes and interfaces like when an interface running DHCP gets a new IP address in that case we wanted the ability for the IP address change to affect the name of the VM so the strategy is that you register for notifications on the network interface you'll receive DHCP events as they come in when that DHCP event says that the interface address changed you bring net kernel down you bring it back up with the new name and now all of a sudden you have an addressable node again so now we fixed the network things are getting better we're finally getting towards the end of this path and the last piece left that I wanted to show you here on this case was some of the the work that we've done on the host tools so the host is a tricky place the laptop that you're running on and at this point in the equation I started to see the light at the end of the tunnel I had working tests that I could actually code make code changes on the on the remote device with bootloader and I had a network that could get me there to do it now at this point it was ready I was like alright now I can start pulling pieces of inspiration in from Phoenix and I can take a look at what they're doing with the monitoring systems and so I brought in FS and the idea here was that we need to know we need to look at all the source files that are on your machine for the different applications that you're running including some of the dependencies that are path based because if you're an umbrella we want to monitor those too so we brought in FS into a project that we're calling the nerves reactor and FS is just told to monitor all these files including the priv directory files and then whenever it receives a change then it just says hey try to compile it much like how Phoenix works and in theory this all works fine in reality you're running underneath a host environment that is always being compiled for the target so here I am I'm ready to be able to test this out I'm ready to see the fruit of my labor and and all of a sudden then it says FS kicks me back in there that says what native interface for Mac are you talking about I'm running on Linux nope doesn't work so what's the reason for this well I've said this in the past nerves based projects will always compile for the target and the reason that that decision was laid down that way is because it's very important that the environments don't get mixed up throughout the next life cycle because nerves does so much to be able to patch the life cycle so that it can find the right cross compilers so that your machine can produce code for what it thinks is a Linux machine or a target that's of a different architecture and this is past Justin saying this so now I'm saying it'll sometimes compile it for the target this is a change that we had to make a realization that I've come to and to do this we're sort of taking the step into the next level of adding a second layer an additional layer of mix ins for configurations in addition to mix and which you're going to we're we're hiding hooking on to called mixed target here's a pull request it's still open making this change isn't a slight easy move actually making this change will actually impact a lot of documentation and a lot of functionality primarily what does this look like from the outside in well our new project generator mix nerves that new it always took a target at the end because we always needed to know what you're most interested in compiling for because host wasn't an option so you'd say oh my default target for this application is going to be a Raspberry Pi 3 and then it would structure application so that you could you'll always by default be compiling for Raspberry Pi 3 so all your mixed commands would just always be in that environment now the change this is before this is after well you no longer in the new project generator coming out need to be able to specify the target because we're going host first in this case a complete 180 and now all of the default mix commands that you run just like you would with any other application and any other project will compile for your host machine first and then if you want to be able to produce firmware produce an output for a different target like a Raspberry Pi 3 you pass in mixed target and let the system know that you're interested in moving the component to the different environment so the main component of this the most interesting part of this switch actually is this section right here this is inside of the mix file that gets generated this is where we define our aliases and in the case of mix there's nothing magical about it all of the aliases are declared inside of the file so that things are explicit these are what we do in the case of compiling for a any target this says but now in the new project in the case of the host we're saying don't invoke the the nerves environment as part of the the mix lifecycle we want to actually compile for the host now this introduces a couple different interesting pieces though in the case of nerves projects since there's a lot of times that you're including applications like let's say elixir ale for example which is a an application library written by Frank Hunliffe that knows how to be able to interface with GPIO pins like twiddling pins for that are on like a Raspberry Pi or a piece of hardware that aren't necessarily available on your Mac that application on your Mac will not compile unless it's compiling underneath the nerves environment through the target well if you were to let's say design your application so that as part of the start sequence of your application you wanted to also start elixir ale and start twiddling some sort of pin well then if you tried to run that in I and I X session on your host it would crash so another change we're making is we're defining multiple pathways to be able to start the application in the case of starting on a target you'll be able to define a starting point for the application and then that way that will be able to bring up all the target specific stuff and if you're starting on the host inside that project you'll be able to define either nothing or an additional pathway let's say if you want to be able to stub out some things and mimic some of the functionality that elixir ale might provide because you want to execute some unit tests another thing that we didn't have before yay so here we are the path is getting longer and I'm getting weary because up until now on my path to being able to do hot code reloading I've been doing SD card swapping now we have something in place that allows us to be able to do full remote for more updates it's nerves under for more under HTTP it lets you push for more updates over the HTTP but up until now the only way to be able to do it would be to be able to like hack together some sort of curl command on your machine or others in the community would write some lightweight mixed tasks that would in themselves hack together a curl command on your machine but the beautiful part is now everything just unfurled we see that we have the ability I can run any utility I want on my machine as part of a nurse project now that can complement the actual target so now at this point when bringing in nerves firmware over HTTP we introduced a a new step called firmware push and running on your local machine you'll be able to say mix firmware push to this device this this target and what it does in the background is it compiles a firmware package which is an OTP release and the entire Linux operating system changes and it gives you nice beautiful progress bars inside of the window that you're in and then applies the change and reboots the device on the other end so here's a yak here's mixed firmware push yak shaved this is what that command looks like by the way you have a couple different options you can see that you can say whether or not you wanted to reboot on the other end when it's finished where the actual target is and you can actually point it to the firmware you have to pass either target or firmware you can if you pass target then it'll discover where the firmware is based off of the the mix file itself if you pass firmware then you can just arbitrarily send it to whatever fw file you have on your machine doesn't even have to be for that device you'll find out later so that's what that command looks like when you go to run it you just point it at a place on the internet and when land whatever it'll just try it's best to be able to get there best part about this is it's a begrudgingly written using HTTP see so there's no additional dependencies on your machine it uses all the built-in stuff that's inside of your langvm on your on your host computer so here we are now back to the point where we can execute code I'm happy again I can push firmware I don't have to SD card swap anymore let's get this done so the next step well from learning my lessons with HTTP for with firmware push I found that there's a little trickery that's involved in starting in one mix environment I that's probably not the right term to use there I should say bringing up the mix application with one set of configuration parameters like mix environment is dev and mix target is host and then tricking it so that you can say bring yourself back up again but I want you to be mix environment is dev and mix target is Raspberry Pi 3 and doing that in a way that's proper we needed some hygiene here so what we're doing is there's some there's some funny business happening behind the scenes and instead of doing it inside of the pristine session that you're running in we wrap it all in a in a transient VM and we say hey you decorate yourself like this and we're going to tell you when we need stuff from you so here we are we're back to the point where we've got a running reactor we've got a stable network and we've got a working bootloader and a big pile of yak hair let's see how this works so up here I have a Raspberry Pi 0 connected with just a USB cable giving it power and it's a it's running bootloader right now so it's waiting for some instructions and I have this example application that I'm going to mirror my displays with now so that you can see it because it would be a really bad demo if I can see it but you can't let's do a little fun window treatment here everybody can make fun of me later for not having a window manager if you find one that works nicely let me know I know you have opinions on this Chris all right so let me tell you what we have going on here the top right here I'm sorry the top left is just my console window sitting inside of a regular project that's this project here I'm calling the pi reactor all right and on the bottom left here I have the serial console of the ix session that's actually running on this device so on this device I can do things like hey pi reactor do you have a hello function oh it's undefined now you don't okay so first let me show you some of the new setup pieces and we'll look at the mix file first that I talked about this is part of the change that we made we can see here now that we're going host first as our default for mixed target we're adding in some additional pathways like I said we're changing aliases on target now which down here decides whether or not we want to invoke the nerves environment and then we're also splitting our dependencies when we get to depth we have these are the shared dependencies that will be existing on both my host and any target I run on plus the dependencies of any target in the case of raspberry pi zero I'm including the raspberry pi zero system and nerves networking because I don't need to use nerves networking to bring up the network on my local computer and then any other target we're gonna this is just some magic here where we're saying if you passed something other than raspberry pi zero just go fetch the system for it whatever we'll try our best so the other additional changes like I said this is where we split the code paths so that way if I try to open up an IEX session I can actually boot into a working VM and it didn't try to be able to bring up some specific stuff like what's happening in this application here take a peek at that it's trying to fire up the initialized network worker which would actually try to start configuring DNS mask on it to be able to start a DNS server probably is not gonna work too well on my Mac at least in this configuration so and then some additional stuff that I'm doing this stuff is all in the documentation you can pass in your owner neural init commands so that we can change the serial ports and we're doing some other configuration stuff like we're telling bootloader where which application we're interested in running and where we should store overlays on the target in this case the on on nerves devices the default place for read write partition the app data partition is that is mounted at forward root so we're saying make a directory called oral overlays and put the stuff there and then we're just configuring some static networking and we're telling when we when we build firmware to include our own root fs edition so that we have this custom boot command okay so let's take a look at how some of this fun stuff works so here I am in an IEX session I'm going to start the reactor and tell it that it should interface with this remote node and now here we are as I said in a new session with some you know don't mind that that's the man behind the curtain right now we've got a connection to that session and now this is fully fired up and wired and ready to go so if I if I call this command we can see oh it doesn't exist but you know now that we're live programming let's go and check it out let's go into the pyreactor module here and let's say def hello do and we'll hit we'll hit save it'll synchronize an overlay and all of a sudden now you got hello world as I said the nice part about this is the portability aspect that it's it's really small fragments that gets sent over all that actually happened in this overlay is that it ended up transferring this modified module that it needed to be able to apply on the other end and if we take a look here we'll see at the root yeah there's a directories worth of different overlays that have been applied during the lifecycle of this application and some might cancel out others so in our case we can say okay I don't want hello world like I want to go back to the to the old way of doing things I just don't want anything at all and when I hit save it'll synchronize a new overlay now that doesn't work anymore things are really fast it's great it's almost as if it's right there on your machine it's the speed of your network and the beautiful part about this is that even though this Raspberry Pi zero just so happens to be connected physically to my laptop doesn't mean that it actually has to be physically connected to my laptop since this runs over the network this Raspberry Pi I could be remote debugging it and it could be in a closet in the next room over the only thing that you're not going to get right now is this serial console output that I'm getting unless you're also rem-shelled in which you can do because you're not bringing down the VM on the other side you're only interacting with the bootlayer bootloader shim so let's take a look at the other piece the interim piece now that we're doing our remote debugging is over and we have our our thing in production we can see here we have no we have nothing to find let's kill the reactor and let's define a new thing here def reactors not running code did not get synchronized but let's say we're in more of a production state we want to start pushing stuff out so what I'm going to do here is I'm going to set my mix target and compile some firmware a little faster than SD card swapping that still not as fast as the reactor once it's done creating our entire Linux image and firmware now that we have the firmware file we're going to end the host from the host environment not setting mix target we're going to tell it that we want to execute a firmware push because we need that code to be able to run on our host we needed to be compiled for our host and we're going to pass at the some of the default parameters here and we'll say we'll say review to now what this just did is something that you would this there's a combination of events here that you're going to be using see the nerves reactor is good when you want to be able to do code changes in elixir and like I said we would like it if you could spend as much of your time as possible inside of the VM because it's a nice place to be but let's say that there's a situation where you need to be able to add some sort of Linux land user process that you didn't have on the on the machine before so you'd end up changing some configurations you'd use the Docker provider to be able to produce a new Linux image take a while and then once you're done building your new Linux Linux image that has all your other user land functions in it you'll marry that to your elixir application to your elixir code and then you'll need to push that firmware to your device is something new you can do that by putting the SD card in your computer and re-burning the entire SD card but you'll lose all the contents of your app data partition unless you run an upgrade task but you know by default you'll lose the it'll just flash it all so as I said there's you're going to use complementing pieces of these tools to be able to to work for debugging in this case the reactor won't be able to synchronize user land programs and applications because it's outside the VM to do that you would need to push a new user space to it a new Linux kernel or any other Linux land applications and with firmware push we can do that what it's doing is actually it's it's loading the firmware onto the device and it's streaming the firmware into the B slot and then it boots into the B slot and so your old firmware is actually still left in the A slot and if you were to fail in the B slot while you can you can inside of your application take the necessary precautions to prevent yourself from getting into that dredged brick state and then just boot back to the last version it's good for production not necessarily the best for this situation so let's see if we've succeeded so there we go all right I'd really like to thank Tim Mecklem Tim works for Gaslight Tim is the one that that did all the work necessary to be able to take the Raspberry Pi 3 system image that we provided and what he did was he got this is a running what's known as gadget mode so it's running as a USB gadget and that's how over this USB interface I'm getting both serial and additional serial port and a network interface to be able to very in a very compact way I do the work necessary to show you this today Tim also got the what's known as the IoT P hat or as the kids are saying that the fat working which is a it is a a hat for Raspberry Pi 0 that adds Wi-Fi and Bluetooth to it to be able to make it act and more like a Pi 3 as I put it it really gives it a purpose I mean what are you going to do with these tiny little devices if they don't have a network connection so thank you Tim for building that system if you want to check it out there is a link down here you can go to his site we're going to be building a more official repository to hold all of these community additions that we have in addition to Tim's work I'd like to be able to say hooray we hit 900 people on Slack channel yay lots of people are starting discussions it's a little tough to keep up with at times it's a lot smaller than the Phoenix channel but I'm really proud of the fact that we have so many people in the community who are interested and understanding that the same tools that that they use in their everyday lives that they're interested in that you guys are here to learn more about can directly apply to being able to build and tinker with hardware and and then it's not that frightening anymore once you have the tool set under your belt it's just a matter of plugging some stuff in and playing around with it and seeing if it works there's a lot of great tutorials out there as well that you can be able to get up to speed with and if you also always have questions you can just join our nerves channel there's a bunch of great people out there that are putting together stuff commercial products at LaTote we're using NERVs Phoenix and Elixir to be able to build an incredible stack to be able to automate a lot of the work flows and processes inside of our organization now what's next for the future well we're going to finalize the work on mixed target I'm hoping to make that more of a household term and we're going to change our documentation because we're doing that complete about face 180 make sense we're going to finalize the work on bootloader and get some more test coverage on that writing the test for bootloader to prove that the most early starting replacement to the airline initialization system was probably the hardest piece of code that I almost had to work on to date it's very odd it spins up a whole bunch of different BMS and they all kind of talk to each other and shut each other down and it's it's like that chaos monkey I guess like that kind of like that a big thing for me I want to finish uninteriming networking it's a shame that we have that in the name of our package but you know for just cause networking is hard and Wi-Fi is a lot harder and we're looking to be able to ship more as we're calling it batteries included systems the the goal for NERVs was always to be able to provide and build extremely lightweight distributable Linux VM Linux systems that had the airline VM and your code inside of it and so you know with with the minimalistic approach that we have today we tout the ability of producing systems that are in the megabytes tens of like a 10 10 to 20 megabytes with all your code in it and the full Linux system the batteries included systems are going to be the complete opposite of those they're going to contain almost everything that we can turn on that you're interested in and keep an eye out for those because we have a lot of people that are working right now on releasing these systems to use for Raspberry Pi WebKit kiosks so there's a lot of projects out there that that that are starting to show using the seven inch Pi foundation touchscreen displays with the Raspberry Pi on the back to be able to build a kiosk that can leverage Phoenix for its user interfaces then you can use Elm you can use whatever web languages you want in addition on those battery included systems we're just going to be able to turn on a whole bunch of drivers we're really hoping at that point that we're going to say hey if you're the minimalistic image didn't work for you because your Wi-Fi chip that was built by Joe's computer shop down the street doesn't work you know try the batteries included one and and it's going to weigh like 200 megs but you can at least see if it's going to solve your problem and then and then turn on and off whatever options you need later to save space so with that I'm really happy that everybody is here today because this conference proves that we can continue to grow and rally around such awesome tools and that we're all so interested in learning more about what Elixir can provide for us and our businesses thank you all right we have time for a few questions any questions hey I know that you I think address on slack a little bit but part of the firmware push the security aspect of that locking that down making sure that hey I'm the right person that can yeah so Garth is currently working on adding in the ability to secure that better with some certificates the work there is not done yet but the firmware push mechanism is sort of a primary step in the way of adding a level of of I trust the network I'm on level of convenience but yeah we you know we are we are looking to be able to add a higher level of security to that aspect and I believe we're still at the stage where any level of input from the community would be appreciated and you know we can all open some conversations and talk about what the best way to be able to add that level is that would work for everyone you know the questions all right let's get Justin a big hand