 I don't want to spend too much time introducing people, so feel free to just say who you are and what you're doing. Okay, fine. So good morning everybody. I'm Fabien Chouteau, software engineer at AIDA Core. So AIDA Core is the company that maintains and developed the open source compiler for AIDA, which is called GNAT, it's based on GCC. We develop a lot of other tools for software development as well. And today I want to talk about how to use AIDA in embedded programming, in particular with small microcontrollers like you can find on this kind of small boards. So before I start my presentation, there will be a live demo. I will try. So please everybody, see if you can pray the God of live demo. Thank you very much. So to begin with, I will give you my view on the AIDA philosophy or the AIDA way of doing things, which is in my opinion that programming is all about communication. You have an application, an idea, a program in your head and you want to communicate it. You want to communicate with your tools like the compiler because that's what is going to make your executable at the end. You want to communicate with other tools like static analysis, IDEs, stuff like that. You want to communicate with users of your API. If you're writing a library, you want people to know how to use the library with your colleagues, of course, because they will read your code, debug it, etc. And you even want to talk with, communicate with that idiot that brought this really stupid piece of code. Oh wait, it was me two months ago. So that's something, and Jean-Pierre talked about it, but one of the main design goals of AIDA is really based on the fact that we read code and we debug it more than we program, actually. And it's probably not something that we want to hear a lot because we would like to see ourselves as programmers, developers who create stuff, but actually the reality is that we spend a lot of time reading code. So to put that into the context of embedded programming, what is different for embedded programming? It's a bit difficult to explain. There's a lot of things that are similar. Usually you will have the obvious, which is you have a different tool chain, you have a different processor, etc. But really what it comes down to, in my opinion, is that every bug costs you a lot more time to investigate because you have different tools. You don't have, for instance, as much breakpoints as you want in your debugger. More time to try a fix because you have to reprogram your embedded target. You maybe have some hardware to reconfigure. If you make a mistake, if there's a bug, you can potentially destroy your hardware. And that's an example that I will take later. Or even I don't mention it here, but you can also injure people or kill people in the example of aircraft or trains, stuff like that. And updates are usually also very difficult to propagate. If you have a product on a board like this one, it's very difficult to propagate an update once you have a bug in it. And the other point that I will cover is the need of control. So I guess my presentation is a good follow-up to what Jean-Pierre said because I will also show the high-level representation in AIDA and how you can control the hardware representation. So that's one point. And the real-time constraints. So I will also quickly talk about tasking and real-time in AIDA. So let's get started. To talk about embedded programming in AIDA, I will take the example of a servo motor. So it's a little motor like this. You can set an angle. It's controlled via an electric signal with some pulses. If you put a 1 millisecond pulses, it will go 90 degrees to the left. 1.5 millisecond is the natural position and 2.5 is 90 degrees to the right. Now, what happens if you don't respect these constraints? Well, here you are in the real world and there are real consequences to your bugs which means you will destroy your servo motor. And of course, that's not something you want. It costs money. You will lose a lot of time. So you want to avoid that. So let's see how AIDA will help you to communicate the constraint of your system to avoid this kind of situation. So if we take an example from any other language, your interfaces to control the servo motor will probably look something like this. So a procedure in AIDA is a function that doesn't return anything. You say, okay, let the user set the desired angle of the servo motor. Now if you are a really, really good programmer, you will do something like this. You add commands, right? So as you can see, you have some very, very important information over here because otherwise you will have a failure and you will break your hardware. So that's what you would do in most programming languages and as you can see, this is not very practical. So first, the compiler and the other tools don't know about this constraint, right? Because it's only in the comments. And then if somebody decides to change the implementation and say, okay, I don't want to go from 90 degrees to minus 90. I want to do a percentage. I want to go from 0 to 100. Well, maybe the developer will forget to update the comment and the users of the API will not be notified by this. So in AIDA, you really express what you want and you will define your own type. And this is again, in the perspective of what you were just saying, there's a lot of languages that claim strong typing but really strong typing is not that useful if you cannot create your own type and AIDA gives you all the power to create your own types. So now, in practice, what does it mean? Once you've said that, well, as we said, there are the compilers, the tools, the users of the API. Everybody knows about this. In practice, what does it mean? Well, let's have a look with the compiler. So in a use case, really simple like this, the compiler will be able to tell you, okay, this is really dumb. You're just giving a wrong value. So it will give you a warning. So that's the first mistake avoided. Great. Then if we go to a more difficult example, here we multiply the angle by two. So it's more difficult to analyze. In that case, you will need to go to a static analyzer like code peer. And again, the tool, because it has more information, will be able to give you more precise and more useful analysis. So again, here the static analysis tool will tell you there is a high probability of an error here. The next tool is formal proof with Spark. So there will be a presentation this afternoon about Spark. What this gives you is a mathematical proof that there is no error in your program. So in that case, there is an error. So the tools will tell you. So at this point, you should catch most of your error. But sometimes you don't have access to these tools. So maybe some bugs will go through. So the next step is to actually run your application and you will do that during the development. Usually, you run under a debugger. And as Jean-Pierre already explained, when there is such an error detected in an AIDA program, there will be an exception that is right. And once you are running inside the debugger, the exception will be code. And so you stop before the error and you protect your hardware. And then you can fix. So again, you catch the bug very early. So the next step is to actually catch the error inside the code itself. So the error is just an exception, a standard AIDA exception, so you can catch it like this. And you again stop before doing something bad. So you protect your hardware, and you save money, you save time, et cetera, et cetera. The last chance is this procedure. When an exception is not handled in AIDA, this procedure will be called. It's a very good name, the last chance handler. And that's your last chance to do something about the situation. Usually, when you go to this, you're in really, really bad situation, so you probably want to shut down everything, reset the board, or maybe wait for user input, something like that. And so that's your last result. After that, there is no more protection. So those checks that you, the constraint that you put on the type and the checks that come with them, they have some performance impact, of course, because there will be more code added to your binary. There will be some comparison and stuff like that. It's very useful when you are in development, in debugging, because you want to catch the bug as early as possible and you want to catch all of them. But once you are in production, maybe you want all the performances, and you can remove everything. And in that case, it's up to you if you really want to dare running your application without any checks. So another example of how you can express what you mean in EDA is contracts. So there is also a presentation about contracts later on. So just a quick example. I like this example because it's very simple and this actually saved me a couple of times. So we have a driver for the servo, right? And usually there are some hardware to initialize before you can actually control the servo motor. So this is exactly what we describe here. We say to the user of our API that... So it's a precondition of the procedure set and goals, something that must be true before you call the procedure. And we say that the servo must be initialized. When the condition is not true, well, it's the same story you have. So the tools will be able to tell you this information. And then the debugger will be able to catch the exception. You can catch it in the code as well and the last-gen sender, et cetera. Another quick example that I really like about EDA because many people can relate to this if you use CRC++, for instance. You will often see asserts in CRC++ code for functions that take pointers as parameter. To check that a pointer is actually not null. In EDA, that's one of the examples of how you can express that you take a pointer, okay, but it should not be null. And that's part of actually your interface and your API. So now let's talk a little bit about hardware mapping. So that's one of the things we need when we do embedded development. We need usually a good control of the hardware representation of our type. And so as Jean-Pierre said, in EDA, you always have the high-level view of your type and then you can control its representation. So for instance here, I say that my type servo-hungle should be represented in a byte and I want 16 elements. If I use a smaller value here or too small value, the compiler will tell me, okay, it's not possible. Same thing. If somebody tries to increase the range and it doesn't fit in the size anymore, there will be a compiler error. So this is useful when addressing hardware. It's also very useful in network communication to form packets. The next really common practice in embedded programming, usually with a small microcontroller, sorry, like you have in this kind of board. It's the memory mapped register. So I don't know if you are familiar with this notion. I will try to describe it really quickly. So this is a representation of your address space. So that's all the memory, all the addresses that your CPU can read and write. Of course on small embedded processors like that, you don't have the full memory or you never have the full memory used. So you will have some areas where you have the flash. So it's the read-only memory that holds your program. You have some areas where you have the RAM. Other areas will be allocated to peripherals. What this means is that when the CPU reads or writes data from those addresses, it will be exactly like talking to the peripherals. So when you read data from this address, you receive data from the peripherals. When you write, you send data to the peripherals. And so this is the kind of description that you will find in your hardware documentation. So this is a virtual example. It's not actually representing something real, but it's really exactly like you would find in the documentation. So here we have what is called a memory mapped register. So it's eight bits. And we can see that there are some fields inside those eight bits that are defined. So the first four bits are reserved. They are not used. The fourth and fifth are used for the sense field. And the six and seven are not used as well. And the documentation will tell us what are the possible values and the meaning of those values for the sense field. In C, usually you will have drivers written with something like that. So you will make more or less macros and bit shifts and masks like you see here. So as you can see and you can probably guess that this is not really safe to do. For instance, if you want to put the value one, which is a wrong value for this field, you will don't know about it. The compiler will not know. Also this is not very practical to write. Like you need a special instruction to clear the field first and then set its value, et cetera, et cetera. So now in Ada, again what we will do is have the high-level view and the low-level representation of the type. So first we declare an animation type. So that's the pin sense field that we saw before. We declare its high-level view, which is there's three values, disabled, high and low. We specify the hardware representation. So the size will be two. And also the hardware representation of the different values. Next, we go to the register itself. Again, same thing. We have the high-level view and the low-level view. So we have the first reserved field of the register. We then define our sense field and the second result. And as Jean-Pierre showed as well in his presentation, here you define the hardware representation. And so you define the exact position of each field. And as you can see, this is really exactly what is in the documentation. To use this type, well, you declare an IO register. And with this construct here, you say with address, you tell the compiler that this variable should not be allocated on the stack or should not be allocated on the heap. You specify yourself, I know that there is an IO register at this address and that's how you specify it in either. And then it's just a sign, a value of an enumeration. And so you have all the checks that we mentioned before. So this kind of representation can be a little bit difficult to write, a little bit tedious. So fortunately, the ARM, you know, the creator of the Cortex-M microcontroller, they developed a format called SVD, which is hardware description format. So as you can see here, it's a description of the different registers, gives you the address, gives you the different values, etc., etc. And we developed, so my colleague Jérôme developed a tool that will take this format and produce the ADA representation that we saw here. This will be generated from the description. So this is really a great way, a great tool to start programming ARM microcontroller in ADA because most of the hardware representation will be automatically generated. Another example of ADA features that are really useful in the embedded area. It's the tasking embedded inside the language. So Jean-Pierre, you already talked a little bit about this. I have a blog post right here. If you want more info on this, I will just describe quickly a few stuff, but there's more info over there. So in ADA, tasks or threads are a really native feature of the language. And for the embedded markets or the embedded projects, there is actually a specific tasking profile which is a restriction of the big tasking features of ADA. And it's called Ravenscar. And this is really meant for real-time operating system and to give you real-time properties with ADA. Some of the features that are available, you have a clock to give you the system tick. You can do delays or suspend the task for a given amount of time. You have protected objects which are really something quite unique, I think. It's difficult to explain quickly, but it's a mix of mutexes and semaphore, and you can also do interrupt handling with this. You will see in the blog post I have an example of how you can really create an elegant interrupt handler and a driver, for instance, for a serial port using the protected object. So, it gives you multiple things, but mutual exclusion. You can do synchronization between tasks. So, for instance, if you have a task that produces data, a task that consumes data, you can have the task, the consumer waits in a suspended state for the producer to actually give it data. All of this is really part of the language. It's really safe to use because there's a lot of control over what you can do or what you cannot. The last point is, as I said, the interrupt handling. There's also, as part of the Ada language, the constrict to handle interrupts, which is very useful for embedded and microcontrollers. So, this is just a quick example of a task in Ada. So, you can see, task is a keyword of the language. So, here, we declare the body of the task. And it's just basically a loop. We do a delay. So, we suspend the task every time, and we add 100 milliseconds. So, this will be at 10 hertz. It's a typical code that you would use to make a periodic task in Ada. So, now, I will talk about the Ada drivers library project. This project, we started in 2015, I think. And so, I'll show you a few points. It's a firmware library. So, it's a library that will give you tools to support and to implement programs on microcontrollers like this one. It's hardware and vendor independent. So, this is both a bad thing because it means we have to write stuff ourselves. It's not provided by the vendors. But on the other hand, we can work on really focus on really having the most clean interfaces and reusable code. It's 100% written in Ada and hosted on GitHub, you can have a look. So, why we started this library? Well, the first thing is that Ada has good properties to bind with other languages, like C, for instance. But this usually does not apply very well to drivers provided by the vendors, by the hardware vendors because they use, as I said, as I showed before, they use a lot of macros and bitchips and stuff like that. It doesn't really apply very well to do a binding in Ada. And the next point was also a way for us to actually use our tools and to show to have demos for people to show what you can do with Ada. And the last point, of course, it's really fun to do. So, that's a good way. So, quickly, some architecture aspect of the library. In the library, we have what we call components. So, what we defined by components is a separate piece of hardware that is connected to your microcontroller using a standard protocol, like I2C, SPI, Huart, etc. This is a special, so the drivers are for a piece that is external and, most importantly, it's working using standard protocols. So, the idea is that here you can change microcontroller, you can go from a Cortex to an AVR or to whatever brand you want. The driver will still be the same. So, for the components we want to have really reusable code and portable code. This is quickly the list of what we support right now. So, we have some audio DAC, some camera, what we call motion is a gyroscope, accelerometers, etc. Touch panels and stuff like that. The next layer that I want to talk about is the middleware. We don't have a lot here, but I think we have some interesting things. Bitmap drawings, so to use on the LCD screens. If you know the Adafruit GFX library, it's pretty similar. Very simple drawing features. We also have some file system support, so we support the FAT format and also some kind of virtual file system over the ARM semi-hosting feature. And a small log utility to filter the logs, debug, etc. So, this is more or less what it looks like. So, you've probably seen this kind of diagrams tons of time. What's important to see here is that this part, the SVD binding is generated by a tool. This part over here the hardware abstraction layer, the components, the middleware are all portable. So, really, if you want to benefit from the Adafruit GFX library and if you want to start programming your microcontroller in Adafruit, you will have to focus only on these low-level driver parts. If you are using a microcontroller that we don't already support, of course. Speaking of supports, this is the two platforms that we support. So, with ARM we have the Cortex-M architecture, which is ARM version for microcontrollers. And since last year, we also started to support the first RISC-5 microcontroller. So, I have here the list of boards that we support. I will just spend a few seconds on them. This is a really good option to start. It's one of the boards that we support the most. So, in STM32F405 this one is really cheap, like 15 euros or something like that, but you have everything you need. There's a debugger integrated, really powerful microcontrollers and as I said, that's one of the boards that we support the best. You then have this one, which is more or less the same, but with an LCD screen and a touchscreen as well, which is very good. And then you have all the Discovery family, which adds new features. This one has an SD card and an audio output. This one is in the Cortex-M7 family, so it's the new generation of Cortex-M microcontrollers, more powerful. There's an Ethernet port on here as well, and again another ARM Cortex-M7. This is the OpenMV, it's the board that I have right here. It's an open source, open hardware camera. It's more or less like the Arduino of computer vision. So it's a small microcontroller with just a camera on it. We support that as well. This is the CrazyFly 2.0. It's a really, really small, like it's the size of my hand. Quadrotor. And again, there's a small microcontroller on it. I will show it a bit later as well. This is the BBC Microbit. It's really cheap as well, like 15 or 13 euros. There's a Cortex-M0 processor on it with Bluetooth low-energy support. So far we have somewhat limited support for this, but in the future we will probably focus on using this particular board as the reference platform to learn embedded programming in AIDA. As I mentioned earlier, we started to support the first RISC-5 microcontroller. So this is the Hi-5-1 board from Stifi, the company Stifi. So what's next for the AIDA drivers library? So first we want to focus on the configuration and build system. So I will show you quickly what we have so far, but it's a bit complicated. We use a UGR key of projects, which is not very practical for beginners. More documentation of course, there's never enough documentation. We also have a plan to bring really basic support out of the box support for every possible Cortex-M devices on the market. So that's kind of nice. Linux GPIO. So I mentioned microcontrollers so far, but actually the components driver can also be used on a Raspberry Pi for instance, because you have I2C protocol supported, UART etc. So we want to have some kind of binding for being able to reuse the components driver in a AIDA drivers library, be able to use them on the Raspberry Pi. The AVR platform, so this is maybe not the most trendy platform at the moment, but I think it would be really cool to have some support of AVR in the AIDA drivers library. More components, of course there's never enough, there are so many components in the market. USB stack, so I mentioned that we support we have a lot of support for the STM32. The main block that we are missing right now is support for the USB. So that's something I would like to work on and to support in AIDA drivers library. And there's on the BBC micro bit, there's a Bluetooth low energy microcontroller, so it would be also nice to have some kind of Bluetooth stack on this platform as well. So now it's time for the demo. So I will, I already prepared a few things. So if you want to start programming, embedded programming in AIDA, you can get one of the boards that was listed before. So for this demo I used the STM32F469 just right here. So beforehand I downloaded the toolchain so you can go to aidacore.com slash community you will see the community release of our toolchain. So if you want the ARM ELF version of the toolchain that you can download here. Download it, install the tools, then you can download the AIDA drivers library code. So either you clone the project or you download the zip. And there we go for the demonstration that's working. So this is Gnat programming studio. I will start it here. It's our AID. It's supporting AIDA, C, C++ and Python I think. So when you start GPS you can open a project project file. So let's say this is the AIDA drivers library sources. You go to the example directory and then you will have one sub directory for each of the boards that we support. So for me it's the line. So I go into this sub directory and here we have the different examples that are supported on this board. So I will take the draw example. So this is as I said GPS our IDE. So as you can see over there you have your sources. This is what this looks like. You have support for code navigation. So for instance if I want to if I want to see the definition of this color over here you can jump in the code. You have code completion so if you want to change something to green things like that. So like really a modern IDE features you can then compile your embedded projects. So this is compiling all the Ada drivers libraries so you can see the components. This is the CPU support hardware abstraction layer the STM32 drivers. I don't think I've enabled the parallel compilation here. Okay, there we go. One really nice feature of GPS as well is this view over here which gives you how much memory you are using in your application. So we can see the RAM for instance and you can have some details and see where what part of the program uses most memory. So you might think it's a lot of memory that we use over here but please keep in mind that we have the tasking environment embedded so we have the stacks we have the kernel everything is embedded here. So now that we have our program compiled I will just plug the USB ports of this board. Let's go tech I don't need this and I will have over there you can see them with different shortcuts and this one is flash to board so this will make sure the program is at the latest version so recompile it and then send the application to the board. So that's why developing on embedded is slow. And I have to reset it and this should work so it's just a simple drawing example. Now if I want to debug my application I can use this button over here debug on board and this will open a debugging session yes this will open a debugging session flash the application start gdb etc etc so I don't know if I mentioned it but the Gnat compiler the Gnat toolchain is based on GCC and our debugger is based on gdb we contribute the AIDA support to gdb and then well it's again very common debugging session let me put where is it I can put a breakpoint over here for instance continue looks like you didn't pray enough doesn't really care I don't know maybe I'm not reaching this code current mode drawing restart well ok so demo effect this should work it doesn't and then from this interface you have all the usual gdb feature so you have the call stack hop over here so we can see that it's waiting for some I2C communication so maybe there's something wrong here we have the memory view you can watch variables and all the really neat and usual debugging features so that's it for the demo was more or less ok right next part I want to talk about some of the projects that were developed so either by me or my colleagues at AIDA core and also some people from the community so the first one I already kind of talk about it this was done by Anthony he was intern at AIDA core at the time and he wrote he rewrote the full flight controller for this drone using AIDA and Spark proving some properties using Spark and formal proof this is a project that I made so CNC controller computer control machine made with all the dvd players and floppy disk and this kind of stuff for all the project I give you a link if you want to have a look have more information this was made by University in Spain I think so this is a LED pendulum so using the retina persistence effect to draw text on the air so as you can see this is the small cortex symbol that I talked about earlier this is another project by me so I used the open MV camera and I plugged it to a thermal printer so thermal printer is things that you will see in supermarket or restaurants to print tickets, credit card tickets and stuff like that and I used this to make an instant camera so you take a picture and it will print a gray scale not very beautiful but well it's fun at least the next one is from my colleague Jerome he implemented the version of the Wolfenstein 3D engine in ADA so it's running on this one is the Cortex M7 but it's also running on raspberry pi, bare metal it's running on different version of the board so here yes it's the Cortex M7 as you can see it's customized for the advocacy over there this one again project by myself this one is a custom hardware actually I developed the board as well and this is a sampler and sequencer so you can actually play there's an SD card on the backside you can play samples of music according to a pattern that you enter again if you follow the link you will probably find videos about this and the last thing I want to talk about is the make with ADA competition so for the last two years we organized programming competition so ADACOR organized this competition so far it was focused on embedded software projects for the next edition we will maybe open it a little bit but it's not sure right now it's otherwise open to everyone there's about 8000 euros in prize and so as I said we did not announce the next competition yet but if you follow us on twitter we will make the announcement over there and so my last slides are two example of projects so the winner from 2016 is Stéphane Cares who is over here you can put it he made so this is again the same board as Jérôme used for the Wolfenstein it's an STM-52 F7 there's an Ethernet support on it so he managed to program a network analyzer with this so you used the ADA drivers library in parts and then you made your own Ethernet driver and IP stack and this kind of IP stack the goal of the project was to analyze the traffic analyze the packet and provide some visual feedback about what we have on the network so here you see some IPTV which is running and you have some IGMP microcast packet so this is where you have some flat packets because you have 1,000 packets every second which are received from TV so you displayed the graphic and all the statistics of the network and for 2017 the winner I don't think is over here it was Jonas and he made a brushless motor controller so the brushless motors are the ones used in drones typically and so this is also a custom hardware so Jonas designed this board and he wrote the driver for it using ADA and ADA drivers library so that's it for my presentation I will take any question if you have one but what I would like to know is what are you going to make with ADA maybe I did it from driver's library but I want to ask about the building change so that we can separate the board definitions from the driver's library itself because I designed my own board and basically I had to talk to the driver's library to integrate the board definition inside it so the question is about the new change that we will do in the build system and about configuration of the library for your custom hardware so there's actually two parts that's something that we mentioned in the documentation and I really just went really quickly over this in ADA you have the driver's library and there's the run time which is the library that supports the tasking and this kind of things and usually that's where you will have most of the hardware dependent codes so I don't know if it's the case for you what we will do with the next build system is we will try to as I said support all the Cortex-M peripherals sorry microcontrollers and we will also have some ways of configuring a few points in the driver's library so for instance what you will do is you say I want to start a new ADA driver's library project and you will specify which microcontroller you use and so you will have the linker script for this microcontroller you will have the vector files and stuff like that and you will also be able to configure for instance what is the external clock external oscillators and this kind of stuff the result for the configuration that's what we have planned I don't know if that's what you are thinking about or good I would like to mention that the other question I have the external clock I didn't see before I haven't looked at it in the past not how to change the clock to spend the microcontroller and something like this seems it's all just OK so the question is about configuration of the system clock and if you can turn it off or change the frequency right so given the actual implementation of the Ravanskar runtime the runtime I was mentioning we do not support this is somewhat called CPU throttling so you can change the frequency of your CPU we do not support this right now mostly because your time variables or your clock variables will have no sense if you change the frequency, the speed of the clock so that's not something we support what you can do if you want to save energy is first in the kernel that implements the task inside the runtime when there is no task to run we put the CPU in wait mode so wait for interrupts so it's somewhat lower power mode and the next solution is to really shut down so if you have an STM32F4 you will have to shut down the CPU to save energy that's all we have so far OK yes a little bit you have motor controllers and arm A series and arm M series on the same board do you support so the question is about the M series part of it the question is about the support of the bigel bone blue which CPU is running on this I guess it's made for linux it's for linux it's made for linux on the A series the two cores in it there's an M series core and then an A series arm pole on the same time OK, I didn't know this one I'm out of control of the real time so it looks like there's a cortex A core and a cortex M so for the cortex A I would say it's really meant to run linux so you should run linux and that's what I was mentioning in the improvements that we want to do to support some of the linux driver for SQC and SPI for the cortex M part I don't know this device in particular but you should be able to to support it with with the AWS library there will probably be some adaptations to this specific hardware that should be doable so, thank you thank you all