Rabbit Slide Show

PicoRuby epsode 3

2022-11-10

Description

Presentation slide for RubyWorld Conference 2022

Text

Page: 1

pico
ruby
Episode Ⅲ
REVENGE OF THE STDIN
RubyWorld Conference 2022
hasumikin>&Monstarlab
Nov. 10, 2022

Page: 2

Episode Ⅱ
ATTACK OF THE RAKE
find on the internet

Page: 3

This slot has Q&A time
PicoRuby@SUZURI

Page: 4


        

Page: 5

PicoRuby: An alternative mruby
puts "Hello World"
mruby = mruby VM + mruby compiler
=> 136 KB
MicroRuby = mruby VM + PicoRuby compiler
=> 88 KB
PicoRuby = mruby/c VM + PicoRuby compiler
=> 11 KB
All measurement on 64-bit Ubuntu

Page: 6

PicoRuby: An alternative mruby
github.com/picoruby/picoruby

Page: 7

PRK Firmware: Keyboard firmware
Displayed in Large exhibition hall (1F)

Page: 8

PRK Firmware: Keyboard firmware
github.com/picoruby/prk_firmware

Page: 9

Raspberry Pi Pico
RP2040
Arm Cortex-M0+ (dual)
264 KB RAM
2 MB ROM
(RP2040 supports upto 16 MB)
$4~ (¥600~)
"Pi Pico W" supports WiFi
Got 技適 (new!)

Page: 10

demo

Page: 11

Serial port terminal emulator
Traditional CUI/TUI tools have fallen to
the dark side (apparently CR/LF issue)
cu
screen
minicom
Linux -> GTKTerm
Windows -> Tera Term? (not sure)
macOS -> PuTTY?

Page: 12

Summary: It's still a PoC, though...
An integrated Micon programming environment
Ruby compiler inside
Shell ready
Text editor equipped
Your own commands available
Accelerates developing an IoT system with Ruby

Page: 13

implementation

Page: 14

Command: builtin and executable
Builtin commands are implemented in shell
cd, echo, export, pwd, type, etc.
Executable commands are located in storage
cat, ls, rm, vim, etc.

Page: 15

Command: builtin
# picoruby/mrbgems/picoruby-shell/mrblib/command.rb
def exec(params)
args = params[1, params.length - 1]
case params[0]
when "echo"
_echo(*args)
when "type"
_type(*args)
when "pwd"
puts Dir.pwd
when "cd"
puts if Dir.chdir(args[0] || ENV['HOME']) != 0
when "free"
Object.memory_statistics.each do |k, v|
print "#{k.to_s.ljust(5)}: #{v.to_s.rjust(8)}", @feed
end

Page: 16

Command: executable
picoruby/mrbgems/picoruby-shell/
├─ mrbgem.rake
├─ mrblib
│
├─ command.rb
│
└─ shell.rb
├─ shell_executables
│
├─ cat.rb
│
├─ hello.rb
│
├─ ls.rb
│
├─ rm.rb
│
└─ vim.rb
└─ src
└─ shell.c
# Search path
ENV["PATH"] => ["/bin"]

Page: 17

Command: executable
You can write your own executable in PicoRuby
$ vim hello_ruby.rb
```
puts "Hello RubyWorld"
```
$ install hello_ruby.rb /bin/hello_ruby
$ hello_ruby
Hello RubyWorld

Page: 18

Filesystem
Computer has filesystem(s)
MS-DOS: Microsoft Disk Operating System
NTFS, ext{2,3,4}, etc.
Micon generally doesn't have a filesystem

Page: 19

FAT filesystem
File Allocation Table (FAT)
Developed by Microsoft along with MS-DOS
8-bit FAT, FAT12, FAT16, FAT32, exFAT
Under construction for Flash ROM
Today's demo is working on RAM disk

Page: 20

