Memory Management

mruby machine: An Operating System for Microcontoller

mruby machine: An Operating System for Microcontoller

by Hitoshi Hasumi

In the video titled "mruby machine: An Operating System for Microcontroller," speaker Hitoshi Hasumi presents his innovative approach to creating an operating system tailored for microcontrollers using the Mruby virtual machine. The session, part of the RubyKaigi Takeout 2020 event, explores the integration of a mini Mruby compiler (MMRBC) and the MRuby VM to facilitate effective development on microcontroller platforms.

Key points discussed include:

  • Background of the Project: Hasumi highlights the limitations of existing solutions like MicroPython, particularly in terms of memory requirements for microcontrollers. He focuses on developing a small MRuby compiler to address these challenges.

  • Microcontroller Target: He specifies the PSoC 5LP microcontroller, characterized by its ARM processor, 64 KB of RAM, and 256 KB of ROM, emphasizing the project's goal to run a Ruby compiler on it.

  • Technical Stack and Tools: The speaker introduces important tools and technologies, including MRBC (a command line tool of the MRuby compiler) and MMRBC (Mini MRuby Compiler), along with various cross-compilation tools for ARM architecture.

  • Toolchain and Libraries: Hasumi elaborates on different toolchains used in the project, including GCC and EABI tools, and discusses the advantages of using lightweight C libraries like newlib over larger alternatives like GNU C Library.

  • Parser Generators: The presentation includes insights into the parser generator Lemon, its advantages over alternatives like YACC and Bison, and its relevance to memory efficiency and code size.

  • Memory Efficiency and Performance: In a comparative analysis of RAM consumption between MRBC and MMRBC, Hasumi demonstrates significant improvements—MMRBC uses only 11 KB to compile a basic "hello world" script compared to MRBC's 157 KB, showcasing the potential for microcontroller applications.

  • Syntax and Capabilities: He reviews the syntax supported by MMRBC and outlines plans for future enhancements, indicating that MMRBC can support various Ruby features while targeting minimal resource utilization.

  • Conclusions: The talk concludes with a summary emphasizing the integration of MMRBC, MRBC, shell programs, and hardware drivers to build a comprehensive development environment for microcontrollers. Hasumi expresses hope for further discussions on related topics in the future.

This session provided valuable insights into building efficient operating systems for constrained environments and illustrated the capabilities of Ruby in embedded systems programming.

