Skip to content

Commit 0bd3f94

Browse files
harukasanclaude
andcommitted
Integrate PicoRuby VM to run Ruby scripts on RP2350
- Add PicoRuby submodule and cross-build config for Cortex-M33 - Rewrite main.c to initialize VM and run Ruby LED-blink task - Add HAL implementation (timer tick, I/O, stdin ringbuffer) - Add Rakefile for build automation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ca541ab commit 0bd3f94

13 files changed

Lines changed: 717 additions & 17 deletions

File tree

.editorconfig

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
charset = utf-8
7+
trim_trailing_whitespace = true
8+
9+
[*.{c,h}]
10+
indent_style = space
11+
indent_size = 2
12+
13+
[*.{rb,rake}]
14+
indent_style = space
15+
indent_size = 2
16+
17+
[CMakeLists.txt]
18+
indent_style = space
19+
indent_size = 2
20+
21+
[*.cmake]
22+
indent_style = space
23+
indent_size = 2
24+
25+
[*.{json,yml,yaml}]
26+
indent_style = space
27+
indent_size = 2
28+
29+
[Makefile]
30+
indent_style = tab
31+
32+
[Rakefile]
33+
indent_style = space
34+
indent_size = 2

.github/workflows/build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ jobs:
2020
submodules: recursive
2121
fetch-depth: 0
2222

23+
- name: Set up Ruby
24+
uses: ruby/setup-ruby@v1
25+
with:
26+
ruby-version: '4.0.1'
27+
2328
- name: Install ARM toolchain
2429
run: |
2530
sudo apt-get update

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.cache
22
build/
3+
lib/picoruby/build/
34

