rpremote 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.ja.md +17 -3
- data/README.md +17 -3
- data/RELEASING.md +2 -2
- data/THIRD_PARTY_NOTICES.md +4 -0
- data/lib/rpremote/bootsel_command.rb +124 -0
- data/lib/rpremote/cli.rb +52 -9
- data/lib/rpremote/config.rb +2 -0
- data/lib/rpremote/deploy_command.rb +191 -0
- data/lib/rpremote/dfu_command.rb +65 -3
- data/lib/rpremote/flash_command.rb +4 -1
- data/lib/rpremote/flasher.rb +49 -11
- data/lib/rpremote/help.rb +64 -11
- data/lib/rpremote/mrbgems.rb +41 -12
- data/lib/rpremote/nuke_firmware.rb +71 -0
- data/lib/rpremote/picoruby_source_patch.rb +23 -6
- data/lib/rpremote/recursive_copy.rb +84 -0
- data/lib/rpremote/runner.rb +33 -6
- data/lib/rpremote/setup_command.rb +4 -1
- data/lib/rpremote/shell.rb +9 -5
- data/lib/rpremote/terminal.rb +13 -1
- data/lib/rpremote/version.rb +1 -1
- data/lib/rpremote.rb +4 -0
- data/patches/picoruby-3.4.5-bootsel.patch +71 -0
- data/patches/picoruby-4.0.3-bootsel.patch +71 -0
- data/sig/rpremote.rbs +50 -2
- metadata +7 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rpremote
|
|
4
|
+
class RecursiveCopy
|
|
5
|
+
def initialize(output:, serial: Serial, device: Device)
|
|
6
|
+
@output = output
|
|
7
|
+
@serial = serial
|
|
8
|
+
@device = device
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(source, destination, options)
|
|
12
|
+
validate!(source, destination)
|
|
13
|
+
remote_root = RemotePath.validate(destination)
|
|
14
|
+
directories, files = collect(source, remote_root)
|
|
15
|
+
create_directories(directories, options)
|
|
16
|
+
upload_files(files, options)
|
|
17
|
+
output.puts("uploaded #{files.length} files: #{source} -> #{destination}")
|
|
18
|
+
rescue Errno::ENOENT => e
|
|
19
|
+
raise ArgumentError, e.message
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
attr_reader :output, :serial, :device
|
|
25
|
+
|
|
26
|
+
def validate!(source, destination)
|
|
27
|
+
raise ArgumentError, "recursive cp only supports a local source and remote destination" if RemotePath.remote?(source)
|
|
28
|
+
raise ArgumentError, "recursive cp source must be a directory: #{source}" unless File.directory?(source)
|
|
29
|
+
|
|
30
|
+
RemotePath.validate(destination)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def collect(source, remote_root)
|
|
34
|
+
directories = [remote_root]
|
|
35
|
+
files = []
|
|
36
|
+
local_entries(source).each do |path|
|
|
37
|
+
remote_path = File.join(remote_root, path.delete_prefix("#{source}/"))
|
|
38
|
+
File.directory?(path) ? directories << remote_path : files << [path, remote_path]
|
|
39
|
+
end
|
|
40
|
+
[directories.sort_by { |path| [path.count("/"), path] }.uniq, files.sort]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def local_entries(source)
|
|
44
|
+
entries = Dir.glob(File.join(source, "**", "*"), File::FNM_DOTMATCH).reject do |path|
|
|
45
|
+
%w[. ..].include?(File.basename(path))
|
|
46
|
+
end
|
|
47
|
+
symbolic_link = entries.find { |path| File.symlink?(path) }
|
|
48
|
+
raise ArgumentError, "recursive cp does not support symbolic links: #{symbolic_link}" if symbolic_link
|
|
49
|
+
|
|
50
|
+
entries
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def create_directories(directories, options)
|
|
54
|
+
with_port(options) do |port|
|
|
55
|
+
shell = Shell.new(port, timeout: options[:timeout])
|
|
56
|
+
shell.synchronize!
|
|
57
|
+
directories.each do |path|
|
|
58
|
+
quoted_path = Shell.quote_argument(path)
|
|
59
|
+
next unless shell.execute("ls #{quoted_path}").start_with?("ls:")
|
|
60
|
+
|
|
61
|
+
result = shell.execute("mkdir #{quoted_path}")
|
|
62
|
+
raise Shell::CommandError, result.strip unless result.empty?
|
|
63
|
+
|
|
64
|
+
output.puts("created remote directory: :#{path}")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def upload_files(files, options)
|
|
70
|
+
with_port(options) do |port|
|
|
71
|
+
modem = PicoModem.new(port, timeout: options[:timeout])
|
|
72
|
+
files.each do |local_path, remote_path|
|
|
73
|
+
size = modem.upload(remote_path, File.binread(local_path))
|
|
74
|
+
output.puts("uploaded #{size} bytes: #{local_path} -> :#{remote_path}")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def with_port(options, &)
|
|
80
|
+
port_path = device.main_port(options[:port])
|
|
81
|
+
serial.open(port_path, baud: options[:baud], &)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
data/lib/rpremote/runner.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module Rpremote
|
|
4
4
|
class Runner
|
|
5
5
|
REMOTE_DIRECTORY = "/home"
|
|
6
|
+
RUN_REMOTE_PATH = "#{REMOTE_DIRECTORY}/.rpremote-run.rb".freeze
|
|
7
|
+
DEPLOY_REMOTE_PATH = "#{REMOTE_DIRECTORY}/.rpremote-deploy.rb".freeze
|
|
6
8
|
|
|
7
9
|
attr_reader :io, :timeout
|
|
8
10
|
|
|
@@ -20,16 +22,33 @@ module Rpremote
|
|
|
20
22
|
@path_factory = path_factory || method(:temporary_path)
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
def run(data, output: nil)
|
|
24
|
-
remote_path
|
|
25
|
+
def run(data, output: nil, cleanup: true, remote_path: nil, diagnostics: nil)
|
|
26
|
+
remote_path ||= @path_factory.call
|
|
25
27
|
shell = @shell_class.new(io, timeout: timeout)
|
|
28
|
+
trace(diagnostics, "SYNC_BEFORE_UPLOAD_START")
|
|
26
29
|
shell.synchronize!
|
|
30
|
+
trace(diagnostics, "SYNC_BEFORE_UPLOAD_DONE")
|
|
31
|
+
trace(diagnostics, "UPLOAD_START", "bytes=#{data.bytesize},path=#{remote_path}")
|
|
27
32
|
@modem_class.new(io, timeout: timeout).upload(remote_path, data)
|
|
33
|
+
trace(diagnostics, "UPLOAD_DONE")
|
|
34
|
+
trace(diagnostics, "SYNC_BEFORE_RUN_START")
|
|
28
35
|
shell.synchronize!
|
|
36
|
+
trace(diagnostics, "SYNC_BEFORE_RUN_DONE")
|
|
29
37
|
shell_ready = true
|
|
30
|
-
|
|
38
|
+
command = "./#{File.basename(remote_path)}"
|
|
39
|
+
trace(diagnostics, "EXECUTE_START", "command=#{command}")
|
|
40
|
+
result = output ? shell.execute(command, output: output, idle_timeout: true) : shell.execute(command, idle_timeout: true)
|
|
41
|
+
trace(diagnostics, "EXECUTE_DONE", "bytes=#{result.to_s.bytesize}")
|
|
42
|
+
result
|
|
43
|
+
rescue StandardError => e
|
|
44
|
+
trace(diagnostics, "ERROR", "class=#{e.class},message=#{e.message.to_s.gsub("\n", " ")}")
|
|
45
|
+
raise
|
|
31
46
|
ensure
|
|
32
|
-
cleanup
|
|
47
|
+
if cleanup && shell_ready && remote_path
|
|
48
|
+
trace(diagnostics, "CLEANUP_START", "path=#{remote_path}")
|
|
49
|
+
cleanup(shell, remote_path)
|
|
50
|
+
trace(diagnostics, "CLEANUP_DONE")
|
|
51
|
+
end
|
|
33
52
|
end
|
|
34
53
|
|
|
35
54
|
private
|
|
@@ -40,9 +59,17 @@ module Rpremote
|
|
|
40
59
|
nil
|
|
41
60
|
end
|
|
42
61
|
|
|
62
|
+
def trace(diagnostics, event, details = nil)
|
|
63
|
+
return unless diagnostics
|
|
64
|
+
|
|
65
|
+
line = "rpremote: run event=#{event}"
|
|
66
|
+
line += ",#{details}" if details
|
|
67
|
+
diagnostics.puts(line)
|
|
68
|
+
diagnostics.flush if diagnostics.respond_to?(:flush)
|
|
69
|
+
end
|
|
70
|
+
|
|
43
71
|
def temporary_path
|
|
44
|
-
|
|
45
|
-
"#{REMOTE_DIRECTORY}/.rpremote-run-#{Process.pid}-#{stamp}.rb"
|
|
72
|
+
RUN_REMOTE_PATH
|
|
46
73
|
end
|
|
47
74
|
end
|
|
48
75
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "optparse"
|
|
4
|
+
require_relative "nuke_firmware"
|
|
4
5
|
|
|
5
6
|
module Rpremote
|
|
6
7
|
class SetupCommand
|
|
7
|
-
def self.run(args, defaults:, config:, config_filename:, output: $stdout)
|
|
8
|
+
def self.run(args, defaults:, config:, config_filename:, output: $stdout, nuke_firmware: NukeFirmware)
|
|
8
9
|
options = {
|
|
9
10
|
force: false,
|
|
10
11
|
cache_dir: defaults.fetch(:cache, Target::DEFAULT_CACHE_DIR),
|
|
@@ -29,6 +30,8 @@ module Rpremote
|
|
|
29
30
|
cache_dir: target.cache_dir
|
|
30
31
|
).setup(force: options[:force])
|
|
31
32
|
output.puts("installed #{target.language} #{target.language_version}: #{path}")
|
|
33
|
+
nuke_path = nuke_firmware.new.setup(force: options[:force])
|
|
34
|
+
output.puts("installed Raspberry Pi nuke firmware: #{nuke_path}")
|
|
32
35
|
end
|
|
33
36
|
end
|
|
34
37
|
end
|
data/lib/rpremote/shell.rb
CHANGED
|
@@ -29,11 +29,12 @@ module Rpremote
|
|
|
29
29
|
|
|
30
30
|
attr_reader :io, :timeout
|
|
31
31
|
|
|
32
|
-
def initialize(io, timeout: DEFAULT_TIMEOUT)
|
|
32
|
+
def initialize(io, timeout: DEFAULT_TIMEOUT, clock: nil)
|
|
33
33
|
raise ArgumentError, "timeout must be positive" unless timeout.positive?
|
|
34
34
|
|
|
35
35
|
@io = io
|
|
36
36
|
@timeout = timeout
|
|
37
|
+
@clock = clock || -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) }
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
def synchronize!
|
|
@@ -43,12 +44,14 @@ module Rpremote
|
|
|
43
44
|
nil
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
def execute(command, output: nil)
|
|
47
|
+
def execute(command, output: nil, idle_timeout: false)
|
|
47
48
|
command = validate_command(command)
|
|
48
49
|
send_command(command)
|
|
49
50
|
echo = ECHO_START + command.b + ERASE_LINE
|
|
50
51
|
stream_state = {}
|
|
51
|
-
response = read_until_prompt(after: echo)
|
|
52
|
+
response = read_until_prompt(after: echo, idle_timeout: idle_timeout) do |buffer|
|
|
53
|
+
stream_output(output, buffer, echo, stream_state)
|
|
54
|
+
end
|
|
52
55
|
command_output = extract_output(response, command)
|
|
53
56
|
ruby_exception = command_output.include?(RUBY_EXCEPTION_STATUS)
|
|
54
57
|
command_output = remove_ruby_exception_status(command_output)
|
|
@@ -76,7 +79,7 @@ module Rpremote
|
|
|
76
79
|
command
|
|
77
80
|
end
|
|
78
81
|
|
|
79
|
-
def read_until_prompt(wait: timeout, after: nil)
|
|
82
|
+
def read_until_prompt(wait: timeout, after: nil, idle_timeout: false)
|
|
80
83
|
deadline = monotonic_time + wait
|
|
81
84
|
buffer = +"".b
|
|
82
85
|
loop do
|
|
@@ -85,6 +88,7 @@ module Rpremote
|
|
|
85
88
|
return buffer if prompt_at && buffer.index(PROMPT_END, prompt_at + PROMPT_START.bytesize)
|
|
86
89
|
|
|
87
90
|
buffer << read_available(deadline)
|
|
91
|
+
deadline = monotonic_time + wait if idle_timeout
|
|
88
92
|
answer_terminal_queries(buffer)
|
|
89
93
|
yield buffer if block_given?
|
|
90
94
|
end
|
|
@@ -186,7 +190,7 @@ module Rpremote
|
|
|
186
190
|
end
|
|
187
191
|
|
|
188
192
|
def monotonic_time
|
|
189
|
-
|
|
193
|
+
@clock.call
|
|
190
194
|
end
|
|
191
195
|
end
|
|
192
196
|
end
|
data/lib/rpremote/terminal.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Rpremote
|
|
|
49
49
|
data = serial_io.read_nonblock(BUFFER_SIZE)
|
|
50
50
|
return false if data.nil? || data.empty?
|
|
51
51
|
|
|
52
|
-
output.write(data)
|
|
52
|
+
output.write(normalize_line_endings(data))
|
|
53
53
|
output.flush if output.respond_to?(:flush)
|
|
54
54
|
true
|
|
55
55
|
else
|
|
@@ -75,6 +75,18 @@ module Rpremote
|
|
|
75
75
|
true
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
# input.raw disables the terminal's usual LF-to-CRLF output conversion.
|
|
79
|
+
# Preserve device CRLF while making a bare LF start at the left margin.
|
|
80
|
+
def normalize_line_endings(data)
|
|
81
|
+
normalized = +"".b
|
|
82
|
+
data.each_byte do |byte|
|
|
83
|
+
normalized << "\r" if byte == 0x0A && !@previous_output_was_cr
|
|
84
|
+
normalized << byte
|
|
85
|
+
@previous_output_was_cr = byte == 0x0D
|
|
86
|
+
end
|
|
87
|
+
normalized
|
|
88
|
+
end
|
|
89
|
+
|
|
78
90
|
def selectable_serial
|
|
79
91
|
@selectable_serial ||= serial_io.respond_to?(:to_io) ? serial_io.to_io : serial_io
|
|
80
92
|
end
|
data/lib/rpremote/version.rb
CHANGED
data/lib/rpremote.rb
CHANGED
|
@@ -19,8 +19,10 @@ require_relative "rpremote/terminal"
|
|
|
19
19
|
require_relative "rpremote/shell"
|
|
20
20
|
require_relative "rpremote/runner"
|
|
21
21
|
require_relative "rpremote/resetter"
|
|
22
|
+
require_relative "rpremote/recursive_copy"
|
|
22
23
|
require_relative "rpremote/picoruby_source_patch"
|
|
23
24
|
require_relative "rpremote/language_source"
|
|
25
|
+
require_relative "rpremote/nuke_firmware"
|
|
24
26
|
require_relative "rpremote/mrbgems"
|
|
25
27
|
require_relative "rpremote/mrbgems_command"
|
|
26
28
|
require_relative "rpremote/flasher"
|
|
@@ -29,3 +31,5 @@ require_relative "rpremote/dfu_command"
|
|
|
29
31
|
require_relative "rpremote/setup_command"
|
|
30
32
|
require_relative "rpremote/build_command"
|
|
31
33
|
require_relative "rpremote/flash_command"
|
|
34
|
+
require_relative "rpremote/bootsel_command"
|
|
35
|
+
require_relative "rpremote/deploy_command"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
diff --git a/mrbgems/picoruby-machine/include/machine.h b/mrbgems/picoruby-machine/include/machine.h
|
|
2
|
+
--- a/mrbgems/picoruby-machine/include/machine.h
|
|
3
|
+
+++ b/mrbgems/picoruby-machine/include/machine.h
|
|
4
|
+
@@ -48,1 +48,2 @@
|
|
5
|
+
void Machine_reboot(void);
|
|
6
|
+
+void Machine_bootsel(void);
|
|
7
|
+
diff --git a/mrbgems/picoruby-machine/mrblib/machine.rb b/mrbgems/picoruby-machine/mrblib/machine.rb
|
|
8
|
+
--- a/mrbgems/picoruby-machine/mrblib/machine.rb
|
|
9
|
+
+++ b/mrbgems/picoruby-machine/mrblib/machine.rb
|
|
10
|
+
@@ -22,0 +23,4 @@
|
|
11
|
+
+ def self.bootsel
|
|
12
|
+
+ self._bootsel
|
|
13
|
+
+ end
|
|
14
|
+
+
|
|
15
|
+
diff --git a/mrbgems/picoruby-machine/ports/rp2040/machine.c b/mrbgems/picoruby-machine/ports/rp2040/machine.c
|
|
16
|
+
--- a/mrbgems/picoruby-machine/ports/rp2040/machine.c
|
|
17
|
+
+++ b/mrbgems/picoruby-machine/ports/rp2040/machine.c
|
|
18
|
+
@@ -12,0 +13,1 @@
|
|
19
|
+
+#include "pico/bootrom.h"
|
|
20
|
+
@@ -32,0 +34,6 @@
|
|
21
|
+
+void
|
|
22
|
+
+Machine_bootsel(void)
|
|
23
|
+
+{
|
|
24
|
+
+ rom_reset_usb_boot(0, 0);
|
|
25
|
+
+}
|
|
26
|
+
+
|
|
27
|
+
diff --git a/mrbgems/picoruby-machine/src/mruby/machine.c b/mrbgems/picoruby-machine/src/mruby/machine.c
|
|
28
|
+
--- a/mrbgems/picoruby-machine/src/mruby/machine.c
|
|
29
|
+
+++ b/mrbgems/picoruby-machine/src/mruby/machine.c
|
|
30
|
+
@@ -417,0 +418,11 @@
|
|
31
|
+
+static mrb_value
|
|
32
|
+
+mrb_s__bootsel(mrb_state *mrb, mrb_value self)
|
|
33
|
+
+{
|
|
34
|
+
+#if !defined(PICORB_PLATFORM_POSIX)
|
|
35
|
+
+ Machine_bootsel();
|
|
36
|
+
+#else
|
|
37
|
+
+ mrb_raise(mrb, E_NOTIMP_ERROR, "Machine._bootsel is not available on this platform");
|
|
38
|
+
+#endif
|
|
39
|
+
+ return mrb_nil_value();
|
|
40
|
+
+}
|
|
41
|
+
+
|
|
42
|
+
@@ -443,0 +455,1 @@
|
|
43
|
+
+ mrb_define_class_method_id(mrb, module_Machine, MRB_SYM(_bootsel), mrb_s__bootsel, MRB_ARGS_NONE());
|
|
44
|
+
diff --git a/mrbgems/picoruby-machine/src/mrubyc/machine.c b/mrbgems/picoruby-machine/src/mrubyc/machine.c
|
|
45
|
+
--- a/mrbgems/picoruby-machine/src/mrubyc/machine.c
|
|
46
|
+
+++ b/mrbgems/picoruby-machine/src/mrubyc/machine.c
|
|
47
|
+
@@ -252,0 +253,11 @@
|
|
48
|
+
+static void
|
|
49
|
+
+c_Machine__bootsel(mrbc_vm *vm, mrbc_value *v, int argc)
|
|
50
|
+
+{
|
|
51
|
+
+#if !defined(PICORB_PLATFORM_POSIX)
|
|
52
|
+
+ Machine_bootsel();
|
|
53
|
+
+#else
|
|
54
|
+
+ mrbc_raise(vm, MRBC_CLASS(RuntimeError), "Machine.bootsel is not available on this platform.");
|
|
55
|
+
+#endif
|
|
56
|
+
+ SET_NIL_RETURN();
|
|
57
|
+
+}
|
|
58
|
+
+
|
|
59
|
+
@@ -439,0 +451,1 @@
|
|
60
|
+
+ mrbc_define_method(vm, module_Machine, "_bootsel", c_Machine__bootsel);
|
|
61
|
+
diff --git a/mrbgems/picoruby-shell/shell_executables/_path.txt b/mrbgems/picoruby-shell/shell_executables/_path.txt
|
|
62
|
+
--- a/mrbgems/picoruby-shell/shell_executables/_path.txt
|
|
63
|
+
+++ b/mrbgems/picoruby-shell/shell_executables/_path.txt
|
|
64
|
+
@@ -16,0 +17,1 @@
|
|
65
|
+
+/bin/bootsel
|
|
66
|
+
diff --git a/mrbgems/picoruby-shell/shell_executables/bootsel.rb b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
|
|
67
|
+
new file mode 100644
|
|
68
|
+
--- /dev/null
|
|
69
|
+
+++ b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
|
|
70
|
+
@@ -0,0 +1 @@
|
|
71
|
+
+Machine.bootsel
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
diff --git a/mrbgems/picoruby-machine/include/machine.h b/mrbgems/picoruby-machine/include/machine.h
|
|
2
|
+
--- a/mrbgems/picoruby-machine/include/machine.h
|
|
3
|
+
+++ b/mrbgems/picoruby-machine/include/machine.h
|
|
4
|
+
@@ -68,1 +68,2 @@
|
|
5
|
+
void Machine_reboot(void);
|
|
6
|
+
+void Machine_bootsel(void);
|
|
7
|
+
diff --git a/mrbgems/picoruby-machine/mrblib/machine.rb b/mrbgems/picoruby-machine/mrblib/machine.rb
|
|
8
|
+
--- a/mrbgems/picoruby-machine/mrblib/machine.rb
|
|
9
|
+
+++ b/mrbgems/picoruby-machine/mrblib/machine.rb
|
|
10
|
+
@@ -22,0 +23,4 @@
|
|
11
|
+
+ def self.bootsel
|
|
12
|
+
+ self._bootsel
|
|
13
|
+
+ end
|
|
14
|
+
+
|
|
15
|
+
diff --git a/mrbgems/picoruby-machine/ports/rp2040/machine.c b/mrbgems/picoruby-machine/ports/rp2040/machine.c
|
|
16
|
+
--- a/mrbgems/picoruby-machine/ports/rp2040/machine.c
|
|
17
|
+
+++ b/mrbgems/picoruby-machine/ports/rp2040/machine.c
|
|
18
|
+
@@ -10,0 +11,1 @@
|
|
19
|
+
+#include "pico/bootrom.h"
|
|
20
|
+
@@ -42,0 +44,6 @@
|
|
21
|
+
+void
|
|
22
|
+
+Machine_bootsel(void)
|
|
23
|
+
+{
|
|
24
|
+
+ rom_reset_usb_boot(0, 0);
|
|
25
|
+
+}
|
|
26
|
+
+
|
|
27
|
+
diff --git a/mrbgems/picoruby-machine/src/mruby/machine.c b/mrbgems/picoruby-machine/src/mruby/machine.c
|
|
28
|
+
--- a/mrbgems/picoruby-machine/src/mruby/machine.c
|
|
29
|
+
+++ b/mrbgems/picoruby-machine/src/mruby/machine.c
|
|
30
|
+
@@ -496,0 +497,11 @@
|
|
31
|
+
+static mrb_value
|
|
32
|
+
+mrb_s__bootsel(mrb_state *mrb, mrb_value self)
|
|
33
|
+
+{
|
|
34
|
+
+#if !defined(PICORB_PLATFORM_POSIX)
|
|
35
|
+
+ Machine_bootsel();
|
|
36
|
+
+#else
|
|
37
|
+
+ mrb_raise(mrb, E_NOTIMP_ERROR, "Machine._bootsel is not available on this platform");
|
|
38
|
+
+#endif
|
|
39
|
+
+ return mrb_nil_value();
|
|
40
|
+
+}
|
|
41
|
+
+
|
|
42
|
+
@@ -529,0 +541,1 @@
|
|
43
|
+
+ mrb_define_class_method_id(mrb, module_Machine, MRB_SYM(_bootsel), mrb_s__bootsel, MRB_ARGS_NONE());
|
|
44
|
+
diff --git a/mrbgems/picoruby-machine/src/mrubyc/machine.c b/mrbgems/picoruby-machine/src/mrubyc/machine.c
|
|
45
|
+
--- a/mrbgems/picoruby-machine/src/mrubyc/machine.c
|
|
46
|
+
+++ b/mrbgems/picoruby-machine/src/mrubyc/machine.c
|
|
47
|
+
@@ -316,0 +317,11 @@
|
|
48
|
+
+static void
|
|
49
|
+
+c_Machine__bootsel(mrbc_vm *vm, mrbc_value *v, int argc)
|
|
50
|
+
+{
|
|
51
|
+
+#if !defined(PICORB_PLATFORM_POSIX)
|
|
52
|
+
+ Machine_bootsel();
|
|
53
|
+
+#else
|
|
54
|
+
+ mrbc_raise(vm, MRBC_CLASS(RuntimeError), "Machine.bootsel is not available on this platform.");
|
|
55
|
+
+#endif
|
|
56
|
+
+ SET_NIL_RETURN();
|
|
57
|
+
+}
|
|
58
|
+
+
|
|
59
|
+
@@ -546,0 +558,1 @@
|
|
60
|
+
+ mrbc_define_method(vm, module_Machine, "_bootsel", c_Machine__bootsel);
|
|
61
|
+
diff --git a/mrbgems/picoruby-shell/shell_executables/_path.txt b/mrbgems/picoruby-shell/shell_executables/_path.txt
|
|
62
|
+
--- a/mrbgems/picoruby-shell/shell_executables/_path.txt
|
|
63
|
+
+++ b/mrbgems/picoruby-shell/shell_executables/_path.txt
|
|
64
|
+
@@ -17,0 +18,1 @@
|
|
65
|
+
+/bin/bootsel
|
|
66
|
+
diff --git a/mrbgems/picoruby-shell/shell_executables/bootsel.rb b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
|
|
67
|
+
new file mode 100644
|
|
68
|
+
--- /dev/null
|
|
69
|
+
+++ b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
|
|
70
|
+
@@ -0,0 +1 @@
|
|
71
|
+
+Machine.bootsel
|
data/sig/rpremote.rbs
CHANGED
|
@@ -166,6 +166,15 @@ module Rpremote
|
|
|
166
166
|
def source_dir: () -> String
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
+
class NukeFirmware
|
|
170
|
+
URL: String
|
|
171
|
+
FILENAME: String
|
|
172
|
+
MAX_REDIRECTS: Integer
|
|
173
|
+
|
|
174
|
+
def initialize: (?directory: String, ?fetcher: untyped) -> void
|
|
175
|
+
def setup: (?force: bool) -> String
|
|
176
|
+
end
|
|
177
|
+
|
|
169
178
|
class PicoRubySourcePatch
|
|
170
179
|
JOB_PATH: String
|
|
171
180
|
PATCH_ALIASES: Hash[String, String]
|
|
@@ -310,6 +319,11 @@ module Rpremote
|
|
|
310
319
|
def run: (String data, ?output: IO?) -> String
|
|
311
320
|
end
|
|
312
321
|
|
|
322
|
+
class RecursiveCopy
|
|
323
|
+
def initialize: (output: IO, ?serial: untyped, ?device: untyped) -> void
|
|
324
|
+
def call: (String source, String destination, Hash[Symbol, untyped] options) -> void
|
|
325
|
+
end
|
|
326
|
+
|
|
313
327
|
class Resetter
|
|
314
328
|
DEFAULT_TIMEOUT: Float
|
|
315
329
|
RETRY_INTERVAL: Float
|
|
@@ -337,7 +351,7 @@ module Rpremote
|
|
|
337
351
|
class Result < Data
|
|
338
352
|
attr_reader mount: String
|
|
339
353
|
attr_reader destination: String
|
|
340
|
-
attr_reader port: String
|
|
354
|
+
attr_reader port: String?
|
|
341
355
|
end
|
|
342
356
|
|
|
343
357
|
class Error < Rpremote::Error
|
|
@@ -362,8 +376,10 @@ module Rpremote
|
|
|
362
376
|
?port_probe: untyped,
|
|
363
377
|
?sleeper: untyped
|
|
364
378
|
) -> void
|
|
365
|
-
def flash: (String uf2_path, ?mount: String?, ?port: String?) -> Result
|
|
379
|
+
def flash: (String uf2_path, ?mount: String?, ?port: String?, ?wait_for_port: bool) -> Result
|
|
366
380
|
def find_mount: (?String? explicit_mount) -> String
|
|
381
|
+
def find_mounted: (?String? explicit_mount) -> String?
|
|
382
|
+
def wait_for_mount: (?mount: String?) -> String
|
|
367
383
|
end
|
|
368
384
|
|
|
369
385
|
class DfuCommand
|
|
@@ -415,4 +431,36 @@ module Rpremote
|
|
|
415
431
|
?flasher: untyped
|
|
416
432
|
) -> void
|
|
417
433
|
end
|
|
434
|
+
|
|
435
|
+
class DeployCommand
|
|
436
|
+
def self.run: (
|
|
437
|
+
Array[String] args,
|
|
438
|
+
defaults: Hash[Symbol, untyped],
|
|
439
|
+
?output: IO,
|
|
440
|
+
?error: IO,
|
|
441
|
+
?services: Hash[Symbol, untyped]
|
|
442
|
+
) -> void
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
class BootselCommand
|
|
446
|
+
RESET_FLASH_FIRMWARE: String
|
|
447
|
+
|
|
448
|
+
class Error < Rpremote::Error
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def self.run: (
|
|
452
|
+
Array[String] args,
|
|
453
|
+
defaults: Hash[Symbol, untyped],
|
|
454
|
+
?output: IO,
|
|
455
|
+
?services: Hash[Symbol, untyped]
|
|
456
|
+
) -> void
|
|
457
|
+
def self.enter: (
|
|
458
|
+
mount: String?,
|
|
459
|
+
port: String?,
|
|
460
|
+
baud: Integer,
|
|
461
|
+
timeout: Numeric,
|
|
462
|
+
output: IO,
|
|
463
|
+
?services: Hash[Symbol, untyped]
|
|
464
|
+
) -> String
|
|
465
|
+
end
|
|
418
466
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rpremote
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ogom
|
|
@@ -26,12 +26,14 @@ files:
|
|
|
26
26
|
- THIRD_PARTY_NOTICES.md
|
|
27
27
|
- exe/rpremote
|
|
28
28
|
- lib/rpremote.rb
|
|
29
|
+
- lib/rpremote/bootsel_command.rb
|
|
29
30
|
- lib/rpremote/build_command.rb
|
|
30
31
|
- lib/rpremote/builder.rb
|
|
31
32
|
- lib/rpremote/checksum.rb
|
|
32
33
|
- lib/rpremote/cli.rb
|
|
33
34
|
- lib/rpremote/config.rb
|
|
34
35
|
- lib/rpremote/config_show.rb
|
|
36
|
+
- lib/rpremote/deploy_command.rb
|
|
35
37
|
- lib/rpremote/device.rb
|
|
36
38
|
- lib/rpremote/dfu_command.rb
|
|
37
39
|
- lib/rpremote/dfu_compiler.rb
|
|
@@ -42,8 +44,10 @@ files:
|
|
|
42
44
|
- lib/rpremote/language_source.rb
|
|
43
45
|
- lib/rpremote/mrbgems.rb
|
|
44
46
|
- lib/rpremote/mrbgems_command.rb
|
|
47
|
+
- lib/rpremote/nuke_firmware.rb
|
|
45
48
|
- lib/rpremote/picomodem.rb
|
|
46
49
|
- lib/rpremote/picoruby_source_patch.rb
|
|
50
|
+
- lib/rpremote/recursive_copy.rb
|
|
47
51
|
- lib/rpremote/remote_path.rb
|
|
48
52
|
- lib/rpremote/resetter.rb
|
|
49
53
|
- lib/rpremote/runner.rb
|
|
@@ -53,7 +57,9 @@ files:
|
|
|
53
57
|
- lib/rpremote/target.rb
|
|
54
58
|
- lib/rpremote/terminal.rb
|
|
55
59
|
- lib/rpremote/version.rb
|
|
60
|
+
- patches/picoruby-3.4.5-bootsel.patch
|
|
56
61
|
- patches/picoruby-3.4.5-ruby-exception-status.patch
|
|
62
|
+
- patches/picoruby-4.0.3-bootsel.patch
|
|
57
63
|
- patches/picoruby-4.0.3-ruby-exception-status.patch
|
|
58
64
|
- sig/rpremote.rbs
|
|
59
65
|
- tasks/firmware_build.rb
|