Skip to content

Commit c7339fa

Browse files
committed
Add docs to Mix tasks
- mix help will now list the available atomvm task - mix doc will generate ex docs
1 parent cbd2fb6 commit c7339fa

File tree

10 files changed

+415
-90
lines changed

10 files changed

+415
-90
lines changed

README.md

Lines changed: 51 additions & 49 deletions
Large diffs are not rendered by default.

lib/ex_atom_vm.ex

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
defmodule ExAtomVM do
2-
@moduledoc """
3-
Documentation for ExAtomVM.
4-
"""
5-
6-
@doc """
7-
Hello world.
8-
9-
## Examples
10-
11-
iex> ExAtomVM.hello()
12-
:world
13-
14-
"""
15-
def hello do
16-
:world
17-
end
2+
@moduledoc "README.md"
3+
|> File.read!()
4+
|> String.split("<!-- MDOC !-->")
5+
|> Enum.fetch!(1)
186
end

lib/mix/tasks/check.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
defmodule Mix.Tasks.Atomvm.Check do
2+
@shortdoc "Check application code for use of unsupported instructions"
3+
24
alias Mix.Project
5+
use Mix.Task
36

47
def run(args) do
58
Mix.Tasks.Compile.run(args)
@@ -201,6 +204,7 @@ defmodule Mix.Tasks.Atomvm.Check do
201204
you must remove the parentheses: map.field
202205
""")
203206
end
207+
204208
IO.puts("error: following missing instructions are used:")
205209
print_list(missing_instructions)
206210
IO.puts("")

lib/mix/tasks/esp32_flash.ex

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,59 @@
11
defmodule Mix.Tasks.Atomvm.Esp32.Flash do
22
use Mix.Task
3+
4+
@shortdoc "Flash the application to an ESP32 micro-controller"
5+
6+
@moduledoc """
7+
Flashes the application to an ESP32 micro-controller.
8+
9+
> #### Info {: .info}
10+
>
11+
> Note. Before running this task, you must flash the AtomVM virtual machine to the target device.
12+
>
13+
> ### ESP32 Build Requirements
14+
>
15+
> This tasks depends on a host installation of the IDF_SDK and Espressif Xtensa tool chains, see [Building for ESP32](https://www.atomvm.net/doc/main/build-instructions.html#building-for-esp32)
16+
>
17+
> If the IDF_PATH environment variable is set, then the esptool.py from the IDF SDK installation will be used to flash the application to the ESP32 device.
18+
> Otherwise, this plugin will attempt to use the esptool.py program from the user's PATH environment variable.
19+
> The ESP Tool Python3 application can be installed from source or via many popular package managers. Consult your local OS documentation for more information.
20+
21+
## Usage example
22+
23+
Within your AtomVM mix project run
24+
25+
`
26+
$ mix atomvm.esp32.flash
27+
`
28+
29+
Or with optional flags (which will override the config in mix.exs)
30+
31+
`
32+
$ mix atomvm.esp32.flash --port /dev/tty.usbserial-0001
33+
`
34+
35+
## Configuration
36+
37+
ExAtomVM can be configured from the mix.ex file and supports the following settings for the
38+
`atomvm.esp32.flash` task.
39+
40+
* `:flash_offset` - The start address of the flash to write the application to in hexademical format,
41+
defaults to `0x250000`.
42+
43+
* `:chip` - Chip type, defaults to `:esp32`.
44+
45+
* `:port` - The port to which device is connected on the host computer, defaults to `/dev/ttyUSB0`.
46+
47+
* `:baud` - The BAUD rate used when flashing to device, defaults to `115200`.
48+
49+
## Command line options
50+
51+
Properties in the mix.exs file may be over-ridden on the command line using long-style flags (prefixed by --) by the same name
52+
as the supported properties key listed in .
53+
54+
For example, you can use the `--port` option to specify or override the port property.
55+
"""
56+
357
alias Mix.Project
458
alias Mix.Tasks.Atomvm.Packbeam
559

lib/mix/tasks/packbeam.ex

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
defmodule Mix.Tasks.Atomvm.Packbeam do
22
use Mix.Task
3+
4+
@shortdoc "Bundle the application into an AVM file"
5+
6+
@moduledoc """
7+
Bundle an application into an AVM file that can be flashed to a micro-controller and executed by the AtomVM virtual machine.
8+
9+
10+
## Usage example
11+
12+
Within your AtomVM mix project run
13+
14+
`
15+
$ mix atomvm.packbeam --start MyProject
16+
`
17+
18+
## Configuration
19+
20+
ExAtomVM can be configured from the mix.ex file and supports the following settings for the
21+
`atomvm.packbeam` task.
22+
23+
* `:start` - The name of the module containing the start/0 entrypoint function.
24+
25+
## Command line options
26+
27+
Properties in the mix.exs file may be over-ridden on the command line using long-style flags (prefixed by --) by the same name
28+
as the supported properties key listed in .
29+
30+
For example, you can use the `--start` option to specify or override the `start` property.
31+
"""
32+
333
alias ExAtomVM.PackBEAM
434
alias Mix.Project
535
alias Mix.Tasks.Atomvm.Check

lib/mix/tasks/pico_flash.ex

Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,53 @@
11
defmodule Mix.Tasks.Atomvm.Pico.Flash do
22
use Mix.Task
3+
4+
@shortdoc "Flash the application to a pico micro-controller"
5+
6+
@moduledoc """
7+
Flashes the application to a Raspberry Pi RP2
8+
9+
You can build with all boards supported by Raspberry Pi pico SDK, including Pico, Pico-W and Pico2.
10+
AtomVM also works with clones such as RP2040 Zero.
11+
12+
> #### Info {: .info}
13+
>
14+
> Note. Before running this task, you must flash the AtomVM virtual machine to the target device.
15+
>
16+
> This tasks depends on a host installation of pico supported tooling, see [Building for Raspberry Pi RP2](https://www.atomvm.net/doc/master/build-instructions.html#building-for-raspberry-pi-rp2)
17+
18+
## Usage example
19+
20+
Within your AtomVM mix project run
21+
22+
`
23+
$ mix atomvm.pico.flash
24+
`
25+
26+
Or with optional flags (which will override the config in mix.exs)
27+
28+
`
29+
$ mix atomvm.pico.flash --picotool /some/path
30+
`
31+
32+
## Configuration
33+
34+
ExAtomVM can be configured from the mix.ex file and supports the following settings for the
35+
`atomvm.pico.flash` task.
36+
37+
* `:pico_path` - The full path to the pico mount point, defaults to `"/run/media/${USER}/RPI-RP2"` on linux; `"/Volumes/RPI-RP2"` on darwin (Mac)
38+
39+
* `:pico_reset` - The full path to the pico device to reset if required, default `"/dev/ttyACM*"` on linux; `"/dev/cu.usbmodem14*"` on darwin (Mac)
40+
41+
* `:picotool` - The full path to picotool executable (currently optional), default `undefined`
42+
43+
## Command line options
44+
45+
Properties in the mix.exs file may be over-ridden on the command line using long-style flags (prefixed by --) by the same name
46+
as the supported properties key listed in .
47+
48+
For example, you can use the `--picotool` option to specify or override the `picotool` property.
49+
"""
50+
351
alias Mix.Project
452
alias Mix.Tasks.Atomvm.Uf2create
553

@@ -9,12 +57,38 @@ defmodule Mix.Tasks.Atomvm.Pico.Flash do
957
with {:atomvm, {:ok, avm_config}} <- {:atomvm, Keyword.fetch(config, :atomvm)},
1058
{:args, {:ok, options}} <- {:args, parse_args(args)},
1159
{:uf2, :ok} <- {:uf2, Uf2create.run(args)} do
12-
pico_path =
13-
Map.get(options, :pico_path, Keyword.get(avm_config, :pico_path, System.get_env("ATOMVM_PICO_MOUNT_PATH", get_default_mount())))
60+
pico_path =
61+
Map.get(
62+
options,
63+
:pico_path,
64+
Keyword.get(
65+
avm_config,
66+
:pico_path,
67+
System.get_env("ATOMVM_PICO_MOUNT_PATH", get_default_mount())
68+
)
69+
)
70+
1471
pico_reset =
15-
Map.get(options, :pico_reset, Keyword.get(avm_config, :pico_reset, System.get_env("ATOMVM_PICO_RESET_DEV", get_reset_base())))
72+
Map.get(
73+
options,
74+
:pico_reset,
75+
Keyword.get(
76+
avm_config,
77+
:pico_reset,
78+
System.get_env("ATOMVM_PICO_RESET_DEV", get_reset_base())
79+
)
80+
)
81+
1682
picotool =
17-
Map.get(options, :picotool, Keyword.get(avm_config, :picotool, System.get_env("ATOMVM_PICOTOOL_PATH", "#{:os.find_executable(~c"picotool")}")))
83+
Map.get(
84+
options,
85+
:picotool,
86+
Keyword.get(
87+
avm_config,
88+
:picotool,
89+
System.get_env("ATOMVM_PICOTOOL_PATH", "#{:os.find_executable(~c"picotool")}")
90+
)
91+
)
1892

1993
do_flash(pico_path, pico_reset, picotool)
2094
else
@@ -70,13 +144,16 @@ defmodule Mix.Tasks.Atomvm.Pico.Flash do
70144
case Map.get(filestat, :type) do
71145
:directory ->
72146
:ok
147+
73148
_ ->
74149
IO.puts("Object found at #{mount} is not a directory")
75150
exit({:shutdown, 1})
76151
end
152+
77153
{:error, :enoent} ->
78154
Process.sleep(1000)
79155
wait_for_mount(mount, count + 1)
156+
80157
error ->
81158
IO.puts("unexpected error: #{error} while checking pico mount path.")
82159
exit({:shutdown, 1})
@@ -94,10 +171,12 @@ defmodule Mix.Tasks.Atomvm.Pico.Flash do
94171
case Map.get(info, :type) do
95172
:directory ->
96173
:ok
174+
97175
_ ->
98176
IO.puts("error: object at pico mount path not a directory. Abort!")
99177
exit({:shutdown, 1})
100178
end
179+
101180
_ ->
102181
IO.puts("error: Pico not mounted. Abort!")
103182
exit({:shutdown, 1})
@@ -123,16 +202,19 @@ defmodule Mix.Tasks.Atomvm.Pico.Flash do
123202
case Path.wildcard(resetdev) do
124203
[] ->
125204
false
205+
126206
[device | _t] ->
127207
case File.stat(device) do
128208
{:ok, info} ->
129209
case Map.get(info, :type) do
130210
:device -> {true, device}
131211
_ -> false
132212
end
213+
133214
_ ->
134215
false
135216
end
217+
136218
_ ->
137219
false
138220
end
@@ -146,25 +228,40 @@ defmodule Mix.Tasks.Atomvm.Pico.Flash do
146228
{"", 0} ->
147229
# Pause to let the device settle
148230
Process.sleep(200)
231+
149232
error ->
150233
case picotool do
151234
false ->
152-
IO.puts("Error: #{error}\nUnable to locate 'picotool', close the serial monitor before flashing, or install picotool for automatic disconnect and BOOTSEL mode.")
235+
IO.puts(
236+
"Error: #{error}\nUnable to locate 'picotool', close the serial monitor before flashing, or install picotool for automatic disconnect and BOOTSEL mode."
237+
)
238+
153239
exit({:shutdown, 1})
240+
154241
_ ->
155-
IO.puts("Warning: #{error}\nFor faster flashing remember to disconnect serial monitor first.")
242+
IO.puts(
243+
"Warning: #{error}\nFor faster flashing remember to disconnect serial monitor first."
244+
)
245+
156246
reset_args = ["reboot", "-f", "-u"]
157-
IO.puts("Disconnecting serial monitor with `picotool #{:lists.join(" ", reset_args)}` in 5 seconds...")
247+
248+
IO.puts(
249+
"Disconnecting serial monitor with `picotool #{:lists.join(" ", reset_args)}` in 5 seconds..."
250+
)
251+
158252
Process.sleep(5000)
253+
159254
case :string.trim(System.cmd(picotool, reset_args)) do
160255
{status, 0} ->
161256
case status do
162257
"The device was asked to reboot into BOOTSEL mode." ->
163258
:ok
259+
164260
pt_error ->
165261
IO.puts("Failed to prepare pico for flashing: #{pt_error}")
166262
exit({:shutdown, 1})
167263
end
264+
168265
_ ->
169266
IO.puts("Failed to prepare pico for flashing: #{error}")
170267
end
@@ -176,14 +273,22 @@ defmodule Mix.Tasks.Atomvm.Pico.Flash do
176273
case needs_reset(pico_reset) do
177274
false ->
178275
:ok
276+
179277
{true, reset_port} ->
180278
do_reset(reset_port, picotool)
181279
IO.puts("Waiting for the device at path #{pico_path} to settle and mount...")
182280
wait_for_mount(pico_path, 0)
183281
end
184282

185283
check_pico_mount(pico_path)
186-
_bytes = File.copy!("#{Project.config()[:app]}.uf2", "#{pico_path}/#{Project.config()[:app]}.uf2", :infinity)
284+
285+
_bytes =
286+
File.copy!(
287+
"#{Project.config()[:app]}.uf2",
288+
"#{pico_path}/#{Project.config()[:app]}.uf2",
289+
:infinity
290+
)
291+
187292
IO.puts("Successfully loaded #{Project.config()[:app]} to the pico device at #{pico_path}.")
188293
end
189294
end

0 commit comments

Comments
 (0)