VFS (Virtual File System)
VFS-like system written in PicoRuby
Different devices and even different filesystems
can mount under the root
VFS.mount(FAT.new(:flash), "/")
"/ram")
VFS.mount(FAT.new(:ram),
VFS.mount(FAT.new(:sdcard), "/sdcard")
/
├─
├─
├─
│
├─
│
bin/
home/
ram/
└─ tmp/
sdcard/ # SPI not impemented yet
└─ data.sqlite

Page: 21

mruby's build system
mrbgems is a library management system for
mruby
You can freely host your own gem
Matz says it's an advanced one (than MicroPython?)
Bundled mgems are automatically loaded

Page: 22

mruby's build system
mruby
├─ Rakefile
├─ bin/
├─ build/
├─ build_config/
├─ include/
├─ lib/
│
└─ mruby/
# MRuby module
├─ mrbgems/
├─ mrblib/
├─ src/
├─ tasks/
│
├─
│
├─ mrbgems.rake
│
├─

Page: 23

PicoRuby's build system
picoruby
├─ Rakefile
├─ bin/
├─ build/
├─ build_config/
├─ include/
├─ lib/
│
├─ mruby/
│
└─ picoruby/
│
└─ build.rb
├─ mrbgems/
├─ mrblib/
├─ src/
├─ tasks/
│
├─
│
├─ mrbgems.rake
│
├─
│
├─ picogems.rake
│
├─
modified
# `module MRuby`
MRuby overridden
MRuby.each_target overridden

Page: 24

PicoRuby's build system
picoruby
├─ build/repos/host/
│
├─ mruby-bin-picorbc/
│
└─ mruby-pico-compiler/
├─
├─ mrbgems/
├─ default.gembox
├─ picoruby-bin-picoirb/
├─ picoruby-bin-picoruby/
├─ picoruby-bin-prsh/
├─ picoruby-filesystem-fat/
├─ picoruby-io/
├─ picoruby-mrubyc/
├─ picoruby-sandbox/
├─ picoruby-shell/
├─ picoruby-terminal/
├─ picoruby-vfs/
└─ picoruby-vim/
# picorbc
#
#
#
#
#
#
picoirb
picoruby
prsh [pəːrʃ]
FAT filesystem
io gem
mruby/c VM

Page: 25

PicoRuby's build system
# picoruby/mrbgems/default.gembox
MRuby::GemBox.new do |conf|
conf.gem github: 'picoruby/mruby-pico-compiler'
conf.gem github: 'picoruby/mruby-bin-picorbc'
conf.gem core: 'picoruby-bin-picoruby'
conf.gem core: 'picoruby-bin-picoirb'
conf.gem core: 'picoruby-mrubyc'
end
`mruby-pico-compiler` and `mruby-bin-picorbc`
can be bundled in mruby (MicroRuby)

Page: 26

A typical picogem
picoruby/
└─ mrbgems/picoruby-io/
├─ mrbgem.rake
├─ mrblib
│ └─ io.rb
└─ src/
├─ hal/
│ ├─ hal.h
│ └─ posix
│
└─ hal.c
└─ io.c

Page: 27

`require`
mruby doesn't have `require` out of the box
Neither does mruby/c
PicoRuby has introduced `require`
Bundled Picogem code already consumed ROM, but
It isn't loaded onto RAM automatically
Consumes RAM only after `require`

Page: 28

Making a PicoRuby app elegantly
CRuby code compatible with PicoRuby
PicoRuby for PC (MRBC_USE_HAL_POSIX)
Write minimum HAL for POSIX
Extend PicoRuby's builtin class if necessary
Keep the app code independent from Picoruby
Do not copy and paste files any longer

Page: 29

Keep the app code independent
example-IoT-app
├─ CMakeLists.txt
# Just link src/*.c and libmruby.a
├─ Rakefile
├─ build
│ ├─ ...
├─ include
│ ├─ ...
├─ lib
│ └─ picoruby
# libmruby.a created by `rake`
├─ mrblib
│ ├─ main_task.rb
│ └─ temperature_sensor_task.rb
├─ pico_sdk_import.cmake
└─ src
├─ hal.c
# Micon dependent hal
├─ temperature_sensor.c
├─ main.c
├─ ...

Page: 30

Compatible CRuby with PicoRuby
# picoruby-vim/mrblib/vim.rb
case RUBY_ENGINE
when "ruby", "jruby"
require_relative "../../picoruby-terminal/mrblib/terminal"
when "mruby/c"
require "terminal"
else
raise "Unknown RUBY_ENGINE: #{RUBY_ENGINE}"
end
class Vim
(...)
end

Page: 31

Compatible CRuby with PicoRuby
Run with CRuby on your PC, then
$ ruby -r./mrbgems/picoruby-vim/mrblib/vim.rb \
-e 'Vim.new("myfile.txt").start'
You can easily implement and debug
a "Pure" PicoRuby app with CRuby

Page: 32

demo

Page: 33

back to
implementation

Page: 34

Shell and text editor
Without Curses and Readline
Pure Ruby just like Reline (irb of CRuby3.0+)

Page: 35

Shell and text editor
Without Curses and Readline
Pure Ruby just like Reline (irb of CRuby3.0+)
STDIN confuses you

Page: 36

Standard INPUT
Cooked mode (by default on Unix-like OS)
Blocked until submit (recall Kernel#gets)
"a" "b" "c" "[BSPACE]" "d" "[ENTER]" => "abd"
Raw mode (obviously by default on bare metals)
Immediately receives any input
"a" "b" "c" "[BSPACE]" "d" => "abc[BSPACE]d"
Really confusing in making compatible code

Page: 37

Standard INPUT
static struct termios save_settings;
static int save_flags;
/* Turn into raw mode on Linux (Windows has another solution) */
struct termios settings;
tcgetattr(fileno(stdin), &save_settings);
settings = save_settings;
settings.c_iflag = ~(BRKINT | ISTRIP | IXON);
settings.c_lflag = ~(ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL);
settings.c_cc[VMIN] = 1;
settings.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSANOW, &settings);
save_flags = fcntl(fileno(stdin), F_GETFL, 0);
fcntl(fileno(stdin), F_SETFL, save_flags | O_NONBLOCK);
/* Turn back to cooked mode */
fcntl(fileno(stdin), F_SETFL, save_flags);
tcsetattr(fileno(stdin), TCSANOW, &save_settings);

Page: 38

Standard INPUT
# picoruby/mrbgems/picoruby-terminal/mrblib/terminal.rb
case RUBY_ENGINE
when "ruby", "jruby"
require "io/console"
def IO.get_nonblock(max)
STDIN.noecho{ |input| input.read_nonblock(max) }
rescue IO::EAGAINWaitReadable => e
nil
end
when "mruby/c"
require "io"
def IO.get_nonblock(max)
str = read_nonblock(max) # calls C implementation
str&.length == 0 ? nil : str
end
end

Page: 39

C object in RVALUE: mruby
#define MRB_VTYPE_FOREACH(f)
/* mrb_vtype */ /* c type
f(MRB_TT_FALSE,
void,
...
struct
f(MRB_TT_OBJECT,
...
struct
f(MRB_TT_DATA,
...
\
*/
/* ruby class */ \
"false") \
RObject, "Object") \
RData,
"Data") \ //
struct RData {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
const mrb_data_type *type;
void *data; //
You can pin any object here
};