45
!.vscode/*

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "lib/pico-sdk"]
22
path = lib/pico-sdk
33
url = https://github.com/raspberrypi/pico-sdk.git
4+
[submodule "lib/picoruby"]
5+
path = lib/picoruby
6+
url = git@github.com:picoruby/picoruby.git

.vscode/launch.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
"request": "launch",
99
"type": "cortex-debug",
1010
"servertype": "openocd",
11-
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
12-
"gdbPath": "${command:raspberry-pi-pico.getGDBPath}",
11+
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
12+
"gdbPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb",
13+
"toolchainPrefix": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi",
1314
"device": "${command:raspberry-pi-pico.getChipUppercase}",
1415
"configFiles": [
1516
"interface/cmsis-dap.cfg",
@@ -35,7 +36,8 @@
3536
"type": "cortex-debug",
3637
"servertype": "external",
3738
"gdbTarget": "localhost:3333",
38-
"gdbPath": "${command:raspberry-pi-pico.getGDBPath}",
39+
"gdbPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb",
40+
"toolchainPrefix": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi",
3941
"device": "${command:raspberry-pi-pico.getChipUppercase}",
4042
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/${command:raspberry-pi-pico.getChip}/hardware_regs/${command:raspberry-pi-pico.getChipUppercase}.svd",
4143
"runToEntryPoint": "main",

CLAUDE.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# CLAUDE.md
2+
3+
## Project overview
4+
5+
Harucom OS is firmware for the Harucom Board (RP2350-based single-board computer).
6+
It runs Ruby scripts on mruby VM with DVI output, USB keyboard input, and a file system.
7+
8+
- Language: C (C11), with Ruby scripts executed on the embedded VM
9+
- Target: RP2350 (ARM Cortex-M33), built with pico-sdk
10+
- Build system: CMake, with a Rakefile wrapper for convenience
11+
12+
## Build commands
13+
14+
```sh
15+
rake # configure + build (default)
16+
rake clean # remove build/
17+
rake distclean # remove build/ and PicoRuby build
18+
```
19+
20+
## Code style
21+
22+
- Follow `.editorconfig` for indentation and whitespace rules
23+
- Use C11, K&R brace style
24+
- Keep HAL functions prefixed with `hal_` or `mrb_hal_`
25+
26+
## Commit messages
27+
28+
- First line: summary of the change
29+
- Following lines: concise bullet points of what was done
30+
- Do not include trivial accompanying changes (e.g. license additions, formatting fixes)

CMakeLists.txt

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,97 @@ message(STATUS "harucom_os version: ${HARUCOM_VERSION} (${HARUCOM_BUILD_DATE})")
6464
# Initialise the Raspberry Pi Pico SDK
6565
pico_sdk_init()
6666

67-
add_executable(harucom_os src/main.c)
67+
# --- PicoRuby ---
68+
set(PICORUBY_ROOT ${CMAKE_CURRENT_LIST_DIR}/lib/picoruby)
69+
set(PICORUBY_BUILD_CONFIG harucom-os-pico2)
70+
71+
# Build libmruby.a
72+
add_custom_command(
73+
OUTPUT ${PICORUBY_ROOT}/build/${PICORUBY_BUILD_CONFIG}/lib/libmruby.a
74+
COMMAND rake MRUBY_CONFIG=${CMAKE_CURRENT_LIST_DIR}/build_config/${PICORUBY_BUILD_CONFIG}.rb
75+
WORKING_DIRECTORY ${PICORUBY_ROOT}
76+
COMMENT "Building PicoRuby (libmruby.a)..."
77+
)
78+
79+
add_custom_target(build_picoruby
80+
DEPENDS ${PICORUBY_ROOT}/build/${PICORUBY_BUILD_CONFIG}/lib/libmruby.a
81+
)
82+
83+
add_library(mruby STATIC IMPORTED)
84+
set_target_properties(mruby PROPERTIES
85+
IMPORTED_LOCATION ${PICORUBY_ROOT}/build/${PICORUBY_BUILD_CONFIG}/lib/libmruby.a
86+
)
87+
88+
# --- Executable ---
89+
add_executable(harucom_os
90+
src/main.c
91+
src/hal.c
92+
${PICORUBY_ROOT}/mrbgems/picoruby-gpio/ports/rp2040/gpio.c
93+
)
94+
95+
add_dependencies(harucom_os build_picoruby)
6896

6997
pico_set_program_name(harucom_os "harucom_os")
7098
pico_set_program_version(harucom_os "${HARUCOM_VERSION}")
7199

72-
set_target_properties(harucom_os PROPERTIES
73-
OUTPUT_NAME "harucom_os-${HARUCOM_VERSION}-${HARUCOM_BUILD_DATE}"
100+
set(HARUCOM_RELEASE_NAME "harucom_os-${HARUCOM_VERSION}-${HARUCOM_BUILD_DATE}")
101+
102+
target_compile_definitions(harucom_os PRIVATE
103+
HARUCOM_VERSION="${HARUCOM_VERSION}"
104+
HARUCOM_BUILD_DATE="${HARUCOM_BUILD_DATE}"
105+
PICO_RP2350=1
106+
PICORB_VM_MRUBY=1
107+
MRB_INT64=1
108+
MRB_32BIT=1
109+
PICORB_ALLOC_ESTALLOC=1
110+
PICORB_ALLOC_ALIGN=8
111+
MRB_USE_CUSTOM_RO_DATA_P=1
112+
MRB_LINK_TIME_RO_DATA_P=1
113+
MRB_TICK_UNIT=1
114+
MRB_TIMESLICE_TICK_COUNT=10
115+
MRB_USE_TASK_SCHEDULER=1
116+
NO_CLOCK_GETTIME=1
117+
NDEBUG=1
118+
)
119+
120+
target_compile_options(harucom_os PRIVATE -fshort-enums)
121+
122+
target_include_directories(harucom_os PRIVATE
123+
${CMAKE_CURRENT_LIST_DIR}/src
124+
${PICORUBY_ROOT}/include
125+
${PICORUBY_ROOT}/build/${PICORUBY_BUILD_CONFIG}/include
126+
${PICORUBY_ROOT}/mrbgems/picoruby-mruby/lib/mruby/include
127+
${PICORUBY_ROOT}/mrbgems/picoruby-mruby/include
128+
${PICORUBY_ROOT}/mrbgems/mruby-compiler2/include
129+
${PICORUBY_ROOT}/mrbgems/mruby-compiler2/lib/prism/include
130+
${PICORUBY_ROOT}/mrbgems/picoruby-gpio/include
131+
${PICORUBY_ROOT}/mrbgems/picoruby-mruby/lib/mruby/mrbgems/mruby-task/include
132+
${PICORUBY_ROOT}/mrbgems/picoruby-machine/include
133+
${PICORUBY_ROOT}/build/${PICORUBY_BUILD_CONFIG}/mrbgems
74134
)
75135

76136
# Enable UART output for debug
77137
pico_enable_stdio_uart(harucom_os 1)
78138
pico_enable_stdio_usb(harucom_os 1)
79139

80140
target_link_libraries(harucom_os
81-
pico_stdlib)
82-
83-
target_include_directories(harucom_os PRIVATE
84-
${CMAKE_CURRENT_LIST_DIR}/src
141+
pico_stdlib
142+
hardware_timer
143+
hardware_gpio
144+
mruby
85145
)
86146

87147
string(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--print-memory-usage")
88148

89149
pico_add_extra_outputs(harucom_os)
90150

151+
# Copy release artifacts with version-stamped names
152+
add_custom_command(TARGET harucom_os POST_BUILD
153+
COMMAND ${CMAKE_COMMAND} -E copy
154+
${CMAKE_BINARY_DIR}/harucom_os.elf
155+
${CMAKE_BINARY_DIR}/${HARUCOM_RELEASE_NAME}.elf
156+
COMMAND ${CMAKE_COMMAND} -E copy
157+
${CMAKE_BINARY_DIR}/harucom_os.uf2
158+
${CMAKE_BINARY_DIR}/${HARUCOM_RELEASE_NAME}.uf2
159+
COMMENT "Creating release files: ${HARUCOM_RELEASE_NAME}.{elf,uf2}"
160+
)

CREDITS.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,30 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSE
3232
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3333
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3434
```
35+
36+
## PicoRuby
37+
38+
- Repository: https://github.com/picoruby/picoruby
39+
- License: MIT
40+
41+
```
42+
Copyright © 2020 HASUMI Hitoshi
43+
44+
Permission is hereby granted, free of charge, to any person obtaining a
45+
copy of this software and associated documentation files (the "Software"),
46+
to deal in the Software without restriction, including without limitation
47+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
48+
and/or sell copies of the Software, and to permit persons to whom the
49+
Software is furnished to do so, subject to the following conditions:
50+
51+
The above copyright notice and this permission notice shall be included in
52+
all copies or substantial portions of the Software.
53+
54+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
59+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
60+
DEALINGS IN THE SOFTWARE.
61+
```

Rakefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
PROJECT_DIR = __dir__
2+
BUILD_DIR = File.join(PROJECT_DIR, "build")
3+
4+
def nproc
5+
require "etc"
6+
Etc.nprocessors
7+
end
8+
9+
desc "Configure and build (default)"
10+
task default: :uf2
11+
12+
desc "Run cmake configure"
13+
task :configure do
14+
sh "cmake -B #{BUILD_DIR}"
15+
end
16+
17+
desc "Build firmware"
18+
task build: :configure do
19+
sh "cmake --build #{BUILD_DIR} -j#{nproc}"
20+
end
21+
22+
desc "Build UF2"
23+
task uf2: :build
24+
25+
desc "Flash firmware via picotool"
26+
task flash: :uf2 do
27+
uf2 = Dir.glob(File.join(BUILD_DIR, "*.uf2")).first
28+
abort "UF2 not found in #{BUILD_DIR}" unless uf2
29+
sh "picotool load -f #{uf2}"
30+
end
31+
32+
desc "Clean build directory"
33+
task :clean do
34+
rm_rf BUILD_DIR
35+
end
36+
37+
desc "Clean PicoRuby build"
38+
task :clean_picoruby do
39+
picoruby_build = File.join(PROJECT_DIR, "lib", "picoruby", "build")
40+
rm_rf picoruby_build
41+
end
42+
43+
desc "Clean everything"
44+
task distclean: [:clean, :clean_picoruby]

build_config/harucom-os-pico2.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
MRuby::CrossBuild.new("harucom-os-pico2") do |conf|
2+
3+
conf.toolchain("gcc")
4+
5+
conf.cc.defines << "MRB_TICK_UNIT=1"
6+
conf.cc.defines << "MRB_TIMESLICE_TICK_COUNT=10"
7+
8+
conf.cc.defines << "MRB_INT64"
9+
conf.cc.defines << "MRB_32BIT"
10+
conf.cc.defines << "PICORB_ALLOC_ESTALLOC"
11+
conf.cc.defines << "PICORB_ALLOC_ALIGN=8"
12+
conf.cc.defines << "MRB_USE_CUSTOM_RO_DATA_P"
13+
conf.cc.defines << "MRB_LINK_TIME_RO_DATA_P"
14+
conf.cc.defines << "NO_CLOCK_GETTIME=1"
15+
16+
conf.cc.command = "arm-none-eabi-gcc"
17+
conf.linker.command = "arm-none-eabi-ld"
18+
conf.linker.flags << "-static"
19+
conf.archiver.command = "arm-none-eabi-ar"
20+
21+
conf.cc.host_command = "gcc"
22+
23+
conf.cc.flags.flatten!
24+
conf.cc.flags << "-mcpu=cortex-m33"
25+
conf.cc.flags << "-mthumb"
26+
27+
conf.cc.flags << "-fno-strict-aliasing"
28+
conf.cc.flags << "-fno-unroll-loops"
29+
conf.cc.flags << "-mslow-flash-data"
30+
31+
conf.cc.flags << "-fshort-enums"
32+
33+
conf.cc.flags << "-Wall"
34+
conf.cc.flags << "-Wno-format"
35+
conf.cc.flags << "-Wno-unused-function"
36+
conf.cc.flags << "-ffunction-sections"
37+
conf.cc.flags << "-fdata-sections"
38+
39+
conf.microruby
40+
41+
conf.gembox "minimum"
42+
conf.gem core: 'picoruby-gpio'
43+
end

0 commit comments

Comments
 (0)