Okay, so let's keep on going with our rename object tool. And the first thing I want to do is I want to detect if the user has gone and selected a certain amount of items. And I want to display that certain amount of items inside of this window here. Alright, so let's go into our ongoing method here. And what I want to do is I want to assign an array of objects. Okay, so that means I'm going to need an array of game objects. Okay, so up here in the variables, actually, I'm going to add a new array and I'm just going to call this selected, like so. Alright, and we can always initialize that as well. So we can say new game object of ray 0, like so. Okay, and I'm going to come down here into the ongoing and I'm going to say selected is equal to selection.gameObjects. And the reason why that works is because this particular property, alright, this C sharp property is returning to us an array of game objects. Alright, so what we can do with that is we can now then display that inside of our label field up here. So I can say something like this, we can say selected then colon. And then I can concatenate so that just means we're going to add on a string by using the plus symbol there. Alright, so we're going to say selected.toString and let's just keep it to a format here. So we'll say 0, 0, 0 like that. Alright, that's how we go and format our string. And what we need to actually do is get the length of this array because this is an array object here. So I'm going to say dot length, that's the length of the array. That's how many game objects we have stored inside of this array. And so that is what I want to display. So I'm going to say selected and then the amount of objects that we have selected. Okay, so we save that and go back into Unity here and let's test this out now. We could test that out with just these two game objects, the default, the directional light and the main camera. Alright, so now I have my editor window here and if I start selecting stuff, you'll notice that it's not updating. And that's no good because you can see that when I come and actually focus the window it'll tell us how much game objects I have selected here. But I really want that to update in real time. The reason why it's not updating in real time is because we actually need to repaint the UI all the time. Alright, so this repaint method right here will actually update that UI for us in real time. Alright, so it just updates it as we're selecting stuff. Alright, so let's test this out now and you can see now we're getting an update all the time. So in real time I select something that's updating. Just that simple. We can just utilize that repaint method. Cool. Alright, so the next thing I want to do is I'm going to just make those guys a little bit more neat like so. And we can even go and add some comments. So we'll just say get current selected objects just to be professional about this. And then what we'll do is we'll say we'll display our user UI. Something like that for now. Alright, so what I want to do is I actually want to give the user of this tool the ability to change the prefix, the actual name of the object, and the suffix. And I want them to have the ability to add a numbering to it if they choose or not. So to do that what I'm going to do up here in the variables is add a new string that is called the current prefix or actually it's called wanted prefix. We'll do that. So wanted prefix and then we'll do string wanted name. Alright, so it's a name that we actually want to give our objects. And then we'll do string wanted suffix like so. And then finally we're going to do a boolean okay it's a bool and we'll say add for the boolean name, the variable name there. And that'll just allow us to add on at the very end of the string some numbering to it. And what we're going to do in this video is make it relatively simple and basic. And once you you've gone and watched these videos and you've created your own, you're obviously more than welcome to go and add whatever you want. So I definitely encourage you to go in and customize it as you see fit for your particular project or your needs. So what I want to do now is I want to actually put all those guys into the UI. So the easiest way to do that in this case is let's do the wanted prefix first. We're going to say wanted prefix is equal to an editor GUI layout item. And this item is going to be a text field alright. And let's take a look at the arguments for that. So the arguments that we get for the first one is string text. So that's going to be our wanted prefix. That's the text that we want to populate with the value that the user inputs. Alright, so let's go down one. And we have this GUI content just like what we did up here at the window. We can assign a GUI content to this and then the string and then some parameters. And then we have string text and a GUI style. So this is when you want to customize it to your own style. And then we also have the one that I usually use, which is just the string label. And that's the label that will sit in front of the text field. And then we have the string that we want to update. And then we have the parameters. Okay, so for the label what I want to do is just call this prefix. And then put a call in there in a space. And then for the string, the string that we want to update is that wanted prefix variable. And then actually let's just start there. Because that should work right off the bat. So let's come back into Unity over here and take a look. So let's just take a look and see what we get up here. Alright, so now we have a text field and we can type stuff into it. Alright, there we go. Cool. So let's go and actually add the rest since we're at it. And what we can do is we can actually just copy this here. Alright. And we can say the wanted name. Alright, so this just makes it real easy here. Is equal to that name that we want to input. And we have the wanted suffix. Alright, so we'll say wanted suffix is equal to this. It's that one more time. Looks like I copied it wrong there. Alright, so we'll do copy, paste. There we go. And then we want to do suffix. Like so. Cool. Alright, so let's go and take a look at that. Jump up here. Let that compile and we'll update our window here. And now what I want to do is I want to actually provide this a little bit of styling as well. You know, to get things rolling and testing you could just do that for sure. That's obviously totally valid. But I want to start diving into some you know, more of the styling side of stuff here. So let's just do some really simple stuff. So the first thing that we can do is add a vertical layout. So I'm going to say editor-gui-layout.begin-vertical. And now we allow ourselves to put these things into basically boxes if you will. Alright, and these are kind of containers that you put your UI into. Alright, and we'll take a look. It'll actually become more evident as we get through more of this. So anytime you begin a vertical you need to end a vertical. And so we're making a vertical layout for this. So to see this what I want to do is I want to add a GUI layout.space. It allows me to add a padding between the values or these UI elements. And so what I'm doing is I'm adding a 10 pixel padding in the vertical direction between the top and the bottom of all these guys. So let's go back into Unity up here and you'll see it just space a little bit below this selected item here. And there you go. So you can see it move down a little bit. So now what I want to do is I actually want to space out the horizontal as well. To do that we can actually put that vertical inside of a horizontal. So let's do editor GUI layout. .begin horizontal. Alright, so hopefully you can see a pattern here. So there's editor GUI layout .end horizontal. So you always got to end those. And in between that horizontal and that vertical layout we can add that space as well. Like so. Alright, so let's go and watch that in action. So now we have a little bit of space there. It just helps, you know, it's one of those subtle things. It just helps you see stuff a lot better. Alright, so let's go back into Unity up here.  That's what we're going to do. Thank you. So let's go in here and the first thing I want to do is I want to add an editor style. Editor styles. And I'm going to make this a mini text field. You can see we have a bunch of, let's do mini and text. There it is. Alright. Very cool. Okay, so I'm going to copy that and we're just going to plop that in for all these other guys and then we're going to go back to Unity and take a look at that. Okay, so let's go back to Unity. And this will change the look of it. Alright, so this is in the mini text fields. And you'll notice that what happens is they get mini. But I like the look of them. Alright, so what I want to do now is I can actually force it to override. So we can say GUI layout dot expand width. And we'll just set that to true. Alright, so let's copy that for all the others as well. So I'm going to jump down here and paste that as well into there. Alright, let's take a look. And there we go. So now we're expanding it. Pretty cool. So now what I want to do is I want to put a little box around it. So inside of our begin vertical here what I can do is I can actually utilize that editor styles again. Alright, and I can say editor styles and we can say help box like so. So we can put a style into that and it'll surround it with a nice cool looking little box. There we go. Not too shabby. Alright. So that's our prefix name and suffix. Okay, so the last thing I need to add is that Boolean. So we need a little toggle. Alright, so I'm going to put that into this vertical layout here. So what I'm going to do is I'm going to say add numbering is equal to an editor GUI layout dot toggle. So and we want to utilize the again the label and value override. So the label is going to be add numbering and I always like to put a little question mark after that in a space and then we'll put in the variable that we want to populate with the value of this toggle. Alright, so it's constantly assigning it to it. Alright, let's jump back in unity now and just take a look. We should have a little toggle right below here. Super cool. Okay, so now we can turn that on and off. Alright, so the last thing I really need for my UI is a button because the button is going to be what actually runs the functionality of renaming everything. Okay, so I'm going to jump back in unity here and outside of this begin vertical here, I want to create another vertical and actually let me put in the button first so you guys can see. So I'm going to say if GUI layout dot button. Alright, so this button is going to return a true or false value. You can see down here returns a bool. Okay, so if this is true, so this button is going to be named rename selected objects. Alright, so if that value is true then we're going to run some code in here. Okay, so we'll say debug dot log and we'll say renaming objects. Like so. Cool, so let's jump back in unity now and we should see a button down here but there's going to be a little bit of a trick to this. It actually ends up on the side here and you can see that we're running that log which is great, but I really wanted this button down here. Now you can obviously leave the button on the side as well if that suits your desired aesthetic. But what I'm going to do is I'm actually going to put it down on the bottom. Okay, so I'm going to do another editor or GUI layout dot begin vertical like so. And we'll do editor GUI layout. Oops, let's do that one more time there. So editor GUI layout dot end vertical. Always need to close it. And Unity will remind you if you forget one of those things. So I'm going to put the space in there again just keep things nice and clear. Alright, so now this button is going to move down to the bottom here and it didn't. And I got that wrong didn't I? So basically what we need to do is we need to put it inside of, oh that's what it was. So sorry about that. I just need to move the begin above all this right here. Like so. So you've got to keep all your vertical and horizontals nice and clean. And the reason why I'm doing this is because I want the button outside of the box. The help box here. Alright, there we go. Cool, so now we have the button at the bottom, but it's a little small. So let's go and do some styling to this as well. So you can add in all these options. So I'm going to do a GUI layout dot height and this height is going to be something like 45 and it's not a string. It's just a number. Okay, and I want to make sure that this expands as well. So I'm going to do GUI layout dot expand with is equal to true. Cool. So there we go. Let's go back to Unity and make sure that this actually looks correct. And there we go. So now we actually have a pretty cool looking tool and that's just using all the default Unity UI stuff. Alright, so very cool stuff.  So currently we have to come up to the menu and hit rename objects. That'll pop up the menu which is great. That's totally fine. But what I can do is I can come back to my object rename menu and I can actually add a little bit of information to our menu item here and that information is going to be a percentage sign which stands for control. Alright, and then a hashtag sign which stands for shift and then the keyboard key that I want to use for my hotkey. Now this combination of items, alright, or the string right here means I need to hold down control, shift and R on the keyboard. Alright, and that will actually run this code as well. Okay, so let's go save that and try that out here inside of Unity. Alright, so I'm going to hit control, shift and R and voila, look at that. So now you can start building up your own custom sets of menus and editors that are launched from specific hotkeys. Now you definitely need to make sure that you go into the edit here into the preferences and then into keys and you can see that some of these are already hooked up to hotkeys. So definitely make sure you can see which hotkeys are already occupied. And then just add on your own. Cool. So I'm going to leave you guys there and in the next lecture we are going to get this all hooked up so we're renaming objects. Thanks so much.


