We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

ROM: the final frontier of mruby

00:00

Formal Metadata

Title
ROM: the final frontier of mruby
Title of Series
Number of Parts
66
Author
Contributors
License
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Memory is limited resource of physical devices. Although mruby is smaller than MRI, it’s not small enough for cheap and easily avaiable devices. But there is another frontier: ROM. Many boards has larger Flash ROM than RAM. However, Ruby is too dynamic to put into ROM just as it is. How can we use ROM to implement classes of Ruby, and how small can we make mruby? It’s a thirty-minutes mission to explore strange new worlds.
VideoconferencingCodeImplementationReal-time operating systemSystem programmingMusical ensemblePresentation of a groupCartesian coordinate systemImplementationMechanism designProjective planeSelf-organizationMikrocomputerReal-time operating systemSoftware developerBitKernel (computing)E-bookComputer animationJSONXML
Execution unitImplementationFormal languageGame controllerArmPeripheralCoprocessorAnalog-to-digital converterModul <Datentyp>Slide ruleStandard deviationMicrocontrollerWhiteboardImplementationServer (computing)Physical systemGame theoryRight angleFile formatXMLUMLComputer animation
JoystickCursor (computers)Electronic visual displayGame controllerWhiteboardComputer animation
Musical ensembleBEEPFormal languageMikrocomputerWeb browserComputer animation
Game controllerArmPeripheralCoprocessorAnalog-to-digital converterModul <Datentyp>CompilerCodeNon-volatile memoryEEPROMWikiFlash memoryBlock (periodic table)WhiteboardElectronic mailing listSocial classStandard deviationObject (grammar)String (computer science)Floating pointKernel (computing)Dylan <Programmiersprache>Run time (program lifecycle phase)Instance (computer science)Point (geometry)AerodynamicsCompilerSocial classType theoryOrder (biology)Physical systemStandard deviationProcess (computing)Position operatorBlock (periodic table)Different (Kate Ryan album)Power (physics)Flash memoryObject (grammar)MicrocontrollerMemory managementNeuroinformatikEPROMData storage deviceSinc functionMultiplication signExecution unitTask (computing)Formal languageScripting languagePerturbation theoryOcean currentChannel capacityMereologyElectronic mailing listBytecodeTheory of relativityWhiteboardFunctional (mathematics)Internet forumObject-oriented programmingInstance (computer science)Computer architectureNon-volatile memoryCodeFluid staticsMaxima and minimaPoint (geometry)Module (mathematics)Read-only memoryCoprocessorCharacteristic polynomialPeripheralCorrespondence (mathematics)Dynamical systemNormal (geometry)Compilation albumComputer programmingGoodness of fitString (computer science)Multi-core processorLine (geometry)Reading (process)Computer animation
Symbol tableSocial classObject (grammar)Variable (mathematics)Instance (computer science)StrutInheritance (object-oriented programming)Data structureModule (mathematics)String (computer science)IntegerObject (grammar)Data managementSocial classSymbol tableComputer programmingVariable (mathematics)Data structureTerm (mathematics)State of matterTable (information)Standard deviationOperator (mathematics)EmailNatural numberInstance (computer science)String (computer science)Numeral (linguistics)InformationDynamical systemRun time (program lifecycle phase)Order (biology)Pointer (computer programming)MathematicsXMLUMLComputer animation
ImplementationExpressionScripting languageOpen setString (computer science)Reading (process)Structural loadException handlingStatement (computer science)Computer programmingFunctional (mathematics)Cellular automatonProcess (computing)XMLUML
Social classMemory managementKernel (computing)BootingObject (grammar)Computer fontSymbol tableModule (mathematics)Open set
Symbol tableFunction (mathematics)Hash functionCodeNon-volatile memoryLogical constantVariable (mathematics)Data structureUniform resource locatorSymbol tableLink (knot theory)Hash functionLevel (video gaming)Computer fileSource codeOrder (biology)Key (cryptography)Formal languageFile formatScripting languagePerfect groupLinker (computing)String (computer science)Computer animation
Hash functionCodeNon-volatile memoryResultantDiagram
FeedbackCore dumpData structureStandard deviationScripting languageCodeObject (grammar)StrutFluid staticsFunction (mathematics)Computer fileAssociative propertyMusical ensembleMultilaterationSoftware developerRight angleData structureMathematicsScripting languageMeasurementResultantFeedbackFunctional (mathematics)Library (computing)Ocean currentNon-volatile memoryVariable (mathematics)Instance (computer science)Symbol tableArithmetic progressionError messageCodePoint (geometry)Fluid staticsDeclarative programmingFormal languageComputer fileHash functionMereologyStandard deviationProjective planeGoodness of fitImplementationReduction of orderElectronic mailing listElectric generatorDirectory serviceData managementRepository (publishing)Patch (Unix)XMLUML
Object (grammar)AerodynamicsMereologyWhiteboardWhiteboardObject (grammar)Social classSinc functionXMLUMLComputer animation
Coma BerenicesXMLUMLComputer animation
Transcript: English(auto-generated)
Before our talk, we would like to make some announcements. This presentation will be a little bit technical, and it's including C, Dazazan, Ruby. We want to explain the implementation of MLB and its implementation in C, so we must use C in this presentation.
What you do not need to know about the MLB, and she expects the details of the implementation. Let me introduce ourselves. I'm Yurie Ayamane.
And I'm Matayoshi Takahashi. We are Team Ayamane Corps. We have development of MLB applications and development for MLB. I am Yurie. I'm interested in microcomputer and real-time OS. I'm a member of Topaz Project.
Topaz Project make kernel for real-time OS and tools. I do development, demonstrations, and presentation at many exhibitions.
I'm an e-book publisher and a committer of e-book publishing tool called review. You can get it from RubyGems.org. I'm also a member of RubyKage organizer team. We will hold RubyKage 2019 in Fukuoka next April, so we hope you come and join us.
Okay, let's get into the main topic. The topic of this talk is MLB and ROM. First, we will briefly explain about MLB. MLB is an implementation of Ruby, like CRuby, JRuby, Luminance, and Opal.
It is also called lightweight Ruby. MLB is a very small implementation compared to CRuby and JRuby. It's compiled with the ISO standard of Ruby. MLB has made two target areas,
embedded systems and applications, such as server and games. We have focused the former embedded system. We have got many microcontroller boards and tried to use MLB on them.
In this talk, we show two devices. Left one of the slide is a Nucleo F401RU. There is an ARM Cortex M4 microcontroller in the board.
Right is M5 stack. It is a famous board in China and Japan. There is an ESP32 microcontroller on it.
This is a Nucleo board. The LCD has a joystick. You can see the cursor.
We move the cursor with this joystick controller.
Another microcomputer is M5 stack. This has a browser and three buttons. Let's play the music.
If you use Ruby or other languages only on PC, you might know microcontrollers. So let me explain about microcontrollers. Microcontrollers are like a small computer on a single chip. It contains a processor called MPU, RAM, DOM, a lot of paper, and other modules.
Microcontrollers are used in smartphones, home appliances, automobiles, and so on. Now back to MLB.
One of the differences between MLB and other rubies is the position of the bytecode. MLB's VM and compiler are completely separate, and you can execute MLB VM without compiler. In such a situation, you can use MLB files, which contain the bytecode for MLB.
When you use CRuby, you also use bytecode generated by CRuby, but it's not explicit. It's only used inside of the VM.
The current hot topic of MLB is 2.0. MLB 2.0 will be released soon. Maybe in the next month or so, according to the MLB forum. It's the first major update of MLB, and it introduces incompatibility.
Sorry, and it allows incompatibility. The architecture of bytecode is completely different, and you cannot use bytecode generated by 2.0 in MLB 1.4.
But it means that it's a good time to use MLB now. It's pretty far for 2.0 brand new MLB. Now, let's talk about LON. LON is an abbreviation of read-only memory.
It's also called non-bratile memory, because it's not released without power. There are various types of LON. The target here is EPRON. EPRON is an abbreviation for electronically erasable programmable read-only memory.
EPRON requires no power to hold data, but power is required to delete and register data. This picture is STM EPRON.
Flash-on or flash memory is a kind of EPRON. You can register on flash only in power block units, not per byte unit. You may use it as USB memory. Currently, microcontrollers usually use flash-on and main storage.
In summary, the relation between LON, EPRON, and flash is like this picture. A part of LON is EPRON and a part of its flash memory. But why are we focusing on LON?
The first reason is that LON can store more data than LON. In a microcontroller, LON capacity is usually less than LON capacity, especially in cheap boards. This is a list of microcontrollers that we have used.
The last item, Arduino Uno, was just as a difference. Arduino Uno is too small to use normal MRB. On the other boards, we have tried to use MRB. As you can see from this table, the lower the price, the smaller the LON capacity.
And except for expensive boards, you can see that the capacity of flash LON is rather than capacity of LON.
Why does a microcontroller have this LON? First of all, the reason is the cost. Microcontrollers tend to be used for devices with only a simple function. So that needs only a minimum amount of RAM. Another reason is the problem of power consumption.
LON requires power to hold data. This means that LON increases, the power consumption will increase. If I find an answer for the same question in stock exchange,
so please read this page as well. The second reason we focus on LON is that LUBE may consume RAM before execution.
What does before execution mean? For example, consider displaying hard work. A LUBE code is just on one line, but there are some things the processing system does in order to execute this line.
The first thing we need is memory initialization. Since LUBE uses GC for memory management, it corresponds to the initialization of GC and the initialization of heap memory used by GC. Another thing in initialization of standard classes,
whereas classes are used in LUBE, you need to prepare all the classes before running your LUBE script. It is a second task that becomes a problem.
The fact that standard class initialization is executed at this timing means that all the standard classes are placed in RAM. In other words, re-executing a LUBE program, RAM is always consumed to generate the standard class and object
in order to use various classes, some as object, class, kernel, numeric, standard, string, and so on. RAM is used even if you do not read a LUBE script line.
It is not good news for us. On the other hand, in other object-oriented languages, such as C++ and MicroPython, it does not seem to happen. Classes and method definitions can also be placed in RAM.
Why is there such a difference? That's because LUBE is a very dynamic language. As we all know, the characteristics of LUBE are dynamic. In LUBE, even in standard class, methods can be added, deleted, and redefined.
The LUBE class is also an ordinary object, called an instance of the class class. This wonderful feature of LUBE has become a serious problem in using LUBE on microcontroller.
Let me summarize the talk at this point. On embedded devices, we can use only a small amount of RAM. Therefore, we want to utilize RAM rather than RAM.
However, since LUBE is a dynamic language, even object, including standard classes, consume RAM is what we want to solve here. In other words, we want to solve the contradiction
between the dynamic language to be under static storage ROM. This talk goes a lot like LUBE object and its management.
LUBE is written in C, and so various data structures are defined as a structure in C.
For example, the entity of LUBE VM is a structure called MRB state in C. The MRB state holds main standard class objects as a member of the structures. The MRB class object is an R class structure in C.
The R class structure has members IV and members MT. In MRB, IV is an operation for the instance variable, and MT is an abbreviation for the method table.
The method table is a table of method as the name suggests. Each class manages a method that can be used in a class by a table. The instance variable of the class class contains internal data for managing class information. For example, the class name is stored here.
This is the definition of R class in C. Thus, IV and MT are in R class as IV TBL, and IV TBL structure and KTMT structure, respectively.
MRB object header is a common header of objects, and super is a pointer to super class. By the way, how do you use ROM and RAM properly? If you think in terms of modern programming language, you should consider ROM as immutable and RAM as immutable.
It's important here that members of immutable structures may be mutable, and on the contrary, members of mutable structures may be immutable. Regarding the use of ROM and RAM, it is as shown in this figure.
ROM is on the left and ROM is on the right. The state of the MRB state, that is, mvbn, changed at runtime, so need to be placed in ROM. But the class object itself can be placed in ROM.
However, the table that manages the instance variable and the table that manages the method is in ROM because it changes while executing. And even if the table of method is in ROM, certain method definitions can be placed in ROM.
As I mentioned earlier, method may be added at runtime. The added method will be put in ROM. Thus, if we understand how to use ROM and RAM well,
we can use ROM without changing the dynamic nature of Ruby. Now let's explain about the symbol table. The symbol table is a table related to name inside mv. Names such as class names and method names are managed as symbols.
The entity of the symbol class in Ruby is this symbol. The symbol table has numeric ID and string name. This symbol ID is used to manage method and classes inside mv.
Therefore, in order to put method and classes in ROM, the symbol table must be placed in ROM. In normal mv, the symbol table is also stored in RAM, so we need to change it here as well. In the expression so far, I think we were able to share our problem.
Let's think about an implementation to solve it. This is a small program to use mv to mv. It's just to show hello world. The function mv open here is the initialization of mv cell.
The next if statement is exception handling when initialization fails, and the next function mv load string lead and execute Ruby scripts
given as character strings like our put hello world. So it's mv open is the initialization process that we are targeting here. This is the outline of mv open. First, we initialize memory management and initialize the symbol table.
Next, we initialize basic classes such as class class, object class, and kernel module. Since basic class boot wrapping requires special work, it is separated from other general classes.
Then, the class definition written in C, the class definition written in Ruby, and the class definition by mv gems, which is Ruby gems for mv, are initialized. Let's consider how to put the symbol table in RAM.
To search for symbol names from a symbol ID, it would not be a problem with a simple array. In order to efficiently retrieve the symbol ID from symbol name, some ingenuity is necessary.
Here, we use gperf. Gperf is what is called a perfect hash function generator. Actually, it is also famous used in C Ruby. Please refer to this URL for the details usage.
How can we find symbols used in MLB? Here, we simply scan the MLB source code and extract the strings that are supposed to be symbols. The extracted symbols are stored in JSON format and converted to a key file for gperf by another script.
Then, convert it into C language source using gperf. Doing this makes it easier to edit symbols at the stage of JSON. Detecting methods also uses a similar method as detecting symbols, like this.
By the way, how can we arrange structure in C into RAM? An easy way is putting the const qualifier. Another way is preparing a special segment with linker script.
But if you do not need to do something complicated so far, const is enough. This is a code generated by gperf. In gperf, by generating static const like this,
we arrange an array of names and data used by hash function in RAM. Comparing the result of using RAM and not using it, memory usage is reduced by about 20%. However, there are places I have not done yet,
so I will try for further improvement. Future works. I will also explain what is currently under development and what we plan to develop later. There are three issues here.
Currently, we have tried to put ilap structure on RAM. In addition, we should support mruby 2.0 explained first. Furthermore, I would like to give feedback to the mruby repository as well.
First, I will explain the ilap structure. mruby-ilap is a structure for managing compiled Ruby script in mruby. The right side is a definition of a structure. Ruby scripts in standard library and mruby gems become ilap structures.
Since ilap are placed in RAM, we want to make them on RAM. We have an idea to put ilap on RAM that executing mruby open to generate ilap structures and dump them all as C language code.
While doing this, we can generate a JSON file for symbols at the same time. Since it's still on work in progress and the measurement method is different from the previous charts,
so we cannot compare them, but when we use RAM 3, we should reduce the RAM memory so much like this chart. In mruby 2.0, the implementation of instance variables seems to be changed significantly.
We should also make change for that. Left side is mruby 1.4 and right side is mruby 2.0. mruby 1.4 uses a hash structure, but mruby 2.0 uses a segmentary structure,
so we can fix this structure. Furthermore, for this method to be widely used, it's necessary to implement it without modifying mruby itself. Unfortunately, the current part cannot work without modifying mruby slightly.
For example, when implementing method of mruby in C, static declaration is given to some functions like this figure, like the figures. Therefore, even if you try to put a point to this function in ROM,
an error will occur at compile time. We'd like to ask Matt how fix to avoid this. And here is good news I'd like to tell you. This project was selected by Ruby Association Grand Committee.
We are very happy to be chosen. We will do our best to make a good result by all means. Thank you so much. Thank you. Okay, I summarize the talk.
RAM is small in embedded devices, so we want to make more use of RAM. On the other hand, since Ruby is a dynamic language, every class object can be mutable. But even if the object is mutable,
you can divide it into elements and put some of them in RAM. Let's use mruby on various boards. We have got a lot of opinions and cooperation for our work. We really appreciate them.
Thank you for coming and let's enjoy mruby.