00:00:00.560 Hello everyone. Today, I am online to talk to you about the mruby machine. Let me introduce myself; I am Hasumi from Matsuya. I love sake, coffee, curry, and soba. I usually write various applications and am sometimes known as a microcontroller developer. Anyway, please check my Twitter account, as I will share some additional information there while this video is being streamed. This is our company, Monster Lab. We are a worldwide development firm, including Matsuya. Please let me know if you are interested in working with us.
00:00:56.239 Okay, let's start Chapter 1: the background of my project. According to the FAQ page of MicroPython, we generally keep the minimal configuration of MicroPython under 80k of ARM assembly code, which includes a compiler and an interactive prompt. This means a Cortex-M microcontroller with 128 KB of flash, which refers to ROM, can host a minimal version together with some hardware drivers. Regarding RAM usage, 8 KB is the minimal amount required to run simple scripts. As Python is an interpreted high-level language, the more memory you have, the more capable applications you can run.
00:02:05.360 The reference MicroPython board, Pyboard, has 128 KB of RAM. On the other hand, flashing a MOV application into 128 KB of ROM and running it on 128 KB of RAM are both evidently difficult. Mrbc is a smaller implementation of the MRuby virtual machine, but it does not have a Ruby compiler. Consequently, you have to compile Ruby scripts into VM code before embedding them. I must admit that MicroPython is really strong, but I am not giving up. Let's create something that doesn't exist yet: a small MRuby compiler.
00:03:06.720 By the way, our target microcontroller is the PSoC 5LP, which has an ARM processor, 64 KB of RAM, and 256 KB of ROM. I believe it will be sufficiently comparable if the Ruby compiler runs on the microcontroller. Now I will show you a quick demonstration. You can see the PSoC on the left window. The right window is a terminal emulator connected to the PSoC via a serial cable. I'm starting the PSoC and then typing some Ruby codes, such as 'hello world' and 'nice to meet you.' Then, I will make an instance of a LED class. The class of LED is, of course, LED. Now I can turn on the LED like this. Look at the PSoC! Yay! And I can also turn it off. Congratulations! You have just seen an MRuby compiler and a virtual machine running together on the PSoC.
00:04:59.680 Chapter 2: Now we are going to look at terms and tools. MRB is MRuby, as you know. MRBC is a command line tool of the MRuby compiler, and it is a part of MRuby. MRBC is a smaller version of MRuby. As I mentioned before, MRBC is merely a virtual machine and does not include the MRuby compiler. Therefore, we usually use MRBC to create VM code for MRVC. There are very relevant terms on this page. MMRBC is the key product of today; it means Mini MRuby Compiler. I refer to the combination of MMRBC and MRBC as MM Ruby. The MRuby machine is the title of this talk, which has its technical stack illustrated on the next page. We will be able to deal with almost everything related to microcontrollers by using Ruby. Today, I am focusing on the compiler, but other tools like shell and interrupts are also very interesting. I hope to have another chance to discuss them in the near future.
00:06:41.520 Next, I need some cross-compilation tools for ARM because the architectures of my host computer and the target controller are different. We use ARM non-EABI tools to build binaries for the ARM processor. EABI obviously means ARM architecture without an operating system; you can also refer to it as bare metal. EABI stands for Embedded Application Binary Interface. So now you know that these tools are necessary. I use three different kinds of toolchains for my project: one is the normal GCC, which is a standard C compiler. Secondly, I occasionally build binaries for Linux to ensure I don't make bugs that only appear on the ARM architecture. With this setup, you can also use GDB for debugging. The last tool is the non-EABI GCC, which is used for creating the final executable for the PSoC.
00:08:15.520 By the way, I've uploaded a Docker image for you; feel free to use it. The last topic in this chapter is the C library. There are various libraries available, such as the GNU C Library, which is the most popular. However, I do not recommend using it for microcontrollers because the code size will be too large to accommodate. In this scenario, you can instead use the newlib series. They are designed to be small and are written for reduced footprint in things like performance and memory security. Now, we are diving into MMRBC, the Mini MRuby Compiler. It's the repository of MM Ruby, including MRBC, so please check it out.
00:09:10.480 These are the features of MMRBC: it does not depend on MRuby or MRBC. MMRBC relies solely on libraries like GLIBC or newlib. MRBC can be integrated with both MRuby and MRVC. You can easily build it not only for the ARM architecture but also many other architectures, and it is small, of course. The details will be discussed later, but you can install MMRBC into 256 KB of ROM and have it run on 64 KB of RAM, just as you saw in the demonstration. MRBC uses Lemon as its parser generator instead of YACC or Bison. Lemon is originally a parser generator for SQLite.
00:10:08.000 I know that almost all of you are fond of topics related to parser generators, so I will elaborate a bit more on it. What I will explain next is what I’ve learned so far, so please correct me if I’m wrong. LALR means look-ahead left-to-right; it refers to a theory of parsing. It is sometimes thought that YACC and Bison are almost the same, but there are several differences between them. For instance, YACC is non-reentrant, while Bison is reentrant. Also, the third is safe. YACC has parser calls known as LEX style, while Bison has lexer calls known as parser style. However, you can also select all the Excel in Bison. Lemon is re-entrant and functions under lexer calls in parser style. It represents a modern formatting style of a parser generator.
00:12:16.560 According to the documents, it is faster than Bison, but I'm not sure if this claim holds true. According to what Max told me, the code size tends to be smaller with Lemon compared to Bison. Thus, I prefer using Lemon instead of Bison. Although I do not have enough time to explain it in detail, I want to mention that the grammar syntax of Flex is different from Bison. For more details about Lemon, please check the official page.
00:14:03.040 In the final chapter, we will discuss how to make it smaller than MRBC. The primary goal I have set is achieving a small footprint concerning RAM and ROM. It is now time to compare the two. First, we'll examine RAM consumption. In this chapter, I will use the MRB3 branch of MRuby to compare it with MMRBC, which I’ve written.
00:14:18.720 To simplify the comparison process, I built MRBC and MMRBC as binaries for 64-bit Linux. Both utilize GLBC's malloc and free to remain analyzable by Valgrind. Valgrind is a toolset that aids in profiling memory or detecting race conditions in multi-threaded analysis. The command to analyze memory looks like this. We also use the `ms print` command to see the results of the analysis.
00:15:20.480 Here’s a key example used to test. The code 'hello world' contains one function call, which has one argument without parentheses, and as you can see, the output is 'hello world.' This is the result of MRBC. The analysis shows a transition of memory usage in this graphical format. It indicates that MRBC used 157 KB of RAM to compile 'hello world.' On the other hand, my compiler only used 11 KB of RAM. I believe you are applauding now; thank you!
00:17:36.800 In Case 2, we will compile a slightly larger script. Here are the results of that script: MRBC used about 53 KB, while MMRBC used significantly less. This suggests that MMRBC has good potential to run on one-chip microcontrollers. However, at the same time, I think I still need to improve memory efficiency. The script from Case 2 also demonstrates the syntax MMRBC can support, including assignments, constants, method calls with parenthesized arguments, arrays, hash literals, symbol strings, and keywords, such as 'true' and 'interpolation' of strings.
00:18:48.960 My compiler can compile this syntax as it stands now, although I still have a lot to do, to be honest. Please check this roadmap if you are interested. I will conclude my talk by showing a code size comparison. These are the application codes called files that I demonstrated at the beginning of this presentation. You can use the `size` command to estimate how much ROM will be consumed, focusing on sections like the text and data sections, which comprise the machine code. These sections contain variables that have initial values. The BSS section indicates RAM size, so the total of text and data will indicate ROM consumption. It appears I still have some margin to implement more syntax for the PSoC 5LP, which has 256 KB of ROM. Here is the summary of my talk.
00:20:35.040 First, MMRBC is a Mini MRuby Compiler. The VM code generated by the compiler runs on both the ML Ruby VM and MRBC VM. While it is still incomplete in terms of syntax and memory efficiency, the MRuby machine integrates MMRBC, MRBC, shells, and hardware drivers. I hope the discussion regarding shells and peripheral drivers will serve as a topic for our next meeting. That's all for today. Thank you very much for listening! I always appreciate the RubyKaigi organizers. Thank you all.