This study investigated the effectiveness of using multi-spectral vegetation indices, MSVIs, and crop height measurements derived from a compact camera mounted on an unmanned aerial vehicle, UAV, to predict grain yield and determine if an additional side dress application of nitrogen and fertilizer was needed just prior to flowering. The study found that the wide dynamic range vegetation index, WDRVI, was the most effective MSVI in predicting final grain yield. Additionally, the study demonstrated that the combination of WDRVI and crop height provided the most accurate prediction of grain yield compared to other MSVIs and crop height alone. Furthermore, the study found that a grain yield of 16.12 mg.hoV-1 could be achieved when applying an economic optimum rate of n-fertilizer, 239.8 kg.n.hoV-1. This article was authored by Angel Merezma, Mara Riza, Elias Martinez, and others. We are article.tv, links in the description below.


Close. OK, cool. Well, welcome, everybody, to simplified cellular IoT with Blues. I'm assuming you, like me, are at least somewhat curious about how the power of IoT and low-power cellular can help you build awesome projects like connected toasters. In reality, you know this is one of the perception problems we have about the IoT today, and we're going to talk about this a little bit later. First, I want to step in a time machine a bit and head back a couple of decades, probably make you sick by looking at this slide for too long. Back to the late age of cassette tapes, as we started kind of migrating to CDs, that being about 1998. Just to set some context for 1998, this was when the last episode of Seinfeld aired. Harrison Ford was considered the sexiest man alive. And far more importantly, in Windows 98 was released. And this is when I got my start in programming. And back then, I was focused on web development, static websites, hand-coding rods, TML, no interactivity to speak of. It was about this time or maybe a year or so later that I learned about this growing set of dynamic web application frameworks like your cold fusion, Java server pages, active server pages from Microsoft and PHP. Collectively, these really brought the idea of the dynamic web to life for me. So these are web applications turning into, sorry, web pages turning into web applications driven by data. And the reason I bring these technologies up today is because it was really the first time in my programming experience where I could interact with something tangible, right, with data in a database. It was one of the first real empowering moments for me as an engineer. And I want to hold on to that idea of empowerment and come back to it in just a bit. But instead, I want to fast forward now to about 2010. This beauty was considered by CNET as the best smartphone on the market. This is the age of Justin Bieber, of course, and I know you're all excited about Twilight Eclipse coming out, Team Edward, Team Jacob, all that. Again, more importantly, it was in 2010 that the Arduino UNO was released. And it was within about a year or so of this that I was introduced to what I consider the second instance of true empowerment in my career. And that's with blinking LED lights, right? And of course it sounds like a joke, but I think most of us can probably relate to this and understand kind of where I'm coming from here because for the first time again in my career, I could write code that started to interact with the physical world. So those early web frameworks were empowering for me as a developer. And my first steps with coding for the physical world were empowering. And today, I want to introduce you to what I consider the third instance of true empowerment in my career. And that's with the super scary surprise in the bag over here. I don't want to ruin it too much here, but you can probably guess what's going to happen. But again, kind of sounds like a joke, but I think you'll see this is an example of kind of how far we've come in the IoT today. It is a silly example and it does kind of perpetuate the perception problem of the IoT, I admit, but there's a very pragmatic undertone to this. So we'll come back to our friend in our bag here later on. So that long-winded intro to this talk brings us to here to today. My name is Rob Lauer. I'm director of developer relations at a company called Blues. Blues is an IoT company that is really hyper-focused on making wireless connectivity easier for developers and for product designers. We're founded and led by former Microsoft Chief Software architect Ray Ozzy. Ray is well-known for starting up Azure back in the day and he was a key figure at Lotus. And I don't need to introduce anyone here, I'm sure, to the concept of the IoT or embedded development, but I do want to kind of set the stage a little bit. So a lot of what we are collectively building today revolves around using a tiny microcontroller to do what? We're maybe sensing something, measuring something, tracking something, maybe even controlling something. And the IoT exists, of course, to do what? It's providing this cloud integration for embedded development. So really empowering the embedded space, if you will, just like those web frameworks enabled web development for me back in the day. And this connectivity thing is important, why? Well, because aside from connected toasters, we all hope the IoT becomes a key component of expanding the reach of the internet. It is such a weird name, though, the internet of things. Like when the web took off in the 90s, we didn't call it the internet of PCs.  So why do we insist on calling this next revolution the internet of things? It almost sets itself up for failure. Now you have to pardon me as I get on my soapbox here for a little bit because I have some pretty strong opinions on the IoT. It is related to why I'm here today, but I wanna start with the, if you do Google image search for IoT or internet of things, you get these like nebulous web looking things. To me, it says that nobody really knows what the IoT means in the general public, right? It tries to be everything and ends up being almost nothing at the same time. And of course, like I mentioned at the beginning, the IoT has a major perception problem. It does include internet connected flip flops. It's a belt that has an internet connection to your mobile device. It's a series of devices that lose connections. It's firmware updates that disrupt our workflow and add friction to our lives instead of removing it. It's newly created privacy concerns.  And all of these make the IoT really easy to dismiss as a fad. And if you're familiar with Gartner's hype cycle, this is why recently they have placed the IoT in the trough of disillusionment here. But there is hope, this isn't super depressing. I would posit that the IoT is still in its early stages and it is a very natural next step as we have migrated from mainframes to PCs to the internet age, to mobility and beyond, right? Devices are doing what, they're getting smaller and we're getting a lot more of them and they need connectivity. So as mobility is maturing and as we're entering the AI wearable, AR, VR, I hate to say, but metaverse stage, that really does include the IoT for sure. So we're talking about an almost immeasurable number of devices that are connecting everything. And when the analysts talk, they talk about big B billions of devices and big T trillions of dollars. And there are really virtually limitless, legit examples of the IoT solving problems today, lowering costs, providing meaningful value, whether it's industrial monitoring and issue diagnosis or using the IoT in agricultural settings, right? They're gathering an insane amount of data by hand that could really never be gathered, much less processed, or sorry, they're gathering it automatically that could not be done by hand. Or in healthcare where you're seeing the IoT literally extend the reach of services into previously difficult to access places. So why am I off on this tangent? Because I feel like it's important for me personally that we kind of battle the FUD, the fear uncertainty doubt about the IoT. Because I feel like the IoT is really only gonna succeed when it solves problems in the embedded space where connectivity is critical, right? Connectivity enables us to do something that would be difficult, if not impossible to do otherwise. Connectivity really becomes the secret sauce here. And IoT solutions that focus on that, that focus on solving those real problems with connectivity are really key to advancing and legitimizing the IoT today. And as IoT developers, we are really key to unlocking this value. That's okay, that's me off my soapbox now. All right, now I'm not using this meme right at all in any way, but I do wanna use this to oversimplify the fact that the IoT and blues effectively exist to bring the device and cloud worlds together. We are really here to make wireless IoT easier and help accelerate your prototyping journey in a really authentic and legitimate way. So what the heck does blues even do? Why am I here? Well, our core mission at blues is really to make wireless IoT easy for developers and more affordable for businesses. Our focus is on securing your data from the moment it's acquired from an on a device from a sensor all the way through to your cloud application. All of our hardware solutions are low power by default to the tune of about eight microamps when idle. And we're also a very developer focused company. We are developers, we're building products for developers, we know the developer. Our developer experience is absolutely a top priority. And I think you'll see that play out with some of my demos here today. But I do wanna pause here because if you're like, whoa, this is getting a little salesy. It's a little too much of a vendor pitch for my taste. It is a vendor pitch, but I gotta check my notes here. Yes, we are at Embedded Open Source Summit. I know collectively I don't like to get explicitly sold on stuff unless it provides really obvious value to me. So let me give me a moment to kind of justify our presence here. So blues wouldn't exist without open source. And I think most tech companies would say that today that's nothing special. And what we provide, yes, there's a one-time cost for the hardware we provide. There is a commercial cloud service that we provide, but it's usage-based, not subscription-based. And there's an open source option as well. The carrier boards that we provide that I'm gonna show you today, the schematics for those are all open source and the SDKs that we provide are all open source. So this is Python, C, C++, Zephyr, Arduino, Go, I think those are the five. We also have a set of 50-plus purpose-built IoT solutions that are all fully open source, and we'll talk about those a little bit more later. So specifically, what does blues do? This is the note card, and I've got a bunch of them up here spread around on the desk and down below. It is a cellular IoT device. It does come prepaid with 500 megabytes of data and 10 years of global service that's all baked into the device. There's no subscription fees, there's no monthly SIM fees, there's no monthly data fees, but this is only half the story. The other half is our cloud service that we call Note Hub, and the two work together to form what we call a device-to-cloud data pump. In practice, what this means is developers buy a starter kit from us, hook up a sensor to it, hook up their microcontroller to it, gonna read data to that microcontroller, and then deliver that data securely over cellular to Note Hub, and then Note Hub will route that data on to their cloud. So to be clear, Note Hub is a cloud service, but it is not a platform. We're not trying to create a platform that locks you in. We exist to help you connect to your platform. That's a really key thing to understand, be it AWS, Azure, Google Cloud, or an IoT platform that you're already using. We're really trying to help solve that kind of messy middle piece of connectivity. And zooming in on the note card on the hardware a little bit more, the note card is the core of what we provide. It is a low-power system on module. You can come see them up here later. They're very tiny, 30 by 35 millimeters. It has an M.2 edge connector at the bottom for embedding in your board. There are both cellular and Wi-Fi variants. The cellular includes a GPS module as well. And as mentioned, it comes prepaid with 500 megabytes of data, 10 years of service. You can top them up if you need to. It has an onboard embedded SIM, but you can add another SIM to it as well. We provide dual SIM support. And the API, the way you interact with the note card, is all JSON, so gone are the days of AT commands, right? There's no archaic AT syntax to manage your cellular radio. And as mentioned, we have those SDKs for all of these languages and RTOSs. And on the cellular side, we work with NBIOT, LTM, and CAT1, pretty standard. So again, everything is JSON in and JSON out with the note card. So for an example, if you wanted to get your note card's GPS location, what do you do? You use the card.location API. This is what the request looks like. It's just a JSON formatted request. And the response is a JSON formatted response with some additional metadata that includes your location. And most of the rest of the API is set up very similar to this, very intuitive. So that's what the note card brings to the table, but just as importantly, you should know what you don't need when you choose note card, when you choose blues. You don't need your own SIM or mobile plan as mentioned, the note card does come with an embedded SIM with global support. Again, you're not using AT commands, you're using JSON calls to manage your cellular radio. There's no custom security implementation. The beauty of the note card is it comes with an integrated ST safe secure element with a hardware random number generator. There's a factor installed certificate that's provisioned at chip manufacturer as well. For firmware updates, the note card and note have provide over the air, firmware updates to either the host note card or ESP 32 or STM 32 hosts. And well, of course, there's always some power management you're gonna do, but with the note card, all the components are low power by default as are the firmware defaults. And in terms of certifications, the note card is FCC and PTCRB and device certified or end product certified. So in most cases, you don't even have to acquire separate certification, which is really handy. So to make it easier to use your note card when you're prototyping or even when you're ready to embed in a more permanent solution, we provide these carrier boards that are called note carriers. So these are development boards that let you snap in a note card and pop it into really any solution that you can dream up. For example, we have the note carrier F that provides a feather compatible socket so you can pop your feather compatible MCU right in there. The A includes onboard antennas and headers that let you hook it up to virtually any microcontroller you want. The B is a small form factor note carrier, so very tiny. These images are not to scale. And we have a Pi hat, so a Raspberry Pi hat, any Raspberry Pi single board computer can work with this as well. And a relatively new board from SparkFun is their MicroMod cellular function board that fits in with their MicroMod ecosystem. And again, the schematics for all these are open source except for the SparkFun one. I don't know if that one is or not. So again, in terms of completing this device to cloud story, we get to Note Hub. Again, Note Hub is the blue's cloud service that is a secure proxy. Receives data as a secure proxy from the note card and then we'll route that data to your cloud app of choice. Within Note Hub you can manage fleets of devices, again perform those firmware updates. And security, I'm gonna double triple down on the security thing because data is actually transferred from the note card to Note Hub off the public internet through private VPN tunnels. Can optionally be encrypted if you want as well. So there's no certificate management, no key rotation required. The note card knows exactly where to go as soon as it's powered on. You just need to tell it to which of your projects in Note Hub it needs to go to. And again, there is a self-hosted OSS Note Hub version that you can use. It is more limited in its functionality. But with the commercial option, you're only paying for event egress. You can send us as much data as you want. You can trim it down and just send out what you need and you only are charged for that.  So we're really trying to enable people to light users and prototypers to use us for free. Finally, to help kind of visualize where the note card in Note Hub sit and you give an IoT solution, I have this diagram to walk through quickly.  Your programming language. We're not dictating any of this for you. You're gonna compose packets of data, JSON data that we call notes. These notes or these events are gonna be queued, they're gonna be stored on the note card. There's about a mega and a half of flash on the note card to use.  And they're securely synced with Note Hub. But note, of course, as I mentioned before, we don't want you to store your data in Note Hub. We're not trying to trap you into Note Hub. We want you to route that data out to your cloud app of choice. Again, that could be a big cloud, could be an IoT platform like a data cake, UbiDots or LoSan, whatever you're using. And it's important to know that the communication with the note card is bi-directional. So you can start on your cloud app. You can send a JSON-based request to Note Hub using the APIs we provide. Note Hub will securely deliver that JSON payload to a note card, to a fleet of note cards. The note card will then deliver it back to the host. So you can see how you can provide, you can handle remote control scenarios, you can update fleet variables all remotely and all over cellular. So let's look at how we get started with wireless IoT with Blues in roughly one or maybe two minutes, just in slides, believe it or not, it's pretty simple. First thing we're gonna do is we're gonna seat the green note card on this black note carrier, then we're gonna plug in that micro USB cable into our computer. That's actually the beginning and end of the hardware setup. Then using a terminal emulator or the terminal provided that we provide at blues.dev, we use the web serial APIs. Actually use your browser to program it if you want. We're gonna send two JSON-based requests. The first is the hub.set request. All it does is tell my note card to which note hub project it should connect to. Again, by default, the note card knows it needs to connect to note hub when it's powered on. We just have to let it know which project it should be relaying data to. And that project, or as it's specified here, the product UID, it's a unique identifier, is what you're gonna paste in there and send that to the note card. The second command is note.add. Remember how notes are packets of arbitrary JSON data, whatever you need. Could be something as small as a bit, could be as big as a base 64 encoded image. The arbitrary data we're sending in this case is just temperature and humidity data. The sync true parameter in there is optional. This one's nice though, because it tells the note card to immediately send this data to the cloud. It'll save it to flash quickly, but then immediately make that connection instead of sending it later when it maybe is gonna periodically connect. So what happens next? Well, we navigate our browser to notehub.io and we see sure enough, our note card has connected to our project. And then we head to the events page, the events tab, and we see our data show up like magic. But we don't want your data to live on note hub. I've repeated that two or three times. That doesn't provide any value really. So note hub has a really powerful data routing feature that lets you securely route your data to any big cloud or in this example, a dashboard on data cake. So that's really the quick start. And that's honestly an incredible amount of power in about one or two minutes. And if you've ever dealt with cellular, you'll likely have some appreciation for the reduced complexity here while also maintaining that really high degree of developer control. But enough of the boring me talking at you, I do wanna show this off in action with a couple of real projects. These are actually kind of real. There's a ridiculous one here, but I've got a couple real ones. These are kind of interesting because neither of them require a host microcontroller to operate. All the logic is configured with the note cards themselves because there's an STM32 chip on the note card. It is not user accessible, but through the APIs you can access it. And I'm gonna talk about the two projects before I demo them. The first one is a pretty simple demo. That's a power outage monitor. So imagine any scenario where you wanna be actively alerted via SMS if power is cut.  In any case, I'm gonna show how simple this is to set up with just a note card and note carrier here along with Twilio for using the SMS alerts. So to configure this, and don't worry about the details here, I just wanted to kind of describe how simple this is to configure. There's two, there's only two requests that you need to send first. Again, is that hub.set request, which again associates my note card with my note hub project. And the other one is using the card.voltage API. This request tells the note card to monitor changes to the USB power state. That's what that USB true parameter is. And then add an alert, that's that alert true parameter. And then to sync immediately. So it's basically saying, if you detect any change of the USB power state, create an alert and send that to note hub immediately. And this uses very minimal hardware. It's literally just the note card, note carrier B, which is right here with an antenna. And I've got a lipo on here that'll actually keep it powered when my power is cut by yanking this USB cable. And that's the first one. So again, I'll show that off in a second. It's a very thrilling demo, as you can probably imagine. The second demo is gonna showcase the ability to remotely query sensor values from a device just using SMS. Now, I really love this example because it shows off a very simple hardware solution. It's just a note card, note carrier again, and a BME 280 sensor. And how Twilio can work with the note hub API to relay sensor data over SMS. Like the power outage monitor demo, I'm gonna send a hub.set request and I'm gonna use the card.ox API, which lets you enhance the built-in sensor readings on the note card through a BME 280 sensor that's wired up to the ox pins here. And I think I showed the hardware here in a second. And then it's also gonna use the card.temp API. This automatically gathers temperature, pressure, and humidity data at the interval specified, that seconds parameter at the end. I'm also gonna use a Twilio function, which probably can't read the code too well there, but effectively what's happening here is I'm querying the note hub API to pull the most recent event that's been sent from my device. I can quickly parse the sensor data, and I'm oversimplifying this a little bit, but it really is incredibly simple, especially using the Twilio examples that they provide. Again, this solution uses minimal hardware. It is a note card, note carrier A, a lipo battery, and a BME 280 sensor. So this guy right here. And all right, drum roll. So let's close this down for a second and make you a little bigger here. And let's do the power outage one first. And just to show you this project, and we can see that my device is connected here, my device is online. And what I'm gonna do is show you the route. So there's a Twilio SMS route here. And this is how you configure it with your Twilio SID. There's an auth token in here. There's some phone numbers that you provide. You can customize the message. I'm not gonna get into the details. There's also a really powerful feature in NoteUp called JSONata expressions. So you can programmatically alter, you can transform your JSON on the fly. So this is gonna send a JSON payload to NoteUp. NoteUp's gonna transform that JSON and then send that on to Twilio. And so if I bring up my device, should be connecting, here we go. And if I yank the power here, oh, I was mirroring a second ago. Well, if this doesn't work, I'll give it two seconds, three seconds. In any case, here's what I'm gonna do. I'm gonna yank my power here. And you can probably see the green light blinking there, hopefully. And what we'll see here in our events tab is this was sent just now, 1128. It says USB power off, USB is disabled. And you'll have to trust me that on my phone, I got an alert that said power's failed to this device. And if I plug this back in, I'll get another alert that says power was restored. So again, what's nice about this is a super minimal hardware solution that you can just leave running in perpetuity because it's powered obviously over USB, but also it will power that lipo, it'll maintain a charge on that lipo. And let's see the other one, which again, is a little bit less engaging if I can't actually stream my phone here. But I'll try it one more time. And that's with the remotely querying some sensor values here. All right. Well, let's at least show the project off. So this has been running, so it was last seen at 1116, so about 15 minutes ago. And this is set to only periodically connect to our cellular network and relay data every 15 minutes. Yeah, unable to connect. So we can at least see the data that's been sent here. Specifically, here's this temp.qonote. Remember, it's just this JSON here. So you can see our humidity pressure, temperature, voltage values. And again, you'll have to take my word for it, but on my device here, I'm going to send a text message that just says report. And I know you can't see this, but this is now going out to Twilio and then Twilio sent back temperature, humidity, pressure and voltage in a SMS message. So this is a great opportunity to, you're avoiding creating a full like data dashboard for this, right? You're just querying data. You can manage your, or write your Twilio function to do whatever you wanna do, whether it's report on a fleet of devices or alter the debate data on the fly, anything that you wanna do. So let's get on to our last demo here. Oh yeah, first I wanted to mention that one of these demos is available now and the other one's coming soon to our 50 blues accelerators. So again, these are purpose-built IoT solutions that are all open source, some of them even with a comprehensive cloud component built in. All of them showcase the best practices when using the note card and note hub. You can find all of these at our developer site at blues.dev slash accelerators. But now I wanna show another real project. And of course, remember, call back to the perception of IoT problem I mentioned earlier. I'm definitely contributing to it in this demo. If the demo works, we had some power issues earlier and I think it'll work, but it might take a second. There is a pragmatic undertone to this, believe me. So I do wanna set the stage here quickly. I have a couple of kids, they know all too well that I love to kind of terrorize the other kids in our neighborhood on Halloween. So back in October with the help of some colleagues, we put together this kind of jump scare that you can remotely trigger with a button. And I thought I would over engineer it and set it up over cellular. Why is this a good example project? Well, the core idea is very simple, but it demonstrates some really powerful features, right? I wanna push a button that's gonna trigger sending some arbitrary data to the cloud, right? And then from the cloud, we can kind of analyze that data, figure out what we wanna do with it, send it then to a different device to trigger an action, right? But it could be hundreds of devices, it could be thousands of devices. It's really arbitrary at that point. In this case, our action is to make a skeleton jump out of a bag, which we do by setting the state of a notecard aux pin without again using a host configured on this side. There is a host on the button side that I'll show you, but not on the side of the skeleton. And I'll get to that in a second. So it's a good example of bi-directional communication, right? Outbound data from a device, connecting to a cloud, delivering a new event to a new device. It's also about the minimal code we have to write to perform what is again, not a trivial process. So here's the start of the hardware. It is just an STM32-based microcontroller wired up to a button. This is nothing fancy at all. This is just the button side where I initiate the action. It's connected to a notecard and notecarrier here. I'd hold this up, but it's literally what you see right there. It's connected via a quick cable over I square C. I wrote a simple Arduino sketch that initializes the push button pin as an input, right? Initializes the notecard using our note Arduino SDK and associates the notecard with a noteproject, just like you saw previously, but this time using a JSON library in Arduino. And in the loop method, I'm simply reading the state of the button. If it was pressed, create a new event, a new note. In the note, we give it an arbitrary name, surprise.qo. We add this jump equals true bullion. Again, that's totally arbitrary. And that's it. That's this side of the equation right here. This is just the button side. This sends an event to Note Hub over cellular. And again, no AT commands provided or required. So that event is gonna appear in Note Hub here. Great. But again, it's not useful at all to let it sit here. We need to do something with this data. In my case, I immediately route this data to AWS, specifically to a Lambda function. Why Lambda? Cause they're super easy to write and deploy and I can easily hit that Note Hub API to send a new request down to the other device. And here's the said Lambda function in Python. It's not very important. I just wanna show how little code I had to write. There's two key elements in here though to understand kind of what's happening here. The first is we're calling a function of the Note Hub API. In this URL endpoint is a device UID. That's the unique ID for my note card device over here. And we're making this call to set an environment variable. This again is kind of a slightly advanced concept in the blues world. But basically environment variables are key value pairs that let you remotely configure devices or fleets of devices. And in this case, I'm using this specific environment variable called underscore ox GPIO set. This has been really one of the more confusing yet very, very powerful environment variables cause you can configure it so many different ways. Specifically there are four ox pins on the note card you can manage one through four.  So looking at the value of this key value pair in the first parameter here, I'm using it to pulse GPIO pin one low. So that's the first item in this comma separated list. I've ignoring two through four. So that's what those empty commas are there for. I'm gonna pulse that GPIO pin low for 1,000 milliseconds for one second. And it's only valid after this generated UNIX timestamp because we wouldn't want a delayed event to trigger something much later. And it's only valid for 60 seconds after that timestamp, okay? So I know that's kind of complicated but just a pause here. We are on the cloud, we've sent that note to Note Hub. Note Hub has routed it to a Lambda function that Lambda function is sent to request to the Note Hub API saying, hey, on this other device over here pulse this GPIO pin low for a second because we wanna trigger an action on the device which brings us to this other device with a note card attached. This is a prototype carrier board here that lets you control any normal outlet or high voltage device from anywhere, obviously. The carrier comes with two relays that are rated at a max of 220 volts at 10 amps. The carrier design is also open source and available on GitHub. So what does that GPIO pin do? Well, it triggers the relay to make the skeleton jump but what's cool about this is if you look closely, again, there's no host microcontroller here. Everything we're doing takes advantage of those hostless features that we've already talked about. And finally, how do we configure this skeleton note card? Well, just like before, we tell the note card to which Note Hub project it's gonna connect to. We set it to maintain a continuous cellular connection which lets us get the data back and forth as quickly as possible. And we need to configure the note card once to be prepared to set the state of that GPIO pin which remember we're remotely gonna toggle that low. So again, to recap, we've got our button and we press it, we send a note to Note Hub. Note Hub takes that data, delivers it to a Lambda function. The Lambda function tells the or hits the Note Hub API to say, hey, tell this remote device to pulse that GPIO pin low and trigger the scares. And yes, this is a very, very contrived example. But again, I hope it shows how easy it can be to set up communication in this bi-directional manner. Now for the anticlimactic demonstration, I'm going to, I'm not convinced my sketch is running on here so I'm gonna quickly redeploy this. And now it's allegedly running. So let's go back to our skeleton project here. It's called Kendall Halloween. I see two devices that are live, which is good. So I am going to press the button and now it'll remember has to make a cellular connection. It's gonna send that data to the cloud. And then the cloud's gonna hit my other endpoint here. I should see a green flash over there. This might be the biggest anticlimactic demo fail there is. Yeah, I'm not seeing any data getting sent. Let's try it one more time before we officially give up. I always get worried in these demos because stuff always gets kind of like disconnected when I'm transferring it around. And in fact, my skeleton got partially broke on the plane on the way over. But let's, all right, I know we're up on time here. So we're gonna look at our serial output here and give it one more chance. So if you can see that, so that's how it went. It's like Schrodinger's box here, right? It had to know that we were looking at it because I heard the relay engage. Oh boy, I hope I hooked this up, right? There, I see it blinking. Ah! Ha, ha, ha, ha! Yes! All right. Wow, that's amazing. I'll pull that out of nowhere. I know we're kind of, oh, I wanted to show this video really quickly here. This is when I actually deployed this in my neighborhood. There's a couple of funny moments in here. Hopefully it'll come through on the mic. She was very unimpressed and mad at me. This poor kid, I thought it was gonna be traumatizing but they didn't even see it. That was surprising, he says. So she almost tripped and fell like as soon as that video cut. This one you can't really see, but. So we got some good scares. Nobody was too angry or anything at me. Again, a lot of these projects we document, like we do a lot of kind of silly things like that but they are, there is a pragmatic undertone to a lot of what we do. They're all posted on Haxter if you're on Haxter ever and we have a list of them on our developer site as well.  You can get through our entire QuickStart process by just using that and again, that's available on our technical site at blues.dev. So again, just to recap really quickly, check out blues.dev for all of our technical resources. You can get your own starter kit if you want to at shop.blues.io. I want to promote one thing really quickly here. At the end of July, we are working with Edge Impulse and Data Cake on a tiny ML virtual boot camp. So that's July 21st, I think it is. So check that out at bit.ly slash blues-tinyml. And that's it. Thank you all very much for attending. Any questions? I know we can't have ran over a little bit. If there's none, that's fine. Oh, there's one. Yeah, so you can update NoCard firmware if you want to over, I mean, we provide like LTS releases of the NoCard firmware and then developer releases for people are actively developing. That you can update over the air. We have a new feature, kind of hard for me to explain in 10 seconds, but it's called an Outboard DFU, which basically allows you to program any ASP32, STM32, or Nordic. I think it's Nordic is included now, NRF52 maybe. A host microcontroller. The cool thing about that is the NoCard actually controls the firmware update process. So if you accidentally brick your device, it's not actually bricked in the field because the NoCard can revert that change. It's a really powerful feature and I'm not giving it enough credit, but yeah, that's all possible. Anything else? You can find us in the, we're at the top of the stairs over there too, if you wanna check out our booth too. Sorry, yeah. Yeah, so the question is about cellular connectivity if it's global. Yes, so we provide four different models of the NoCard. One of them is a narrowband global one, which is literally like 140 some countries. There are wideband specific NoCards as well that are specific to EMEA and well, there's another one that's specific to North America. The EMEA one actually has a lot of support in South America and some African nations as well. Cool. All right, thanks again everyone.


