 Tell us more about ReNoot now. Thank you very much for joining us. Well, thank you for having me, Mario. So for those of you who are out there who are on a lower bandwidth connection, if you want to follow along, these slides are available on the internet p.zobbs.io. This will actually synchronize with the presentation that we're doing so you can follow along if you can't get the video feed. Just a little bit about me, Mario gave a pretty good introduction. I'm here based in Singapore. And as he mentioned, I tend to do weird hardware. There's a picture there of FOMU. Probably the world's smallest FPGA development board can fit inside of a USB port. There's also the Chibutronics, which is a circuit stickers project we did that actually lets you program the device via audio. And you can actually program and see Arduino style language using your phone. Lately, I've been working with the Betrusted Secure Communication Platform, which is multiple FPGAs working together with the CPU and all the logic written in high level language that gets compiled down to Verilog and runs entirely on this open platform. This talk is going to be about ReNode. I do not work for Antmicro, the people who create ReNode. I just find it really useful software and I hope that by the end of this, maybe you'll find it useful too. Now, Mario did mention that this talk is about weird hardware and what do I mean when I say weird hardware? Weird hardware to me is hardware that there is only one of in the world or maybe just a few, usually because you just made it. Possibly you're in beginning production or it's something special for a particular project you have, but for whatever reason, it's somewhat bespoke and there isn't another person in the world who has your exact hardware. Weird hardware could also be just something you have that you found somewhere that you're trying to understand, possibly reverse engineer. Now just be clear, when I say weird hardware, I'm referring to devices that have an ARM, i3-886 PowerPC, RISC-5, Spark or Extensa core inside. Unfortunately, ReNode only supports those platforms. It doesn't support anything like a CS2-230 or an 8051. Unfortunately, those sorts of devices can't be emulated in real time on ReNode. You'll have to use something else or just build a simulated model of that particular device. ReNode itself is a multi-node emulator. It's extensible with C-Sharp and Python, very similar to how OpenTap is extensible in C-Sharp and Python. It is available and can run fully on Windows, Mac and Linux, and it's MIT licensed so you don't have to worry too much about GPL or anything like that. And here's just a picture of what the ReNode console ends up looking like. Now I'm going to start just by asking a question. When I say emulator, what comes to mind? For a lot of people, it's going to be something like a whole system emulator. This is a picture of a Nintendo emulator running on my PC. It's called FCEUX, and it lets me play games that were written for the Nintendo Entertainment System, which is a console from the 80s. As far as the game is concerned, it's running on a real Nintendo. It thinks it's outputting to a CRT screen. It thinks it's reading a gamepad. When in actuality, it's outputting to a window on my desktop, and it's reading from my keyboard. This emulator means that software that was written a long time ago is not going to be obsolete. It means we can still use it today as if it were the 80s. In fact, you can see it says copyright 1985, Nintendo. So in addition to preserving software, emulators can give us greater insight into the software that we're running. For example, this is the same emulator with the debug window opened up. You can see here we can have a live disassembly of the game as it's running. We can see the memory as it's running. This is the sort of thing that would be difficult or impossible to get working on the real hardware. By having an emulator, we can actually get greater insight into the system than if we had real hardware. Now, asking the question again, what is an emulator? Is this an emulator? I would say yes. I don't mean the BBS that I'm dialing into right there. I mean the window on the outside is an emulator that is emulating this guy. This is a DEC VT-100 glass teletype from 1978. I believe this is from the Computer History Museum. It is an alternative to what was prevalent at the time, which was typewriters and printers. So instead of wasting paper, you can connect a glass terminal, a VT-100, to your mainframe and type commands in real time that way. Now, the previous page, this is in no way emulating this. This comes from an era when they would publish the schematics in the reference manual and this is what it actually looks like on the inside. It's got video control circuitry, it's got something to read the keyboard. This is not the sort of thing that you really need to emulate when you are typing in a terminal on your desktop. You don't need to be emulating the firmware of the original Intel 8080. You just want to get enough commands. You want to be able to understand the commands such as move the cursor around or input the colors if that is supported. So basically, emulation depends on your goals. For a VT-100 terminal, usually the emulation is to be able to get the other side to give you the commands that it intends, which is another way of saying that emulation is actually a lie. We're lying to the game that says we're a real Nintendo. We're lying to the thing we're connecting to, saying that we're a real VT-100, even though I'm sure most people have never actually used one. Myself included, if I'm honest. So with that in mind, emulation is a lie. We want to emulate a computer. We can ask the next question, what is a computer? What does it mean for a device to be a computer? Well, I'm just going to say that in my mind, a computer is a system of devices, one or more processors, one or more buses, one or more blocks of memory. And if we're not building a Turing machine that is an infinite paper tape, it has some input and output. And for this purpose, I am going to refer to this guy, which is a Blue Energy 2. It's a Bluetooth chip. It's fairly simple, low power, but I would argue that it is a microcontroller, a system on a chip. For our purposes, it is a computer. And when you work with a microcontroller, you can usually get a PDF, which usually starts with something like this that gives you the bullet points of the chip, followed by a lot of information about how the chip works. And this is from the reference manual for the Blue Energy. If you open the manual and you go to one of the first few chapters, you'll get this. Now, it's really not so important what the blocks are, but you do get a block diagram that tells you how the chip is arranged on the inside. I'm just going to prefix this by saying, currently Reno does not support the Blue Energy. This is a chip that is unknown to Reno. So we're going to figure out what it would take for Reno to be able to understand this sort of chip. Now, when you're looking at a block diagram like this, there does seem to be a lot there, and there's a lot that we would have to get working in order to get this working with an emulator. Except not really. It turns out we can actually ignore anything that I've crossed out in red here. Things like there is a Bluetooth modulator and a Bluetooth demodulator that go from the Bluetooth encoder to the antenna. We don't really need to emulate that. We don't need to do all of the real-time calculations, the IQ encoders and decoders. We can just cross that out. This also has a bunch of bridges that go from, for example, the HB bus to the AXI bus. We don't need to emulate those for our purpose. In fact, if you're writing code for this chip, you rarely need to know about those to begin with. So we'll just cross them off, ignore them. Great. We have in yellow here a CPU, a Cortex M0, which is great because that is a standard ARM M0 CPU. So that is going to be well supported by most emulators out there, including Renode. So great. We have one CPU. We have things in green that are memory. There's the SRAM 212 kilobyte banks. There's a 1 kilobyte of, for some reason, I guess it's public key memory that's dedicated to that. And there's 256K of flash. Now I'm going to treat all of this as memory. It's just bits and bytes in a memory array that isn't really doing much except storing data. So there's nothing special about these areas of memory, except the flash happens to be read only and the SRAM can go away when it goes into a low power state. It doesn't matter. For our purposes, this is just memory. And then we have the rest of the blocks that are all outlined in purple here. And these are peripherals. These are the spice that gives a chip its specialness. Every chip is going to have a different set of peripherals and a different set of addresses. And these are what separates one particular microcontroller from another. Now the way you access all of these memories and peripherals is by memory. So most modern systems are memory mapped. There are port mapped systems, but most modern devices are memory mapped where things like flash and RAM are just addresses in memory. But also the peripherals are memory as well. You can see on the screen starting at address 400000, we have GPIOs. These are input-output pins. So depending on the configuration, reading and writing to these areas of memory will cause pins to either go high or low. There's also some other peripherals on here. For example, the flash controller, the system controller, UART, which is just another name for a serial port, and so on. There's so many peripherals. Each one of them gets its own address that I ran out of space on the bottom of the screen, which means we can boil that complicated diagram down to basically a CPU on one side, some sort of memory bus in the middle, and then devices on that bus on the right, RAM, flash, UART, SPI, and so on. Now, how does this relate to ReNode? Well, it turns out to be really easy to define at least the skeleton of this in ReNode. For start, we have the flash and the SRAM, and we're using the memory.mapped memory block here, and we're just placing it on that system bus. The first one is at offset 1004000, and we give it a size that we get from the reference manual. And the same thing, SRAM is at offset 2000000. We're just copying these numbers straight out of the datasheet. Notice how we don't specify that flash is read-only. It might be that there is an option in the mapped memory block to specify flash is read-only, but it turns out that in practice, that doesn't matter because very few real programs try to write to flash because that would be an error. It could be that if we want to test that that doesn't work, we can add that as a feature. But for now, I'm not going to bother because we just want to get something working. Then we add the CPU to the SysBus. So remember, with this, we can have multiple CPUs sitting on the bus at the same time. We specify its CPU type, Cortex M0+, which, again, is a very common low-end microcontroller that you find in all sorts of very tiny devices. We specify the performance here, and this is just a number that you can get either out of the datasheet or just invent one. You don't want it to be too high because then you're simulating a device that's much faster than the one you're actually simulating. But 24 is usually good enough. Usually, it's about one megahertz, one MIPS per megahertz, depending on the architecture you're using. And then at the end, we actually attach what's called an NVIC. And this is kind of a quirk of ARM Cortex devices. One of the nice things that ARM has done is that they've said for the M series, they're going to give a standard set of peripherals. And the NVIC is one of those. That's the nested, vectored interrupt controller that is a standard way of handling interrupts. It also has things like a SysTick timer that is a universal way of firing interrupts and it's this combination of NVIC plus SysTick plus some other peripherals that actually makes it really easy to port operating systems from one Cortex M chip to another even across different vendors. So we put these all together in a file called bluenrg1.repl that is the re-node platform file that defines our platform. Now, there are a couple of things that we need to talk about. What about loading firmware? And what about adding those peripherals in purple? Because remember, peripherals are going to be a lot more challenging than memory. Well, rhetorical question, what is firmware? Well, you might say that firmware is a series of instructions that are executed by the CPU in order to accomplish a task. And I think that's an overly complicated definition. For our purposes, firmware is memory. It doesn't really matter what it does. It doesn't even have to be valid. It could be you're emulating an emulator in which case it's not real instructions. It doesn't matter. The firmware is just memory that happens to be loaded somewhere. So in re-node, it's actually really easy to load firmware. If you're developing, you build it, your compiler tool chain usually develops, generates an elf file. You load that elf file into re-node by just saying load elf, and then your firmware file. File names are prefixed by at in re-node. So this is saying sysbus load elf, the file called firmware.elf. And what that will do is it will use the elf loader built into re-node to unpack your elf file into memory. So for example, it may be that flash is at one address and then the data section is another. This will do all of that unpacking for you so your image will be ready to run in memory and you can just jump to the start address. If you don't have an elf file, if you just have a bin file, for example, off of an SPI flash chip or maybe that's what your developer tool generates, you can specify sysbus load binary and then give it a file name and an offset. Remember that flash was located at one zero zero four, zero zero zero zero on our target blue energy one. So that's why I've specified sysbus load binary one zero zero four, zero zero zero zero. And this, you need to ask the question, how does this interact with the random developer vendor tool that you've got? Hopefully it produces elf files. And if not, we'll just use the load binary to load the hex or the binary file. Unfortunately, if your tool generates a custom firmware file format like updaters or something like that, you'll need to unpack them first before fading it into renode. But for the most part, just treat it as bytes that get loaded into memory somewhere. What about new peripherals? When doing any sort of big project like emulating a brand new device, it really is all about the small victories. If you can make something that is, gives a high reward, the most value you can get for the least amount of effort will at least get you started on the project. If your goal is to emulate the entire system, you're going to burn out before you get anywhere close to emulating the whole system. So start small. And it turns out that serial ports are super rewarding because you can get text out and see what's going on and run a lot of software very quickly. They're also usually very simple and they're easy to script once you get a serial port written. So going back to this document, this table from the reference manual, we can see that address 4030000 is a UART. And that is where the UART peripheral lives. And the UART peripheral is full of registers. Now, what is a register? A register is just an area of memory that has some special property when you read or write. And in the UART register section of the reference manual, we have two registers here. There was a page break after this, so I only copied two registers, but you could see address zero is DR. That's the data register. And offset four is the RSR, the receive status register. And these are going to be at 4030000 and 40300004. What do these special addresses mean? Well, even further down, there is a documentation for each individual register. So this is the documentation for DR. We could see that bits zero through seven are the data register. You read from that to read data. You write to that to transmit data. And then there's some other flags as well. Okay, that is useful. So we can think that if we want to create a peripheral, we want to make it so that when they write to this address, we send it out the serial port. And when they read from it, we get the data that the user typed in or the test harness wrote or something like that. But there's an interesting thing there. Address zero is DR, address four is RSR. Those numbers look kind of familiar. This is the reference manual from CC2538, which is a chip from a different vendor that has a radio in it. And we look at their UART. Address zero is this thing called DR. Address four is this thing called UART RSR. And address four, they also have this thing called UART ECR. Hmm, okay. Looking at a Raspberry Pi, the Broadcom chip that is used in the Raspberry Pi has the same thing. Address zero is the data register. Address four is this register they've called RSR ECR. And then they have some other registers below. And a hint as to what's going on is actually up at the top. It says the PL011 USRT is mapped onto the base address. And if you look that up, you can actually see that the PL011 is a prime cell UART from ARM. And they have the technical reference manual for it. Because what happens is it's really hard to design a chip. And what chip designers do is they want to reuse as much intellectual property, as much IP as they can. So companies such as ARM not only will sell you the CPU core, they'll also sell you peripherals that go around it. And so because ARM makes the prime cell UART and most companies don't want to design their own UART, they just buy the IP from ARM, slot it into their system, and now they have a UART any other chip that uses a PL011. And this is such a common core that ReNode actually ships with a PL011 driver. So in order to instantiate a PL011 onto our SysBus, we just say UART.PL011 at SysBus 4030 000. We also specify the NVIC interrupt is 10, and we get that from a different area in the reference manual. So now we want to set up ReNode. First we load the platform definition file that we just defined. Then we load a binary of DLA chat server. Now you'll notice I'm loading a binary here and not an elf file. And that's because these demonstration programs came directly from ST. I didn't actually compile the source because I wasn't sure how to set up their developer environment, but I knew that this code ran on real hardware, so I just decided to load it into the emulator at address 100400000, just like the bootloader would do in the real device. Then you do some ARM-specific things, setting the vector table offset, which is where the interrupts live. Most of the time this will be at address zero, but because on this particular chip, the firmware lives at 1004, we need to reset the vector table offset. It's just a single command. Then we set the stack pointer and program counter. Again, this is the sort of thing that any ARM chip does. The hardware actually does this on its own, except it usually sets SP to the value at address zero and the PC to address four. It's just because Flash is at a weird place on this chip that it is at this weird address. Remember, this is all about getting weird hardware to work. This is really the extent of the weirdness, because at the end we hit start, and there's our whole setup. We're going to call this blueenergy1.resc, that is the re-node script, and we feed this into re-node, and there we go. We get output. We get the firmware that comes from ST running in our virtual system, outputting a message that says it managed to initialize the UART. That's cool. That's huge. Before re-node, you'd have to do something like recompile QMU in order to get this working, and it wouldn't work on Windows, Mac, or Linux. You'd have to have a different version for each platform. This is just some scripting that we do in order to get it working. Number one, always check for block reuse, because companies frequently use blocks across different designs, and that can save you from just having to re-implement it from scratch. It may be that a block is slightly different, in which case you'll have to copy the existing design and modify it slightly. Maybe the addresses are different, but try and use a design if you can. Now, peripherals can be developed surprisingly quickly. I was skeptical until I saw this, but I was at the Hackaday SuperCon in 2019, and we were just bringing up the Betrusted platform. This is an early Betrusted prototype. It is on the left. On the right is a Raspberry Pi with a debug hat that we use for serial I.O. and also SPI flash. What would happen is you do the development on your desktop, upload it to the Raspberry Pi, which would then program the flash chip in the Betrusted and give you feedback over serial as to how this device was running. You can see here, this is Bunny in Singapore running a demo that is a ball bouncing and is also reading some values and putting them on the screen. This is 17th November, 2019. Very early stuff. I was at Hackaday SuperCon and the micro people were there and they said, yeah, we could emulate that, no problem. It should be doable. Risk 5 CPU core, okay. Now, with Betrusted because it's an FPGA, we actually have to do everything ourselves. We use Litex SoC in order to design the FPGA and as part of the build process, we actually generate our own reference manuals. This is an example of what our reference manuals look like. There's a link at the bottom in case you want to go take a look, ci.betrusted.io. These are actually generated every time we rebuild the firmware. I sent this to the Reno guys. I gave them the flash image that Bunny was using here. Instead of sending it to the device in the Raspberry Pi, he just sent it to me over Telegram. So I gave that to the Renoed people who were at Hackaday. I gave them a link to this reference manual and I told them a little bit about the layout of the screen and the frame buffer and all that. She said, yeah, we can do that in a day. It'll take a day, no problem. I said, a day, really? Okay. Then I went to go see a conference or a talk and an hour later, I get a call and he says, let me, I got something to show you. I go over to his desk and he has this running in his machine after an hour. So it turns out that it's really easy to create new peripherals. This isn't even a really a patched version of Reno. This is a stock version of Reno that he's running here. He's got our software loaded. He's got the frame buffer working. He's got the timer working. It's a bit slow compared to real hardware but that's just because the peripherals are completely unoptimized. He managed to get it working in an hour and I've just never seen anything so amazing. You got the ball bouncing working. It's delightful. Okay, this is a cool piece of software and so that is actually what started to get me to use it for the Betrusted project. Remember we had the Nintendo emulator that gives you access visibility into the system. There are some things that you can get with emulation that you can't get with real hardware. One of the things is that in the real hardware we have one serial port because it's a Raspberry Pi. There's only one serial port that's brought out to the device on your test and so to get around that there is this register called UART cell where you can select which one of the logical UARTs inside the system on our chip in Betrusted will get sent to the Raspberry Pi. There's two bits which gives you four options. With ReNode I don't bother to emulate that. I just open up two serial ports. I can put as many serial ports on the screen as you want. Just open up another window. This is something you can't do in real hardware because you're limited to the number of wires but in emulation we can have as many serial ports as you want. One other story about this, getting hardware to users it's a lot easier to send somebody a download link than it is to send them hardware. In fact it's easier to patch ReNode or even an FPGA hardware than it is to patch real hardware. This mess of wires is what we call the engine. It is a cryptographic acceleration engine because modern cryptographic primitives particularly ED25519 requires a lot of 256-bit multipliers and those can be very difficult to do on a 32-bit RISC5 core. We offload it to a DSP that Bunny ended up designing. I emulated this in ReNode as a peripheral so we can run the engine's firmware as if it were running on real hardware and we check this in and somebody checked it out this person named Fabian Weisberg checked it out and added these vectors from Google Project Whiteproof which basically tests the engine a little bit better than we had done. It's additional test vectors that we didn't test before. He checked them in, ran it under ReNode they passed, submitted the pull request and then they got added to the repository. Now the amazing thing is Bunny checked them out himself built them on hardware and discovered a bug. It turns out that his implementation didn't properly propagate the 17th bit. So he was failing on some of the tests that ended up passing in ReNode and because this person managed to add these test vectors we were able to catch them. Now if you look at the date here 7th September 2021 it is now 9th April 2022 we just got users real hardware three weeks ago. This is months ago that this person managed to download the software and find this bug and contribute to the project. So again emulation brings more eyes to the project because it's easier to download software. ReNode also supports robot framework and this is where the CI part of the talk title the original talk title comes from. If you're familiar with robot this should look very familiar. If you're familiar with COBOL this might look familiar as well but robot is a common test framework that lets you run various test cases in CI. This is actually from ReNodes built in test cases the way robot works is you have sections this is the settings section most of this is going to be the same across all of the tests you see it just says how to set up the particular test case then you have the variables section there's all the variables that are used with all the tests in particular here you can see we're actually defining a REPL file a ReNode platform file here where we're using the recursion feature where we're actually just saying this device under test it's just a Nordic NRF 52840 core which is a very standard Bluetooth core that comes built in with ReNode and what we're going to do is we're going to add this accelerometer this LIS2DS12 which is the device we're interested in testing we're going to add it on the TWI1 that is the two-wire interface otherwise known as I2C bus at address 1C and we're going to hook this accelerometer sensor up to GPIO0 port 28 so this is something that might vary from board to board which GPIO port it's connected to which address it is which I2C device it's connected to but you can see it's very easy to change that just in this one text file down below we have the keyword section which is essentially functions that can be called my test cases in this case we have a keyword that creates a new machine for testing so you can create a machine very easily just say mock create you load the platform definition from what we divided up above as a string and then you load an L file and finally we test to make sure that it can read the acceleration we're actually calling C sharp functions on the accelerometer so acceleration X is a C function that is defined on the accelerometer chip and then we start the emulation and make sure that the UART prints out the correct values you can actually see we're also testing the rounding of this particular C library just to make sure that it hasn't changed possibly due to a new version of lib C this also means you can throw this into GitHub Actions and test your firmware every time you push code just as you would test any other desktop application Reno does also use for reverse engineering there's other things you could do for example there's this standard called SVD which is an XML file that most chip vendors have that describes the chip it's essentially an XML version of the reference manual except everybody follows the same standard so it starts out with the vendor section with things like the name of the chip down below we have things like the peripherals so you can see here this is the random number generator of the blue energy you have the name here description which isn't always very useful but more importantly we have the base address for this peripheral so we can use this to assign information to the system that's being emulated we also have the individual registers including their name the offset so in this in case of the the UR this would be DR address offset 0 we have the different fields here so this is actually really interesting because within a single register remember there was that individual registers section we saw in the reference manual we also get individual bits here as well so crucially we also have the reset value so the SVD will tell you when the chip starts up what is the default value and this becomes particularly interesting for chips that have version information and software that looks for that version information to determine which version the chip is running on so that will have a reset value that depends on the exact version of the chip you have that we can actually pass this into Reno we can apply the SVD file to our sys bus which means that when you run your code if there's a register that's unimplemented Reno can now log what block which register and which peripheral it's reading and writing from for example the first one on the screen it's trying to read from the data register on GPIO if you didn't have that you would just say 400 and you'd have to look in the register manual manually here you can just let Reno take care of it for you and relabel everything and you can see the last read on the screen there from clock gen underscore BLE it's filled in the default value for us which probably means something like clock was reset due to system start I'm guessing you can also load an L file and have it log function names as it executes various functions so this is an example of logging function calls on the embedded controller for betrusted because betrusted was loaded from a bin file from an SPI flash I didn't have functions on there so I just loaded symbols from an L file and started logging and you can see it entering the function it tries to join the Wi-Fi then it tries to configure IPv4 and then it requests the DHCP address also cool is that this is actually Rust code that it's running so it doesn't matter that it's Rust it's going to still print out the function names that it gets from the L file if that wasn't enough you can also debug the emulated system with GDB just say machine start GDB server give it a port number and attach GDB to it specify the port and you can start disassembling code right away can disassemble from the program counter on you can print the registers you can examine memory it works pretty well notice I started GDB here without symbols because for this particular device I didn't have symbols what you can do is you can just create an L file this is probably a whole other talking itself but you can actually feed binary files into this lovely software called Ghidra that has a really nice decompiler you can label you can rename functions to give function names that make sense to you then you can generate an L file and load those into both Reno and GDB to make debugging on the device that you're testing much more understandable we've also got multi system emulation this is what we would do with Betrusted where we actually have two different chips that are running in lockstep one of them is 10 times as fast as the other there's the EC on one side that's connected to wifi there's the SOC that's on the other that's connected to things like the keyboard and the display and we they communicate over a COM bus and so we can actually run all of these in lockstep together and get a whole system emulated running short on time but there's some other fun things that Reno can do you can load peripherals at runtime you don't actually need a C compiler or a C sharp compiler it'll load C sharp files natively so this is just me including a C sharp file and Reno will take that compile it and give me access to that peripheral at runtime and these peripherals are cross platform so you don't need to recompile Reno for Windows Mac or Linux you just include your C sharp file with your distribution include it this way and you should be able to add it as a peripheral on your device peripherals are also relatively easy to create remember I said he created a display in an hour that's not unreasonable at all when you create a peripheral at runtime you would do something like this you have an enum with all the registers that comes straight from the reference manual then you have this function called define registers this is an example of something that has two bits we define each bit differently because doing bit shifts is really hard because it's prone for error so we say bit number zero is a callback closure that just returns true because in this case this is a random number generator and because we're emulating this we can lie and say that we always have random numbers the second bit here is whether or not the random number generator has available data again we're just going to lie here and return the bit true the flag feature makes it very easy because again you don't have to worry the data field on this particular random number generator is not a flag it is a value in fact I make it a 32 bit value and I pass to the function value provider callback which is again a C sharp closure and I just use the system random number generator because it's C sharp is the full language it comes with things like a random number generator so this is the entirety of the random number generator implementation plus a little bit more glue to add this as a C sharp class you can load this into your running emulated system at runtime it will compile it and then you can use it in your target system this is C sharp to answer the question you can also because Microsoft created C sharp they also created visual studio code you don't need to get a full visual studio install you can actually use visual studio code and get auto complete with the C sharp because the reno binary itself contains a lot of debug symbol information you can just point visual studio at reno and it will give you all of the library information that reno uses for example here I'm doing auto complete on what a double word register value looks like and you can see that there's a function called change callback that takes two arguments this makes it really nice for debugging new peripherals because if the IDE says that your code is good it's going to run the first time it may not make sense logically but they'll at least be free of syntax errors and you get auto complete which is huge you could also do networking with tap now tap is a device for doing adding virtual network devices that you can use to bridge to your ethernet device started in linux in 2000 it's been ported to windows and there's a version of on the Mac you can create an emulated switch using this command you can create a tap on your system using this command and what this will do is this will create a new network interface or ethernet device on your system which you can then bridge or run that and then you can connect the host system that is running re-node to an ethernet device that your device under test may have if you don't want to connect it to your host system using tap you can also connect it to a small network that is entirely emulated an earlier version of this just had me emulating a linux system already on arm that was providing DHCP information but with this you can actually get your emulated system working on the internet to the point where you can actually send and receive pings you can do everything you would in a real system running on your desktop so the bottom line re-node is free software it's MIT licensed give it a try I think it's underappreciated I think more people need to know about it because it's really cool stuff it's really good really easy to make new peripherals and thank you for joining I'll put some links up here there's re-node.io which is the software that we've been running betrusted.io which is the embedded which is the secure communications device there's the link again to this talk if you'd like to see it after the fact the source to this talk is also up on that git page if you'd like to download that that's all any questions okay thank you very much yeah that was just so deep like I already get a lot of feedback from people and we have time for one question so this from Nilek he says it's partly a philosophical question can an emulator be better than the original hardware or is the original device per definition the best solution how about fixing bugs of the original hardware oh that is a great question again it really comes back to what your goals are if your goal is to for example with the Nintendo nothing can emulate the feeling that you get when you're 8 years old playing with a game on Christmas morning it's there's nothing that can come close to that but it is a lot harder to attach debug probes to a real Nintendo system so it depends on what you're looking to do for a lot of what we want to do in terms of development an emulator can be better than the real system a practical example is that a Cortex M0 usually comes with two flash patch points which let you insert breakpoints on read only flash as soon as you exceed two gdb will throw lots of fits saying you can't continue because it can't add breakpoints and this happens a lot when you have code that's been heavily inline so a single line of code might equal 20 different lines in the flash file if it's a particularly hot function things like locking disabling interrupts that's generally a single function that gets lined everywhere so if you try to insert a breakpoint on that and your system will refuse to run with an emulator that's no problem because flash is emulated so you can insert as many breakpoints as you want so if you're developing emulators possibly are better especially when the hardware is still changing but nothing beats the real thing so we do have real hardware that is connected to a Jenkins machine with be trusted that is running all these tests on real hardware but because we have access to the cloud we can now run 5, 10, 15 infinite number of emulated systems in the cloud which scales a lot better than just the one or two devices we have connected to hardware here in Singapore. Thank you Sean, it's been an absolute pleasure having you here again at the Fossager Summit and I hope we can catch up sometime soon personally in person. Definitely looking forward to that thank you for having me. Good evening, thank you very much, bye bye.