atomvm / AtomVM

Tiny Erlang VM
https://www.atomvm.net
Apache License 2.0
1.43k stars 94 forks source link

Instructions unclear for getting up and running with new projects. #1073

Open jkbbwr opened 4 months ago

jkbbwr commented 4 months ago

Hey, firstly thanks for this project and your work on it. Its great!

I spent several hours trying to get a few simple hello world programs built for two devices, the pico-w and the esp32-s3

I wasn't able to get either of them to flash or boot reliably.

One of the biggest issues was the disparity in tooling between rebar and mix, and the flashable formats hex/uf2 and so on.

One possible suggestion, we have a standalone tool, like picotool or esptool.py that handles .beam -> .avm and then .avm -> (.hex/*.uf2/etc), this tool is then called via ports from rebar and mix so the codebases are identical.

An example manual flow might be

$ wget atomvm.com/avmtool 
$ elixirc Hello.ex 
$ avmtool avm Elixir.Hello.beam
$ avmtool uf2 hello.avm 
$ picotool load hello.uf2

Same goes for the esp32/stm32 flows.

UncleGrumpy commented 4 months ago

Did you check out the section on tooling in the documentation? The 0.6.0-beta.0 and earlier release images for the pico have some quirks that make flashing a bit of a pain and serial console impossible to use. There should be a 0.6.0-beta.1 released soon that makes it much easier to work with, in the mean time you can build a binary from the release-0.6 branch, which includes these fixes.

Following the Getting Started and AtomVM Tooling sections of the documentation should get you going on esp32-s3 with no troubles at all. If you have problems with the instructions at any point, would you please let us know where things are not explained well enough, and we will do our best to improve it, and help you get set up.

jkbbwr commented 4 months ago

Thanks for taking time to reply

So the issue I had with the esp32-S3 might be due to using a WROOM variant. Not sure if that factors into things.

I saw the tooling page but it seems to split the behaviour between the elixir mix plugin and rebar. And when executing the commands it would seemingly generate bad files, or I couldn't build valid uf2 files.

I was also unsure if I needed the .avm standardlib files and when I went looking for them i coudln't find them.

If the beam -> avm process and avm -> output process was documented I could make an attempt at this myself and report back?

UncleGrumpy commented 4 months ago

I have the ESP32-S3-DevKitC-1 which also uses a WROOM module, so that is not a problem. Not sure when you checked last, but the documentation was very recently updated to include the correct offset to flash the atomvm image. We have also just discovered a problem with the network_driver that only seems to affect the S3, so that could be part of your problem.

As far as uf2 files for the pico, using a v0.6.0-beta.1 version of AtomVM-pico_w-v0.6.0-beta.1.uf2 and atomvmlib-v0.6.0-beta.1.uf2 will help the atomvm_rebar3_plugin to work correctly. I believe for mix development using the ExAtomVM you might need a copy of atomvmlib.avm in a directory named avm_deps in you mix project's top level directory to keep the compiler happy, but I way be wrong on that point, I haven't done very much in Elixir. I will look into this and try to update the documentation if that is the case. Unfortunately the mix plugin doesn't have uf2/pico support yet, only stm32 and esp32 devices.

As you pointed out we don't yet have a "standalone" tool for converting *.avm files to pico uf2 files (which could at least for now convert mix created avm files to uf2 manually), but we do have such a tool included in the AtomVM repository. It is built when doing a generic_unix build (which must be done first for all platforms to build the standard libraries). It can be found in build/tools/uf2tool and is called uf2tool. If you are going to develop Elixir applications this way using picotool mentioned in the tooling section is easier than messing with the BOOTSEL button and power cycling the device to put it into BOOTSEL. (picotool reboot -f) then you can just cp the uf2 file the the mounted partition that is presented by the pico.

Hopefully we can get uf2 support added to ExAtomVM for better Elixir support soon, and this helps point out the need for a standalone distribution of the AtomVM uf2tool.

UncleGrumpy commented 4 months ago

If you are using Erlang and the atomvm_rebar3_plugin then the pico_flash task will generate the uf2 files (first compiling, and generating the packbeam file if necessary) and reset the device into BOOTSEL automatically and copy the uf2 files to the appropriate location. None of this worked correctly in v0.6.0-beta.0 and prior. Several fixes were just merged and are included in the v0.6.0-beta.1 that allow it all to work together, as well as implementing a 20 second timeout, to let you connect a serial monitor before the application starts. Also a quirk in the v0.6.0-beta.0 release was hello_world (or any other short application) would finish and hang the CPU before you had a chance of connecting to the console.

jkbbwr commented 4 months ago

I was coming at it from Elixir originally, to make this more annoying.

UncleGrumpy commented 4 months ago

Yes, I see now how frustrating that is. I didn't consider this workflow when walking through our documentation and testing.

We are working on getting uf2tool into a standalone repo, so you can build it to use for applications with release binaries of the VM without needing to clone the entire repo. Once we have it in it's own repo it will be much easier for us to add it to the ExAtomVM mix plugin as a dependency. If you can survive with the manual workarounds I mentioned previously, for the time being, we really appreciate your feedback and patience.

Just a word of caution, our Elixir support is still quite a bit less mature than Erlang, but any contributions to improve it are greatly appreciated.

jkbbwr commented 4 months ago

I have all the time in the world for projects like this. Id be happy to help as/where I can.

Ill take another stab at the more manual method in a few days time

jrfondren commented 2 months ago

The more manual method:

  1. produce .beam files with your usual tools
  2. produce an .avm file out of multiple .beam files with PackBEAM
  3. run the .avm file with AtomVM

So for example:

-module(hello).
-export([start/0]).

start() ->
    erlang:display('Hello world!').

Gets run this way:

$ erlc hello.erl
$ ~/erlang/AtomVM/build/tools/packbeam/PackBEAM hello.avm hello.beam
$ ~/erlang/AtomVM/build/src/AtomVM hello.avm
Hello world!
Return value: true

Or with Elixir:

defmodule Hello do
  def start do
    :erlang.display(:"Hello, world!")
  end
end

Only the first step differs:

$ elixirc hello.exs
$ ~/erlang/AtomVM/build/tools/packbeam/PackBEAM hello.avm Elixir.Hello.beam
$ ~/erlang/AtomVM/build/src/AtomVM hello.avm
Hello world!
Return value: true

An example like this would fill in the "staircase" of adoption a bit, adding a confidence-building step between "confirm the build with an already-existing .avm" and "use the rebar3 plugin to this all for you"

It's also nice to see a 2000x speedup for Erlang's 'hello world', and the much smaller runtime for it.