Hello and welcome to the session. Let's work out the following question. It says prove the following identity where the angles involved are acute angles for which the expression is defined. So let's now move on to the solution. We'll start with LHS and we'll prove that it is equal to RHS. LHS in sine a plus cosecant a whole square plus cos a plus secant a whole square. Now here we'll apply the formula of a plus b whole square.  Now here again we'll apply the formula of a plus b whole square. So this becomes cosecant square a plus secant square a plus 2 cosecant a into secant a. Now again this can be written as sine square a plus cosecant square a. Cosecant square a can be written as 1 plus cot square a plus 2 sine a into cosecant a. Cosecant a can be written as 1 upon sine a plus secant square a which can be written as 1 plus tan square a plus 2. Cos a into secant a secant a is 1 upon cos a.  Hence we have proved that LHS is equal to RHS. So this completes the question and the session. Bye for now. Take care. Have a good day.


In this video I will describe the structure and function of the male and female gonads, discuss the effects of the gonadal hormones, testosterone, estrogen, and progesterone. The hypothalamic pituitary gonadal axis or HPG axis starts with the hypothalamus producing GNRH to stimulate the anterior pituitary to release LH and FSH, the tropic hormones that stimulate the gonads. LH stands for luteinizing hormone and LH will stimulate the production of the steroid sex hormones. FSH stands for follicle stimulating hormone and FSH will stimulate the production of sperm and eggs. The name follicle stimulating hormone comes from the fact that FSH stimulates the growth of ovarian follicles. The ovarian follicles are support cells surrounding the immature egg cell. As the ovarian follicles grow and stimulate the maturation of the egg cell, they produce increasing levels of the estrogen known as estradiol. Estradiol is just a specific form of estrogen. Estradiol is produced in increasing levels during the follicular phase of the ovarian cycle and has effects all through the body, including in the uterus where it will stimulate the growth of the inner lining of the uterus known as the endometrium. But the production of estradiol is regulated by a negative feedback control mechanism where estradiol will bind to receptors in cells of the hypothalamus and anterior pituitary gland in order to inhibit the production of GNRH, LH, and FSH. Around the 14th day of the ovarian and uterine cycle, the control mechanism regulating the production of estradiol switches from a negative feedback to a positive feedback mechanism where estradiol will stimulate the production of increasing levels of GNRH, leading to even higher levels of LH and FSH. As the levels of LH surge, this stimulates the process of ovulation, which is the release of the immature egg cell known as a secondary oocyte from the ovary. The immature egg cell will then travel through the ovaduct, also known as the fallopian tube or uterine tube, following ovulation. The remnant of the ovarian follicle is called the corpus luteum, and the corpus luteum produces the steroid hormone progesterone in response to luteinizing hormone. So this is where the name luteinizing hormone comes from, that LH stimulates the process of ovulation leading to the production of the corpus luteum, and the corpus luteum secretes the hormone progesterone. Progesterone will then bind to receptors within cells all throughout the body. In the uterus, this will help to maintain the endometrium and stimulate the secretion of the uterine glands. In the hypothalamus and anterior pituitary progesterone will have a negative feedback mechanism to decrease the production of GNRH, LH, and FSH. The uterus is regulated by the steroid sex hormones estrogen and progesterone. These hormones fluctuate over roughly a 28-day cycle. We can start looking at the cycle with the beginning marked by the initiation of menstruation, the shedding of the uterine lining, or endometrium. Following menstruation, increasing levels of FSH stimulate the ovarian follicles to produce estrogen, and estrogen stimulates the growth of the endometrium during what's known as the proliferative phase of the uterine cycle. Following ovulation, the corpus luteum of the ovary produces progesterone in response to luteinizing hormone. Then progesterone will stimulate secretions from the uterine glands during the secretory phase of the uterine cycle, and progesterone helps to maintain the endometrium. But as progesterone levels fall towards the 28th day of the uterine cycle, declining levels of progesterone stimulate the process of menstruation. In men, the HPG axis regulates the production of the steroid sex hormone testosterone, and also regulates the process of sperm production. The HPG axis starts with GnRH from the hypothalamus, stimulating the production of FSH and LH from the anterior pituitary. LH binds to receptors on the surface of cells in the testes known as the LIDIG cells, or interstitial cells of LIDIG, and LH stimulates the LIDIG cells to produce testosterone. Testosterone then travels through the blood, all through the body, binding to receptors within cells, stimulating the masculinizing effects like increased muscle mass, increased growth, stimulates the maturation of hair follicles to produce the facial hair, stimulates the enlargement of the larynx to produce the deeper voice in men. But locally within the testes, testosterone will help to stimulate the production of sperm, and within the hypothalamus and anterior pituitary, testosterone will have a negative feedback control mechanism decreasing the levels of GnRH, FSH, and LH. But testosterone's negative feedback effect is primarily regulating the control of luteinizing hormone release, and luteinizing hormone is the primary hormone regulating the production of testosterone. Follicle stimulating hormone binds to receptors on the surface of sirtoli cells. Sirtoli cells are support cells in the testes that help to support the production of sperm. One of the ways that sirtoli cells help to stimulate sperm production is by producing the androgen binding protein that binds to testosterone and helps to increase the local concentration of testosterone within the testes. Sirtoli cells also produce a hormone known as inhibit. Inhibit travels through the blood to reach cells in the anterior pituitary, where it will decrease the production of FSH. So inhibit is a negative feedback mechanism to control the production of FSH, whereas LH is primarily controlled by the negative feedback for testosterone.


