Skip to content

Commit 757e852

Browse files
committed
Built-in esptool flash (via Pythonx)
Optional use built-in esptool install via Pythonx. Signed-off-by: Peter M <[email protected]>
1 parent cbd2fb6 commit 757e852

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

lib/esptool_helper.ex

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule ExAtomVM.EsptoolHelper do
2+
@moduledoc """
3+
Module for setting up using esptool through Pythonx.
4+
"""
5+
6+
@doc """
7+
Initializes Python environment with project configuration.
8+
We use locked main branch esptool version, pending a stable release 5.x release,
9+
as we need the read to memory (instead of only to file) features.
10+
"""
11+
def setup do
12+
Application.ensure_all_started(:pythonx)
13+
14+
Pythonx.uv_init("""
15+
[project]
16+
name = "project"
17+
version = "0.0.0"
18+
requires-python = "==3.13.*"
19+
dependencies = [
20+
"esptool @ git+https://github.com/espressif/esptool.git@6f0d779"
21+
]
22+
""")
23+
end
24+
end

lib/mix/tasks/esp32_flash.ex

+52-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,58 @@ defmodule Mix.Tasks.Atomvm.Esp32.Flash do
5959

6060
tool_args = if port == "auto", do: tool_args, else: ["--port", port] ++ tool_args
6161

62-
tool_full_path = get_esptool_path(idf_path)
63-
System.cmd(tool_full_path, tool_args, stderr_to_stdout: true, into: IO.stream(:stdio, 1))
62+
case Code.ensure_loaded(Pythonx) do
63+
{:module, Pythonx} ->
64+
IO.inspect("Flashing using Pythonx installed esptool..")
65+
flash_pythonx(tool_args)
66+
67+
_ ->
68+
IO.inspect("Flashing using esptool..")
69+
tool_full_path = get_esptool_path(idf_path)
70+
System.cmd(tool_full_path, tool_args, stderr_to_stdout: true, into: IO.stream(:stdio, 1))
71+
end
72+
end
73+
74+
defp flash_pythonx(tool_args) do
75+
# https://github.com/espressif/esptool/blob/master/docs/en/esptool/scripting.rst
76+
ExAtomVM.EsptoolHelper.setup()
77+
78+
{_result, globals} =
79+
try do
80+
Pythonx.eval(
81+
"""
82+
import esptool
83+
import sys
84+
85+
command = [arg.decode('utf-8') for arg in tool_args]
86+
87+
def flash_esp():
88+
esptool.main(command)
89+
90+
if __name__ == "__main__":
91+
try:
92+
result = flash_esp()
93+
result = True
94+
except SystemExit as e:
95+
print(f"SystemExit: {e}")
96+
result = False
97+
except Exception as e:
98+
print(f"Warning: {e}")
99+
result = False
100+
101+
""",
102+
%{"tool_args" => tool_args}
103+
)
104+
rescue
105+
e in Pythonx.Error ->
106+
IO.inspect("Pythonx error occurred: #{inspect(e)}")
107+
exit({:shutdown, 1})
108+
end
109+
110+
case Pythonx.decode(globals["result"]) do
111+
true -> exit({:shutdown, 0})
112+
false -> exit({:shutdown, 1})
113+
end
64114
end
65115

66116
defp get_esptool_path(<<"">>) do

mix.exs

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ defmodule ExAtomVM.MixProject do
2121
# Run "mix help deps" to learn about dependencies.
2222
defp deps do
2323
[
24-
{:uf2tool, "1.1.0"}
24+
{:uf2tool, "1.1.0"},
25+
{:pythonx, "~> 0.4.0", runtime: false, optional: true}
26+
2527
# {:dep_from_hexpm, "~> 0.3.0"},
2628
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
2729
]

0 commit comments

Comments
 (0)