Page: 40

C object in RVALUE: mruby/c
typedef struct RInstance {
MRBC_OBJECT_HEADER;
struct RClass *cls;
struct RKeyValueHandle ivar;
The last member can extend
uint8_t data[]; //
} mrbc_instance;
// File.new
mrbc_value obj = mrbc_instance_new(vm, v->cls, sizeof(FIL));
//
^^^^^^^^^^^
//
extend RVALUE
FIL *file_stream_ptr = (FIL *)obj.instance->data;
SET_RETURN(obj); // File.new => #<File:200098a0>
No need to `free(file_stream_ptr);`

Page: 41

Finally, the shell works

Page: 42

By the way,

Page: 43

How should I name
this product

Page: 44

Ruby on Raspberry Pi Pico

Page: 45

Ruby on Raspberry Pi Pico

Page: 46

r2-p2

Page: 47


        

Page: 48

r2-p2

Page: 49

“It is said that (account) names
should not contain
hyphens or underscores.”
[cited from `@kakutani']

Page: 50

r2-p2

Page: 51

r2p2

Page: 52

Be one the first stargazers of
github.com/picoruby/R2P2
(turned public repo today!)

Page: 53

Wrap-up
R2P2 is an all-in-one programming Micon

Page: 54

Wrap-up
R2P2 is an all-in-one programming Micon
Runs on Raspi Pico which has 264 KB RAM and
2 MB ROM

Page: 55

Wrap-up
R2P2 is an all-in-one programming Micon
Runs on Raspi Pico which has 264 KB RAM and
2 MB ROM
Picogem ecosystem easily builds your app

Page: 56

Wrap-up
R2P2 is an all-in-one programming Micon
Runs on Raspi Pico which has 264 KB RAM and
2 MB ROM
Picogem ecosystem easily builds your app
Filesystem ly makes you happy
Filesystem will make you happy

Page: 57

Wrap-up
R2P2 is an all-in-one programming Micon
Runs on Raspi Pico which has 264 KB RAM and
2 MB ROM
Picogem ecosystem easily builds your app
Filesystem will make you happy
STDIN is evil

Page: 58

Future work
PicoRuby and Shell
More functionality of vim and the name
UTF-8 support
Multi-task controll on the fly
Redirect and pipeline
Peripherals
FAT filesystem with SD card (SPI)
Real-time clock (RTC)
WiFi and TCP/IP on Raspberry Pi Pico W

Page: 59

q and a
github.com/picoruby/r2p2

Page: 60

may the
source
be with you

Other slides