Nice, my mic's on. Oh, it's good. OK, so today we're going to continue talking about virtualization. And we're talking about kind of our first actual research paper that I ask you guys to read. Be honest, how many people read the paper? Or at least looked at the paper, clicked on the link. Aspirational goals of, you know, yeah. So this is a good paper. And it introduces sort of a new point in the design space. This came out of the Cambridge Computer Laboratory, which is sort of a pretty good track record of building actual things that people really use. It's a long list of co-authors on this page and a bunch of different people worked on this project. So, OK, assignment three checkpoint, we're still shooting for a five-five-at-five deadline. So that's a week from Friday. Clearly, people are making it to the finish line. There's about 10 assignment 3.3 submissions so far. Most of them are perfect scores.  You guys have a little over a week and a half. OK, for those that read the paper, what kind of paper is this? Well, OK, but go back to our taxonomy. That's what the paper's about. What kind of paper is this?  This paper is from the 1990s, I think. So, yeah. Somebody either knows this exactly or read the slides. Because, yeah, this is both a big idea paper. It introduces a new approach to virtualization. You can also think of this as a wrong way paper. This claims that approaches to try to providing full virtualization are making the wrong design trade-offs when they try to support operating systems, unmodified operating systems. So remember when we talked on Monday, that was our goal, was just to be able to support unmodified operating systems. So the wrong way is this approach of full virtualization of not modifying the operating system. So the Zen trade-off, so there's some quotes from the paper. So what they point out is that x86 was never designed to support full virtualization. And this is what we talked about last time, this problem that there are instructions that are part of the x86 instructions that are not classically virtualizable. So it is not possible to trap and emulate those instructions because they don't trap properly. So for example, certain supervisor instructions, if I execute them with insufficient privilege, fail silently rather than causing a convenient trap. Officially virtualizing the x86, MME was also difficult. We'll come back to this in a few minutes. These problems can be solved, but only at the cost of increased complexity and reduced performance. So what they're pointing out is, look, all this work that VMware and others had to do to fully virtualize the x86 architecture because of these irritations. So what are we going to do instead? Well, OK, so sorry, they also make another argument here as well, which is that, look, not only is it really, really hard to provide this illusion that the guest operating system is running on top of real hardware, it's also in certain cases not the best idea. It limits what we can do. And there's some opportunities here to provide better performance by providing virtualized hardware that's a little bit different than the underlying hardware. So there are situations in which it is desirable for the hosted operating system to see real as well as virtual resources. So for example, timers is one thing that we'll talk about. Why do timers become an interesting concern? Yeah. Well, OK, so let's say I expose the operating system to the underlying hardware timers. So firing along at a pretty predictable rate. What is the operating system not used to in this environment if it's running on virtualized hardware? So I'm running inside a virtual machine monitor. Yeah. OK, so that can happen, but why? No. No, the operating system is running along as usual. But what is the operating system not used to? Yeah. Yeah, the operating system's not used to being descheduled. So if you're running in a virtual machine monitor or hypervisor, that operating system can be stopped. This happens all the time. You go do stuff on EC2.  And there are more virtualized servers on that box than there are CPU cores. Probably, unless you paid big bucks for one of these mega instances or whatever.  And so your operating system from period from time to time gets stopped, and then time goes by, and then it runs again. So what sort of problems can this solve? There's a couple of examples on the slide. Anyone here doing networking stuff? The examples they use are from network stacks. Does anyone know that TCP exists yet? Is that something that you've at least glommed onto over time? OK, good. Yeah, so there are these networking protocols. And one of the things they do is they try to figure out, when do I need to resend a packet? I wait for a while, and then I assume at some point if the other host hasn't gotten that packet, if I haven't gotten an act or some sort of indication from the other side of the connection that the packet was received, I have to retransmit it. But these timing estimates get wonky when the operating system isn't running all the time. Because, for example, I might have run. My operating system ran. It sent some data. Then it was descheduled. Some other operating system ran on the same set of cores. And while I was waiting, the data came back. But it sat in a network queue somewhere in the virtual machine monitor and the hypervisor. And now when I'm scheduled again, that packet arrives. But from my perspective, it looks like it arrived a lot later than it actually did. But part of the delay was me. Me waiting to be rescheduled. Does that make sense? And if I'm not aware of that when I'm doing these sorts of estimates, that can cause things to be wrong. So what I actually want to know is I want some information from the virtual machine that says, hey, this is when this packet actually arrived in real time. And so that requires that the operating system that's running as a guest now be aware. This is not for virtualization anymore. We are going to let the guest operating system know that it is running inside a virtual machine. And there are some features that come along with that. So one feature is the ability to distinguish between virtual time and physical time. Physical time that marches on monotonically. Virtual time that measures that stops when I'm not using the CP. And then there are some other things on the slide as well. Give me an access to low level information about machine addresses and some other things. OK. So the big idea here is this idea called pair of virtualization. And so the goal is, can I trade off small changes to the guest operating system in exchange for improved performance? And improved simplicity too. So there's certain areas, particularly having to do with memory management where the tangled web that I have to weave in order to get full virtualization to work can be substantially simplified by making some small changes to the guest operating system. So not only does my guest operating system change a little bit, but part of the goals here is that it performs better, but also that the hypervisor or my virtual machine monitor becomes a little bit simpler. OK. So you say, we avoid the drawbacks of full virtualization by presenting a virtual machine abstraction that is similar, but not identical to the underlying Harper. An approach which has been double pair of virtualization. This promises improved performance. Although it does require modifications to the guest operating system. Now here's a critical component of this design. It does not require changes to the application binary interface. What does that mean? So I am going to change the operating system. Got that. We'll come back and talk about what those changes are, some of those changes. What does it mean to leave the application binary interface? It's kind of a strange term. Maybe you guys haven't heard this before. You've heard API, this is ABI, what does that mean? Yeah. OK, to what degree do I not have to change them? Yeah, exactly. So not only do I not have to change a single line of source code, I can run the same binary on a para-virtualized operating system. And it runs identical. So this is critical. What would be the problem if that wasn't the case? Let's say that they broke the ABI. Now what becomes hard? Yeah, I mean, I have to recompile everything, all my application binaries from scratch. I may not have source code for everything, proprietary things I got. So yeah, it's a core design goal of Zen to leave the application binary interface unchanged. That's really important. OK, so here are the Zen design principles. And so when you're reading a paper, this is the design principle section, or the design section is a part of a paper where authors will say, here's what we're trying to accomplish. And usually there's discussion surrounding why these things are important. So unmodified application binaries. And the reason this is so important is because if we require changes to the applications as opposed to the operating system, it's going to be very difficult to convince people to transition and use Zen. They're just going to keep using their old stuff or they keep using full virtualization. Again, they're volunteering to make the changes required to do per virtualization to the operating systems that they have to modify. They are not suggesting that everybody go out and rebuild all their software from scratch. That's way too much work. Supporting full multi-application operating systems is important. So I want to support real operating systems. So the changes that I'm going to make to support per virtualization aren't something that I can just do in these little toy operating systems like OS 161. I have to be able to make these changes to Linux, Windows, BSD, real, modern, multi-application operating systems. So they claim that per virtualization is required to get better performance and we'll come back to this. And I love how they refer to this, the uncooperative machine architecture like x86. So x86 is not that easy to virtualize. And so rather than trying to force x86 to cooperate with me, I'm just going to say forget it. I'm going to make some small changes to my operating system. And then finally, again, this comes back to what we've talked about before. Even if the underlying architecture was more cooperative, they're still arguing that I can actually make things work better by modifying guest operating systems slightly in ways that allow them to detect that they're running on virtualized hardware, but also provide some new interaction opportunities for them to make things a little better. OK. So here is the, so Zen introduced this idea of a hypervisor. So the hypervisor, remember what the architecture we had before when we talked on Monday? We had an operating system that controlled the actual physical hardware, the operating system that runs that you installed on the machine.  In Zen, there is no operating system in control of the physical hardware. There is a new piece of software called a hypervisor. The hypervisor is less fully featured than an operating system. The hypervisor is supposed to be as small as possible. As time has gone on, one of the criticisms of approaches like Zen has been that hypervisors have started to get more complicated. And so it starts to feel like I'm building a new operating system that is just sort of designed that I can run other operating systems inside of it. But at this time, this is the dawn of this era. So a hypervisor is this very, very small piece of software. The hypervisor has direct machine access. The operating systems do not. But because I'm going to modify them, I can play some tricks with the kind of access they do have. And now what happens is my guest operating systems run on top of the hypervisor. In order to control, so they might wonder, how do I control the machine? How do I create new virtual machines and stuff like that? So this is clever.  This is something that if you configured VMware servers, you're used to. There's like one virtual machine on there that provides a web interface that allows you to make changes and supports usually an interface to a client-side application. And you can log into that and poke around and do things. So this is the model. So the software, the configuration software, is itself not part of the hypervisor. That makes the hypervisor simpler. It means that if I want to upgrade the control software, I just have to upgrade that one guest instance. So this is kind of a nice architecture. I could have built that into the hypervisor, but they chose not to. Yeah, good question. So remember, the hypervisor has direct access to, the hypervisor is running on bare metal. The EMMs in general are not designed to run on bare metal. The EMMs are designed to run as an application inside another operating system. This is communicating directly with the hardware itself. And the virtual machine abstraction that's provided by the hypervisor in this case is a bit different. Does this make sense? Okay, so this is the architecture. I've got my hardware down here. I have the hypervisor. You can see it's providing a virtual CPU, virtual memory, virtual network, and IO devices. And this is actually one of the places where hypervisors provide some benefits, is that the hypervisor IO interface is actually a lot simpler. And it tends to be more performant for the operating system. Sorry, sorry, not on top of it. In this configuration I've got three guests. I have a, I feel like there's always this bug following me around. Like the last month, maybe the bug is coming out of some part of my body I can't see. But it's happening over and over. Go away. That's kind of scary actually, I don't know. Anyway, so there it is again. So I have three guests running here. I have a Linux guest, a BSD guest, and an XP guest, and these are hard to read. These guests, now this is important, are running Xen or Xeno aware device drivers. So this is sort of a way of expressing the fact that these guests have been modified to work with Xen. So running on top of Xen requires some changes to the guests. And then there's user software that's running on top, unmodified user software. Okay, any questions? Okay, so here are some of the changes that Xen makes. To the underlying machine interface. To make virtualization easier. So for example, protection, guest OS must run at a lower privilege level than Xen. So how is that possible? I thought I only had two privilege levels. User mode and kernel mode. How am I gonna modify the guest operating system to run it at a lower privilege level? I mean clearly Xen, the hypervisor, has to run at the highest privilege level. It needs direct access to the hardware. So it's gonna have to run in kernel mode. How do I get the, how can I achieve this? How can I get the guests to run at a lower privilege level? I could run it as in user mode and then I'd have all some of the problems that I had last time, but there's another option. Remember, anyone remember end of last lecture? Yeah, what's that? X86 privilege ring. Yes, the X86 privilege ring.  Literally, when they started using X86 privilege rings, I think they were the first operating system to do that in 30 years. There were operating systems in the past that used ring one a little bit, but Xen was like, whoa, check this out. And for some reason, they kept that feature around, like that doesn't make any sense to me. But I think that someone at Intel would be like, wait, hold on, why are we supporting these privilege rings again? But they probably said that about a lot of things, actually. That's the hard time, that's the problem you have with winning, right? You end up having to support all these features for a thousand years. Okay, so system calls. So remember what happened on a system call before? I had this pretty gnarly path. I had to go, system call would trap to the host operating system, host operating system would pass it to the guest operator, to the host, sorry, to the VMM, and the VMM would have to handle that back somehow into the guest operating system, so they would be handled. Xen, remember, I'm modifying the guest. So what do I do? When the guest operating system starts to run, it's allowed to register a fast path signal call handler with the hypervisor. And the hypervisor checks that signal call handler to make sure that all of the addresses are valid. I'm not trying to jump into somebody else's operating system. But then what it does is that for system calls, I can actually vector that system call right into the guest operating system. Does that make sense? Full virtualization, because the guest is unchanged, the traps are gonna end up in the host operating system, so it goes host operating system VMM back to the guest. On Xen, I modify the guest so that when the guest starts to run, so remember, the guest is an application now like other applications, so when it's scheduled and starts to run on the hypervisor, it communicates with the hypervisor to register this set of addresses that it says when there's a system I'll call jump to this address in my operating system. And then those calls can be handled right back to the guest. So this is one example of an optimization that's possible on Xen, that wasn't possible before. Time, each guest to us has a timer interface and it can actually pull both real time and virtual time. Real time being the actual time that marches along monotonically, virtual time being the time that's measured since I started running. Yeah. Well remember, there's no host OS here, there's a hypervisor, right? So the hypervisor doesn't allow the guest operating system to handle all exceptions, only some of them. So for example, software exceptions that are caused by system calls are an example where the guest is allowed to register this handler. But there are certain handlers that the hypervisor has to handle, right? Certain types of exceptions, it wouldn't be safe to let the guest have and handle everything because then it could essentially take over the machine. But system calls are safe. So essentially, you can think about what happens. The guest starts to run, it communicates with the hypervisor. Does anyone who read the paper know what those are called? So normally they communicate with the operating system, you make a system call, to communicate with the hypervisor, you make a hypercall, yeah, a hypercall. French would say hypercall, right, hypercall. So the guest operating system, which has been modified to work with Xen, makes a hypercall and it says, when there's a system call, here's the address that I want you to jump to. And the hypervisor looks at that and says, okay, that address is inside the memory that I've allocated for you. So that's cool. And then it registers that interrupt handler with the interrupt server's routines. So do they know where to go? Does that make sense? Yeah. Okay, segmentation. Well, okay, sorry, paging. Let's talk about paging. This is really interesting. And unfortunately, you guys can't appreciate how nice this is because we never talked about shadow page tables because, again, that would take like three lectures. So virtualizing the X86 MMU is really, really hard, partly because the MMU is allowed to walk the page tables that have been registered by the operating system to find translations. And there's this gnarly thing that you can do with full verges and clearly it works. I mean, whenever you use virtual box, that's what's happening. But what Xen allows the guest to do is maintain its own page tables. We'll come back and talk about how this stunts. Pretty cool. With modifications to those page tables checked by Xen. This is particularly important during lots of operations that just access the page tables. So you can think about page table data structures. They don't change that often, but they get used all the time. Every time a process runs, those page tables get loaded and then the MMU is using them constantly to figure out how to translate addresses. But the number of times that those page tables actually change is pretty small. Like I call S break or I use M map to set up a new memory or something like that. But it doesn't happen very often. So page tables are sort of like a read mostly data structure. And what Xen allows me to do is give the MMU access to my own page tables, which I can read from and it can read from, but I can't modify without Xen's help. So this is a really, really nice approach. It means it's safe in the common case and also safe in the uncommon case where I'm changing things. All right, we'll come back to this. So we just talked about this. Xen makes this point, which is that there's a couple of things that the hardware could have that would make virtualizing memory easier. One is the software managed TLB or a TLB with address space identifiers so you don't have to flush it on every transition. And they also point out that X86 doesn't have any of these features. Keep in mind, I mean it's easy to, I don't wanna throw too much shade at X86. I mean, this is an old architecture. I don't think that they were thinking about this stuff when they designed it. What's that? I don't think the rings were designed to support virtualization. I don't know what the rings were for. I mean, that's a great question. I would love to know what the protection rings were supposed to be for. Now we know what they're for. But usually you don't add a feature and expect that people would discover what it's for 20 years later. But they did, I mean it's kind of good design. Someone at Intel got a big promotion. It's like, yeah, I didn't know what that was for either. I'm glad VMware figured it out and told me all about it. I don't know, I might not be giving them enough credit. Maybe they knew what it was for, but who knows? Anyway, it didn't get used for a long time. Okay, so here's what Zen does about memory. Guest operating systems are responsible for managing their own page tables. This is good. It's the data structure I want to let the operating system manage. And they try to minimize the emulment of Zen in this process. So the more I have to communicate with Zen, the more I have to make these hypercalls, the slower the operating system is going to get. So this is interesting. When we talked about full virtualization, the operating system slows down because these traps get vectors in the host operating system and have to be handled back to the virtual machine. Or in certain cases, VMware has to rewrite parts of the operating system, which might also slow it down. In Zen, I communicate with the hypervisor by making these hypercalls. And so we're just introducing a new level here. So remember when we talked about applications, the more they communicate with the operating system, the more they slow down. Same thing on Zen. The more the operating system has to communicate with Zen, the more it slows down. It's making hypercalls as expensive. It at least requires a context switch because they have to run the hypervisor in its own address space. Now, one thing they do that's very clever is to prevent having to... So normally every time I made a hypercall, I would have to flush the TLB and load new mappings that Zen was using. But they get away with this kind of clever trick, which is that they load Zen. The entire hypervisor is under 64 megabytes and they load it into the operating system of... They load it into the address space of every operating system. They found this unused region at the very top of the address space. And they put Zen there on every operating system that gets loaded. And so what this means is that when I make hypercalls, I don't have to flush the TLB because I can allow TLB entries for the hypervisor to coexist with the operating system itself. Now, obviously the operating system doesn't have right access to the area where Zen lives. But this does mean I can get in and out of the hypervisor without having to flush memory mappings, which is good. That helps with performance. So the trick here is to figuring out how to allow the... So what Zen does is, this is cool. So when guest operating systems create page tables, here's what they do. And now that you guys are doing this yourself, you have some idea of how this works. They create their page table data structure with their address space, is what you guys have been thinking of. Any memory that's required is part of that address space. They have some access to it at the beginning so they can make any changes they want. When they register the page table with Zen, they relinquish right access to it. So at that point, what Zen does is it marks any pages of memory that the page tables are using as read only to the guest operating system. Now again, I can still let the MMU use those to look up translations. So that's good. The question is how do I change them later? So what they do is they have a new hypercall interface that they've created that allows the operating system to request that Zen make a change to their page tables. So you imagine, okay, there's a few bytes I need to change at this location. I tell Zen, please change this and it does it on my behalf because Zen has right access to this memory. To improve performance, if the guest wants to, it can batch updates together. So rather than doing one update at a time, which could be very expensive, they can say, here's a bunch of updates that I want you to make. I make one call, I pass you a data structure that has all the information about what to do. Zen runs, has right access to those pages, makes those changes, and then returns. Does this make sense? It's kind of, this is pretty clever. And again, it is way simpler than having to maintain shadow page tables. Okay, so let's talk about the CPU interface. So I already talked about memory. These are modifications that Zen is making to the underlying machine hardware interface to better support virtualization. So with memory, it's that I'm playing this game with the protection of the pages that the page table data structures live on that allows them to be used freely for translating addresses and gives guest operating systems in a way to modify them when they need to. Now with the CPU, the insertion of hypervisor below the operating system violates the usual assumption that the OS system most privileged ending on the system is what we talked about on Monday. In order to protect the hypervisor from OS misbehavior, guest operating systems must be modified to run at a lower privilege level. So if the operating system runs at the same privilege level as Zen, it can do everything that Zen could do. It can modify its own page tables, it can break other operating systems, so clearly have to run at a lower privilege level. And here we go, here privilege rings to the rest. So efficient virtualization is possible in X86 because it supports four distinct privilege levels. So zero is the most privileged, it's full kernel mode, three is the least privileged, it's user user mode. OS code typically executes in ring zero, and application code is typically run in ring three. That's how normal operating systems work when they're running on bare, on bare metal. What Zen does, here we go, yeah, to our knowledge rings one and two and not been used by any well-known OS since OS two. Does anyone remember OS two? I didn't think so, okay. So anyway, in 1980s, 90s maybe? I can't remember whose product that was. If I remember correctly, there were some nice ideas in OS two. Clearly it didn't matter because it's gone. So essentially, okay, sorry I lost my, so what they do is they run, they modify the operating system to run in ring one. So there is enough that it can do on its own in ring one and when it needs help from the hypervisor, it does what we've been talking about and it essentially executes a system call or a hypercall that causes it to start running in the hypervisor and start running in ring zero. So again, this is very, very analogous to the way that system calls are made by processes. So when a process needs to do something that it can't do, doesn't have the privileges to do, it makes a system call. The system call starts executing operating system code at a higher privilege level that then takes care of whatever the application wanted to do. So this is the same model they're gonna use here. Just like with processes, I start to worry about the overhead of boundary crossings. So I start to think about what are the two things that happen often enough that they would really slow the operating system down if it had to communicate with the hypervisor every time. And those two things are page faults and system calls. System calls and page faults, okay. So system calls, we've just talked about this. We let the operating system register this fast exception handler that can be used by the processor without entering ring zero. So when I register this, Zen checks it and then as the guest operating system is running, that's the handlers that are used. This handler is validated before installing it in the hardware exception tube, okay. So I think that's the last detail I had. I actually wanna go back and talk about time for a minute. So let me ask a question. So we talked about cases where knowing the real time is important. So knowing the real time that a packet return, for example, is useful and actually really critical when running congestion algorithms like TCP. Where's a case where I need to use the virtual time? Where's a case where it's really important that the OS know the virtual, yeah. Yeah, absolutely. So imagine, so remember, when the operating system gets descheduled, it doesn't know. It's just like any other program. It just gets yanked off the machine and something else starts to run and that's something else starts running all of its own applications. So if I didn't know how long I was stopped for, I would come back to life and be like, wow, that thread has been running for a long time. I never even gave permission to run for that long. I don't know how this happened. So that's a case where I really need to be able to know the virtual time because I shouldn't penalize threads for running when the entire operating system that they're part of was descheduled because clearly they weren't using the CPU. Okay, so, and this is what I'm interested in, right? If you think about full virtualization, I still have to make these modifications to the operating system. It's because it's impossible on x86 to run an unmodified operating system because of these problems with the architecture. So VMware is like, okay, we're gonna do all this fancy binary translation and we'll make these changes at runtime. Zen's approach is, you know, why don't we actually be a little more intentional about the changes that we're making? Instead of making them on the fly by rewriting the binary, doesn't that sound scary? I mean, how many people would like to be assigned to a project in their new job that involved on the fly binary rewriting of an operating system kernel? Okay, I mean, you guys are nuts, right? Like that sounds awesome. Also, you were gonna crash a lot of machines. I'm just gonna point that out right now, right? Talk about debugging, you know? Oh yeah, wow, I made some changes to the binary and it crashed, right? Good luck. GDB's like, any other questions about Zen? This is a cool paper, yeah. Yeah, sorry, I didn't talk about this before. So Zen allows you to configure virtual machines in the same way that we talked about on Monday. So when you set up a new domain, or they call it, you allocated a certain amount of memory, for example, right? And you might allocate it a certain number of cores. And then the hypervisor is doing the resource allocation between them. So on a multi-core machine, I can have multiple domains that run at the same time, right? I can have, let's say I have 100, I don't know what type of machine they ran this on. I'm sure it's in the paper, but maybe this is like a 16-core machine. So there were 16 operating systems running simultaneously. And each one of them could have been allocated like a couple gigabytes of memory. I'm sure the details are in there. That's not specialized, right?  There's nothing special about the machine. The machine is just a commodity server at the time, right? I mean, would you have been able to get this good performance running on a desktop-class machine? I don't know, right, maybe. Part of their goal is, I think, well, I don't know, I won't put words in their mouth, but I think they're aiming more at a server-class market, right? Because this is the kind of thing that people who deploy servers would have loved to be able to do, right? Like, you know, on some level, when you start using virtualization in your servers, what you care about is how many VMs can I pack onto one machine? Because as soon as I run out and I start to perform badly, I've got to buy more hardware. All right, so on Friday, I'll be back and we will talk about, I'm gonna write a new lecture. I haven't done that in years, about container virtualization. So we'll talk about Docker and stuff like that. I'm sure that'll be fun. See you guys then.