 Hello everyone. My name is Michael of the NACA from Bootlin and today I'm going to talk about using Visual Studio code for embedded Linux development. So to introduce myself, I'm the founder and an embedded Linux engineer at Bootlin, which is an embedded Linux engineering company. We are specialized in low-level developments, kernel bootloaders, working on embedded Linux build systems. We do boot time reduction projects, implementing secure booting, graphics layers and many other aspects that are low-level enough, right? Contributing to the community is what we try to do as much as possible through code, of course, with experience sharing like in such conferences, but also by sharing all our training materials freely online through a free documentation license. I am also the current maintainer of the Elixir cross-referencer, which is a tool to index the source code of Linux, Uboot and Busybox through an online interface. So check it out if you're interested in such projects and in browsing source code. I'm always interested in discovering new tools and sharing my experience and the learning experience with the community. And what's special about this talk, I have to admit it's the first time I'm speaking about the Microsoft tool and actually so far I've only used Microsoft tools with the purpose of replacing them. So I initially proposed this talk after stumbling upon a survey from Stack Overflow from last year stating that visual studio code was ranked as the most popular development environment in the survey with more than 50% of the respondents claiming to use it, so that's an impressive number. And I was actually looking for other tools, other editors, but they eventually was amazed by this number. So I wanted to know more about that. So let's start with a disclaimer and the goals of this talk. First, at not a visual studio code guru at all, I'm just learning. But after hearing about VS Code also from many bootlin customers who started showing the tool to me, I wanted to do my own research on it and share that with you. So the main focus of this research was to find out to what extent VS Code can help with embedded Linux development tasks, and also how it compares to the Elixir cross the refer-referencer that I've been contributing to in terms of code browsing and indexing. So please share your experience while this pre-recorded talk is playing by posting questions and comments. And I'll be available during the talk on the chat and also after the talk, of course. I'm most interested in your feedback and your experience too, as this is relatively new for me. Thanks. Let's start by an introduction to Visual Studio Code. It's hard to beat these summaries from Wikipedia, so here it is. So Wikipedia says that Visual Studio Code is a free source code editor made by Microsoft for Windows, Linux, and macOS. Features include support for debugging, syntax highlighting, intelligent code completion, snippets, code refactoring, and embedded git. Users can change the theme, the keyboard shortcuts, preferences, and install extensions that add additional functionality. The first release was made in 2015 and over the years, over 16,000 extensions were developed by the community showing how extensible, easy to extend the solution is. It's important to keep in mind that this is not a free software or open source project. You can check on the interface itself. The license is stated as a Microsoft proprietary license. However, most of the project is still based on the VS Code open source project from Microsoft, which is under the MIT license. So check out this GitHub repository where most of the source code is. So what are the issues with Visual Studio Code? The first one is telemetry. Visual Studio Code collects usage data and sends it to Microsoft. There's a link to the Microsoft privacy statement in the tool, but it's all about Microsoft products and doesn't reveal anything specific about the data collection in VS Code. However, this can be disabled by tweaking the user settings. Just look for telemetry that's very easy to disable. And anyway, the source code for this data collection is available. Another issue is with the extensions marketplace. So the issue is that Microsoft prohibits non-visual studio applications from downloading binaries from their extensions marketplace, the Visual Studio Code marketplace. So you can't implement a third-party alternative that fetches from the Microsoft marketplace. You can see that in section 1.b of their marketplace terms. It's very explicit. I find this disappointing as most extensions are open source anyway and not developed by Microsoft. So as a consequence, the extension owners have to push their extensions to other extension registries too. And that's manual, that's not automatic. They have to do that explicitly. So as I'm always looking for 100% open source solutions, I looked for one. And I eventually found VS Code, which is 100% open source build of Visual Studio Code with telemetry disabled, essentially, and proprietary extensions disabled too. The strengths of this project is that it's making very frequent updates, staying in sync with the latest VS Code base very quickly. So as soon as there's a VS Code release and you release there, you get VS Chromium update very quickly too through the repositories. So that's really impressive. It has limitations though. Like it doesn't have all the VS Code extensions, as indeed it cannot use the same marketplace, as I will explain in the next slides. It also missed some extensions I found under VS Code that I found useful for embedded Linux development such as Devastory, Kconfig, embedded Linux, Linux kernel dev. And another issue was that in particular, C and C++ support is apparently built in according to the documentation, but doesn't work out of the box as it does with VS Code. Like when I imported a new project, a C project, normally in VS Code, it just detects that, proposes the C++ plugin, and there it goes. Everything is ready to be used, but it didn't work out of the box with VS Code. So I could do a few things to improve this, but that's probably due to my limited knowledge of VS Code. So that's a project definitely worth supporting, and I will continue my investigations with it. But since I had limited time, I decided to stick to VS Code for the moment and really understand what features it can bring, and then we'll see about the alternatives to it. Before we dive into the capabilities of VS Code itself, I have to mention other related solutions that I found during my research. One of them is the Thea IDE from the Eclipse Foundation, which is a completely different project, still supporting all VS Code extensions, but having its own architecture being more modular and allowing for more customizations, according to their developers, of course. It's also designed from the ground up to run on both cloud and desktop, and I'm not sure that's the case with VS Code. So it's developed and hosted by a vendor-neutral open-source foundation and not by a single company, as is the case with VS Code. It's now adopted in many IDEs across the industry, such as the new Arduino Pro IDE, ARM's embedded IDE, Eclipse J, which is a flavor of Eclipse, and the proprietary WebID from SAP. Another related project is Eclipse OpenVSX, which is a vendor-neutral open-source alternative to the Visual Studio marketplace that solutions such as VS Code and Thea can use. There is a very nice article actually, right here, introducing you to Thea OpenVSX and the limitations that are brought by the Visual Studio Code marketplace. Last but not least, here are some terms that you will find when you read documentation about VS Code or when you go through its menus to explore them. So the first one is IntelliSense, it's a generic code-completion tool that's built into Microsoft Visual Studio and it appears in support for all types of languages. There's nice documentation about it in here. Another one is IMET, but it's shown in the interface, but apparently it's for web developers, so that's not for us here. And the last one I wanted to mention is the Language Server Protocol, which is a new generic open protocol for communication between code editors and IDEs, so that when you use a new language to support, you don't have to create a new communication scheme between the IDE and the editor. Wikipedia has a worth-checking page about that. The first thing I want to show you is how to install VS Code on Ubuntu. Then I'll quickly guide you through the interface and its various components. I also show you how to disable telemetry and I will just show you the most important shortcuts in my opinion. So here's how you can install VS Code on Ubuntu 20.04. It could be different with other distributions. In the case of Ubuntu, it's available as a snap package. And then the package name is just Code. Yes, here it says that you don't have a classic confinement and not a security sandbox that would be better in terms of security, but let's go ahead and do it. So I just add minus, minus classic code and there you are. So here's what the interface looks like when you start it for the first time. Well, I already started it as you can see because there are files somewhere that are open. So well, you have a welcome page with summaries, information, documentation, shortcuts, et cetera. That's quite nice. So you have like the code explorer here for product code. Then you have a search and replace functionality, which is quite, quite good actually. So like replacing hello by hello in a set of projects. Just works fine. So it finds the projects that are applicable and does that. Then you have the source control window that for a repository can work with Git, typically. Then the debugger window, at least the debugger button and then the extensions that are available. So here you see all the most popular extensions apparently. Then I wanted to show, yes, here you have like the settings part. That's where you can set your settings. Here it's time to disable telemetry. So I'm going to show you how to do this. It's very easy. Just input it and disable it here. So there should be no more reporting to Microsoft in case you don't want that. And last but not least, I wanted to show the shortcuts. The most important one in my opinion is control shift P, like command palette. It shows you various tasks that are available, like to build a project. And that's the second shortcut I would recommend, which is control shift B, like build. And then of course there are other ways, other ones you can customize. You have plenty of choice here. This is very flexible. Now I will demonstrate the CPP tools extension for the C and C++ languages. Once again, if you look at the interface and the description of the extension, you'll see that the license is proprietary, but once again based on MIT license code. So I will open the Linux kernel source directory and then VS code will propose to install the plugin, which I will do. And then I'll show you the features of this plugin. First looking up identifiers, as I would do in Elixir, testing the expansion of the finds and also starting to type code and try auto-completion as proposed by the IntelliSense mechanism. So here I opened VS code again on the Linux kernel source directory. I started browsing a little bit. I got a few warnings I can dismiss. Normally when you open a C source file for the first time, it pops up and automatically suggests to install the C++ extension. But here I've done that before and it doesn't want to bug me with the same suggestions. So I would have to install it manually, but it comes next very close to the top. So here it is. I can install support for that. That was quick. I don't want that. And then you can go back to browsing the code again. There we are. So now it takes a bit of time for VS code to index the source code. You can see this. It's scanning. So it's ongoing. Like if you look at the definitions here, they're not available yet. So let's wait a little time before this is over. But it's making progress. Usually it happens even before you realize it. You start browsing and while you're doing that, the indexing is over. Okay, I'm back now. I wanted to show now that information about symbols is available like this. Just pass the mouse over the symbol and you get the information. What's nice too is that you have also defined expansion. It's really nice. Very, very convenient. Actually, to make this happen, I also had to accept the update or maybe the installation of extra settings. So I just accepted the suggestion that I was given. And now we have the code information right here. Of course, then you have lots of more detailed things like go to declaration, definition, references. All this go to switch header source like that. Right, okay. So you go to the corresponding header, men.h corresponding to men.c. And that's about it. Yes, now I can show you how we can edit the source code, of course, using auto-completion. So here, if I want to add a printk, it will show me the possibilities and the prototype. But I can also use the same command device create and see all the commands that match like this one. So you see the prototype here. I don't know exactly how to expand it, but there must be a way, right? That's about it for the moment. You see that indexing is still going on. But I did that again, actually, on the project. It's apparently, I guess it gives priority to the file that the files that are being explored. So this way, you always get similar information once you're browsing a given source file. So that's very convenient too, so that you have a fast response for all your requests. Next, I will show you the VIM extension. It's available under an MIT license, as most extensions do. And you will see that it's easy to enable or commands seem to work as usual. You feel like at home within. Note that other extensions also exist for other editors, such as Emacs, Atom and many others. Well, now I want to show you the VIM extension. There we are. VIM Emulation for Visual Studio Code. Let's install it. Hey, there we are. It's enabled globally, so everywhere it should be available. So let's go and try to edit our code now using features of edit of VIs. So I'm moving the code with the J, K, L, H keys. That's great, they work. Let's try to delete this word. CWU, yeah, it does work with BI commands. The last one thing I like is also rectangular selection. So let's see if this works. So it's Ctrl Shift to Ctrl V. Now, I probably made a mistake. Ctrl V. There you are. Yes, it does work. Almost, at least. Yeah, kind of it. It works. Currently, so now I can... It's not as rectangular as I used to have, but almost. Then I can delete that and undelete that, of course, with undo. So it seems to work mostly. Well, we don't want to explore the whole of Vim, but at least I'm back to my editor for editing the code. I'm feeling at home now. The next extension I want to show you is called CheckPatchLint. It's available again under the MIT license. What you need to do is first install the checkpatch.pl script on your system coming from the Linux kernel source directory. And it's very useful to create code that's compliant with the Linux coding style and rules right from the start. So directly in the editor, you get feedback from CheckPatch if something is not right in the code you are creating. Of course, you can also post-process your code with this and see the CheckPatch report. So let's install the CheckPatch extension. There you are. So to actually use it, you have to install a CheckPatch on your workstation or maybe provide a link to copy it from the kernel sources to somewhere on your workstation. I already did that. So now it's just a matter of exploring the source code with CheckPatch. So I'll do that. Actually, if I go back to the properties of the extension right here, you see properties. I'm supposed to enable it. It's not only installed, but I need to enable it explicitly. And now I can go back and explore the code. So now I open another file, a Ctrl and Shift P to run a command. CheckPatch selected file. There we are. So I'm going to checkPatch on this file. I don't see lots of warnings up here. Right here. Which one is that? Oh, okay. Two ones. We prefer PR Info to PrintK, Kern Info. That's to recommend it now as PrintK is re-deprecated. And there's also spacing. There's a space prohibited between function name and open parenthesis. So we should take that away, right? I could run CheckPatch again from the commands. Ctrl Shift P again. CheckPatch. And at least this should be gone. Apparently I need to save, I guess. Save. Ctrl Shift P. Check. Oops, sorry. One command. And now this should be the only one problem that's reported. So you see the CheckPatch errors that actually reported by being underlined in blue. A bit like syntax checking. No, spelling checking. But with a blue color. So here you can see where all the issues here, they're reported in the problems as well. And by the way, I failed to say that there are a few issues with the kernel sources. It cannot find some generative.h files. And that's expected, of course, because they are generated. So there are probably things to do to properly support the Linux kernel sources, like maybe either generate the headers ahead of time or we'll do something else. This is something I haven't figured out yet. Another resource I found is called Kconfig syntax highlighting with MIT code again. But it's just for syntax highlighting in the Linux kernel and bit root configuration parameter definitions. There's no support for symbol lookup. I'll compare that to the more advanced capabilities of Elixir in that field. So now I'm going to show you syntax highlighting for Kconfig files. So you see you have syntax highlighting by default with MIT files, at least for CNC++. But if you go to Kconfig, nothing happens. So let's go ahead and look for the extension that's missing. Kconfig, there it is. So let's install this one, enable it. Go back to the code. If I open Kconfig now, there you are, syntax highlighting. However, it's just syntax highlighting. It doesn't help, for example, to do something about the settings and see where they're used, for example. And this is in contrast to what you have with Elixir. So I'm going to fire Elixir and show you what kind of information you get with Elixir compared to this. So there I am. I opened Elixir on driver's chart Kconfig. And this time you can see that for each, you have syntax highlighting as well that we contributed, if I remember correctly, to the printing print project. I forgot about the name exactly. So now here for each symbol here, you have a link to each parameter. And you see where, in which Kconfig is defined. So that's exactly where we were. But also where it's referenced, especially in the makefile. So here the reference, thanks to dependencies, I guess, what is the definition itself. But there's probably a dependency somewhere else. Depends on printers. You can see the dependencies on that parameter. And also where it's used in the makefiles, typically here. So you see where it's used. To what file it's being used for compiling. And the same applies to other settings in makefiles. So you can click on those and see how this one is defined. So that also helps to explore the makefiles themselves. So that's something we don't have in VS Code yet. Hopefully one day. Another extension that I found is called embedded Elix kernel dev extension. It's also licensed with the MIT license. It's trying to support symbol.completion, function and symbol navigation for C, Kconfig, devconfig.config and device tree files. So all types of kernel files. And it's trying to add automation to match device tree compatible and open their respective driver or documentation files. Like Elix here, it's based on universal syntax, but it's less advanced than Elix here, as we will see. So I'm going to install this new extension. So it's called embedded Elix kernel dev. There we are. It's installed. We enable it. And then I'm going to show you how it tries to match, to find the device tree compatible definitions. So let's look for a file. So the easiest way to look for a file in a project, you go to the command palette, control shift P. You actually do a backspace here. You want to look through commands, but rather through files. So backspace here. And then you get a chance to look for files by name. So here I'm going to look for SAME5D3 DTS sign. That's I want to go to. Now I'm going to look at, oops, control F. Sorry. So looking for SPI. I'm looking for, of course. Let's this one. So that's the compatible string. I'm going to try to use this to go to the definition of it. Oh, no. Device tree doc from compatible. And there we are. Let's wait. There we are. So what it found was atmelflexcom.h. And I believe it's actually wrong, because it just probably mentioned of this string inside this file SPI. Yes. That's an example here. But it's just a child node to the main child, to the main node that's been demonstrated. So here the binding is for flexcom, not for atmel SPI. So here we have a false positive. It does find the compatible string in the binding, but not at the right place. So that's the one, this one that should match. So actually it's somewhere else. And let's use Alex here to see that. Otherwise, let me just close this, get back to the original file, and then look at device driver match from compatible, and see if this works. At least you see the syntax highlighting for device tree, which is good. And here there's another one, XFDcore. So if I look for SPI, I'm not sure I got the right one. I should look for compatible. Nope, doesn't seem to match. I don't know why this one matched in particular. Okay, so that's not completely perfect. It's not really mature yet. So it needs perfecting. So now let's have a look at how this is handled by Alex here instead. So I've opened the DTSI for SAME5D3, right? I want to look for the SPI, SPI node. That's right. That's the one I was looking for. So here in Alex here as well, you have a happily corresponding to this compatible string. And let's see if it works. So the definition is actually the implementation like the driver implementing that compatible string. So there you are. That's the SPI admin driver as expected. So there's no, you don't have the false positive that you had before. Effectively, we still find the one that was found by VS, virtual studio code, but visual studio code and virtual studio. But that's also false positive here, I believe. So here it's actually should be, that's the right answer here. So that's the binding for the SPI admin driver, right? And then what you also have is all the device resources that our device resource includes that make a reference to this compatible string. So all the boards are essentially all the SOC or board devices that use this particular compatible string. So that's useful too. So Alex here has the false positive as well, and I'll report that, but at least it also has the correct information. Next, I'm going to quickly show you GitLens, which is a quite exhaustive extension for Git access and management. It's a monthly license as well. I'm just going to show you the Git blame feature, which I find useful when working with kernel code, but otherwise they are countless possibilities related to Git. So now it's time to show a few details about Git integration. The first thing I wanted to show you is here. It shows actually the changes that have been made. Oh yes, so here you can see the diffs the original version and the original version and the new one. What happened is that we fixed the check back issue if you remember. So now it could actually create a commit out of that change. It's also, I can actually discard a change if I want. Let's do it. You see, it's nice. So this is out of the box. You get support from VS Code, right? You could also update, get the latest changes from Mainline, from upstream. Let's do it. Yes, please. So it takes a bit of time. Shouldn't be so slow because there are probably not many changes to check. And that was done. All right. So I guess it pulled some other files. I could see. But I don't want to spend too much time on that. Git is a very huge topic and you can assume that it's pretty well covered. What I want to show is an extension that's well known. It's Git Lens. There you are. So it's super charged. Git capability is built into Visual Studio Code. So there we are. Let's install it. It's immensely popular, as you can see. In particular, it's going to show Git blame information for the code. So there we are. It should be ready. Get back to the code. I'll select a file and we'll be back with you. So I'm back. I open the blog, ioctl.c. I'm trying to use Git blame, for example. And just after enabling Git Lens. So here, when I click on the line, you can see here in gray, or you can see a description of the commit that corresponds to it, to this change. So you know who last changed that line. So you even recognize the photo of Arne Bergman, if you know him. That may be a gravitar or something like that. Then you can click on, you also have that information right here. So on every line that you click on, you see who last modified the file. So then you can go to here and see the changes associated to that commit. Oh no, sorry. My mistake. You have to go. You can go here and do show commits in search commits view. And that's the commit we want to check. And you can see the changes in the files, right? Corresponding the difference between the original file and the modified file. Nice, isn't it? Yeah, it's really nice to have such integration directly in VS Code. So Git blame, very easy to run this time. Next, I'm going to show you how to cross-compile the Linux kernel inside VS Code. So I'll show you how to set the environment for cross-compiling in Terminal. And using the Terminal to configure and build the kernel. Here, VS Code doesn't add much value. Here, CPP tools could help finding tool chains, setting up the environment maybe for the Linux kernel. But I guess a more dedicated extension would be more suitable than a generic one. But it doesn't seem to exist yet. So now I'm back in the Linux kernel source directory. And what I want to do now is just compile the kernel. So I haven't found anything special yet to compile the kernel. So you can do it though in VS Code just by opening a terminal. So there we are. And it's business as usual. So I need to check the target architecture, the target compiler. Which was already set. There you are. I can make the terminal a little bigger. Notice that the terminal is automatically opened in the directory corresponding to the project. So that's the right directory. I can run make menu config. Hopefully the terminal is wide enough. Yes, it is. So I can check various things. Actually, I don't have the right setting. So I'm going to run make some A5 DevConfig. Because I want to compile the kernel for the some A5D3 explain board. There we are. So now I can check the system type. And it's the right one. So I could make further changes of course. And then just make running multiple jobs in parallel. And then here it goes. Obviously it would take a bit of time. So here nothing really special about kernel combining. You just had the convenience of directly having a terminal in the right project directory. And there you are. You don't have any special highlighting for warnings, I guess, in terminal and output. That's something that you might get. But then of course you can't expect that from a generic C++ extension. It should be specific to the Linux kernel, right? So that's it. We don't wait for the end of the compile work. It's going to take maybe five minutes. So no need to wait. Now I'm going to show you how to cross compile a simple C program. Hello world, of course. So I'll show you how to specify the use of a cross compiler in the interface. Actually it's just replacing the name of the compiler executable. And then I will show you how to define the default build task. So that you can easily compile a program every time you change a line of code, right? Just by pressing a button. So now I'm going to show you how to cross compile a simple hello.world file with Visual Studio Code, right? So just what you have to do is just define the build task as done here. So I'm going to take the GCC build active file for the current file, right? That's very easy. And the only thing you have to do is just customize the compiler. And that should just be enough. I'm going to find the compiler file in the terminal. There it is. There you are. You can actually, this creates actually a tasks.json file. That's what defines the task, the build tasks, right? So tasks.json, you can save it. Then you move back to hello.c and just run build task, which is going to be run directly through control shift B. There you are. Success. So just click on that to close. And then I can see I've got an executable that's called hello. And that has the right type. It's an ARM executable. You see how easy it was. I'm sure you can do that again easily. Another tool I found is called CMakeTools from Microsoft. It was actually created by somebody else, but Microsoft took over. So this can generate a template project for you to get started. And a nice feature is the capability to detect cross-toolchains. Cross-toolchains, it calls such toolchains kits, but that's partially broken, as we will see. There's support for multiple compiling profiles, like building a production ready executable or an executable with debugging symbols, or to optimize the executable for size of a speed. Another limitation is that there's no example code or CMake files for languages other than C++. I didn't see any C support and URAS support. And that's missing. So I've just installed CMakeTools, the extension. And I'm going to use it on an empty directory here to create a new project. So it's a CMake project. So it's easy to do. You do a CMake quick start, which asks you for a project name. Hello, of course, it will be an executable. So it proposes to create a CMakeList file, right? And that should be all right. So it did create a main file with Hello World and a CMakeList file. All right. So the next thing I need to do is Ctrl Shift P, select scan for kits. I'm looking for cross compilers. So it did manage to find some Ctrl Shift P. Now select the kit. That's the one. So I'm going to use my standard C cross compiler. There we are. And now the next thing you need to do is CMake configure. So that's going to build the infrastructure to compile my executable on Linux. And now after doing that, I can do Ctrl Shift P build, CMake build. There we are. So let's look at the output. It did work. So if I go to the build directory, there's a file that's gone. Hello, as expected. Ouch. It's an x8664 executable. So it didn't really take the cross compiler into account. So there's something I need to fix. I know how to fix that I found out. So let me take the path to my cross compiler on Linux GCC. That's the one. I found out that the quick hack is to modify the CMake cache file and look for C++. That's the wrong path, you see. It didn't get it right. From this kit, the kit I selected. Unfortunately, so if I build again, Ctrl Shift P CMake build, it succeeded. Apparently it called my terminal, my compiler. And now it's an arm file. So I need to fix this to understand why it doesn't work as expected. But now I have a CMake file and it's ready to get started with this project. Then the last thing I want to show you is something closer to real life. That is remote debugging with GDB server. So here I'll show you how to implement a script to cross compile code, deploy the generated executable on the target through SSH, and still using SSH started remotely through GDB server. Then I'll show you how to customize VS code for the use of a remote debugger. And then we'll be able to use the remote debugger with all its features like inserting breakpoints through the interface, step-by-step execution, reading variables, analyzing a segmentation fault. And that's the first time I use a graphical interface for driving GDB and it was really a pleasant experience. A special thanks to the author of this article which really helped to get this to work. So now about remote debugging, let me show you what I've done. So first, I'm going to show you what I've defined some process, some script to actually build my executable. Cross compile my executable, so it's called Mr. C executable, it's called vstimulator.c. I compile it through prepdebug.sh. So this cross compiles the executable, kills GDB server on the target, copies the executable to the target through SSH. So here it assumes that you have to set up password less access to your board through SSH. This is relatively easy to do. Just look at the URL, the article I shared. And then still through SSH, you restart the newly compiled application through GDB server on the TCP IP port, right? And this means that the GDB server is waiting for a connection from the host. Now, the way I'm going to show the tasks.json, it declares how I'm going to build this executable. So here I just had to create a new task. I mean, VS Code will help you to do that. You just essentially need to fill the path to your executable instead of just invoking the cross compiler just called your script instead. So that cross compiles and copies to the target. So you can look at this. It's json.tasks.json. So that's where I run, when I run build task, terminal, run build task. And then, so let's actually run it. Just run build task. And you see it, there's no GDB server for the moment. So it's not killed. It did do the job, right? In the terminal. So it should be okay now. So now I can go and actually debug my application remotely. And this is done by creating and customizing launch.json. Launch.json is always for debugging. There are a few things that I needed to specify the target architecture, the debugger, that's GDB. And especially I added two parameters that correspond to remote debugging. That's the debugger path. Here I'm invoking ARM Linux GDB on my host. So that's part of my tool chain. And that's for the GDB server address. So that's another parameter I had to add. That's the target address and the remote port. That's all you have to do if I recall correctly. You have to mention also the path to the local executable, which was built with debugging symbols, right? So now I can go ahead and actually launch the debugger by just pressing start debugging. All right. An exception has occurred, segmentation fault. So now I could debug that. So you see it worked. It showed me exactly where this happens. It actually happens because I'm allocating too many buffers. And after some point, of course, the allocation fails. And there's a segmentation fault because I didn't check the return value from KMLO. So here I could run that again. I can insert breakpoints, for example, by clicking on a line, abort the debugger and debug it again. Wait. OK. Now I hit the breakpoint. Good. And it's nice here because you can read the values from the variables in this context, like file is 0x0. And filename has this value. You can read the string value from here. So if I had other local variables, I could check their value. I could step in and run again. And then I hit the segmentation fault again. I would expect to have to step in multiple times and remove the breakpoints. So if I do that, it would stop and directly hit the segmentation fault again. Yeah. I apologize. It's a bit quick. But I'm running out of time now. But I could change some code and fix the issue, recompile. Like if I recompile the code here, I would build it again and be able to debug it again until I managed to get rid of the error, of course. So it just works out of the box if you know how to configure those things, how to configure remote debugging. And set it, I mean, of course, here in that case, I built a root file system with build route with GDB server on the file system and also with SSH, DropBear SSH, so that I could directly copy the executable over SSH from Visual Studio Code to the target, right, to the target by using SSH. And then restarting GDB server. Restarting the target executable through GDB server. Right. But this works. That's quite nice interactive. It's a nice experience for me to use a debugger in an interactive way, not only from the command line. It's now getting time to draw conclusions. So in terms of pure code browsing, I believe the Elixir cross-referencer wins. For C, C++ make files, device tree files, it provides links to included files, which the current extensions in VS Code can do. In the device tree, it supports finding driver bindings, which is just partially implemented in VS Code extensions. There's also full key config language support. It's also available as a way to identify users in this space. But however, VS Code would win for exposing git information, such as git blame information, and showing in-place information, like symbol prototypes, expansion of defines, which is much easier to get than through links that you have to click on in the browser. But of course, VS Code offers much more than code browsing. Now, I would like to share the limitations I found in Visual Studio Code during my research. The first one is that there's no way to filter extensions by license, whether they're open source or proprietary, and I have a clear preference for open source one, so I'd like to have that option. I have the exact same issue on Android, by the way. An issue with CPP tools, like that is C and C++ support, I observed clogging the CPU, or maybe the IO, looking for the declaration of some symbols. I had to close VS Code to end this. This is quite rare though, but I noticed that some other people report this kind of issue about when they rate the extension. Another issue, which is the outcome of this research, is that there is a current lack of extensions for embedded Linux, like applications and tools. So support for cross-compiling tool chains, support for Valgrind, except output syntax highlighting, that's just that. Support for S-Trace, L-Trace, Yocto project, build route, there's nothing for kernel modules. There's no serial port emulators that I could find. So currently, the VS Code and extensions seem better suited for microcontroller and RTOS work. There are plenty of plugins for that for embedded microcontrollers, for OpenOCD and things like that, but it's more focused on microcontrollers, apparently, than for embedded Linux itself, but of course that's a gap that can be filled by the community. And now come the final conclusions about Visual Studio Code and its suitability for embedded Linux work. All in all, I think Visual Studio still misses important features for embedded Linux development. However, it is very flexible. It's easy to extend and therefore has a great potential for further improvements. So it's already a great solution for debugging programs, even remotely. It just works out of the box and fine. Not out of the box, but just fine. And it makes me feel like contributing new extensions. For example, to support bootlin cross-compiling tool chains. This will also benefit to more open platforms, VS Code, Yocto, everything you contribute to VS Code can also support to the more open platforms. So think about it. Hey, that's already the end of this talk. It's time for questions, suggestions, any comments. I'll be most interested in your feedback about your usage of VS Code, what extensions you discovered, and I could talk about those ones in my next talk in the updates to this presentation. So I'll be available for further questions in a time that remains and also we'll be hanging around in the instant messaging channels that's provided by the conference. Thank you in advance and thanks again.