Skip to content

Commit

Permalink
Initial support for Raspberry Pico
Browse files Browse the repository at this point in the history
Also slightly modify SMP code to handle the specific case of the Pico.

Code relies on condition variables implementation proposed in this upstream PR:
raspberrypi/pico-sdk#1101

Signed-off-by: Paul Guyot <pguyot@kallisys.net>
  • Loading branch information
pguyot committed Apr 10, 2023
1 parent abe4f9c commit 8ddcf9d
Show file tree
Hide file tree
Showing 26 changed files with 1,690 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/pico-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#
# Copyright 2022 Paul Guyot <pguyot@kallisys.net>
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

name: Pico Build

on: [push, pull_request]

jobs:
pico:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: "Install deps"
run: sudo apt install -y cmake gperf ninja-build gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib

- name: Build
shell: bash
working-directory: ./src/platforms/rp2040/
run: |
set -euo pipefail
mkdir build
cd build
cmake .. -G Ninja
ninja
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ endif()

add_subdirectory(tests)
add_subdirectory(tools/packbeam)
add_subdirectory(tools/uf2tool)

if (NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
add_subdirectory(libs)
add_subdirectory(examples)
Expand Down
50 changes: 50 additions & 0 deletions CMakeModules/BuildErlang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ macro(pack_lib avm_name)
add_dependencies(${avm_name} ${avm_name}_main)
endif()

add_custom_target(
${avm_name}.uf2 ALL
COMMAND ${CMAKE_BINARY_DIR}/tools/uf2tool/uf2tool create -o ${avm_name}.uf2 -s 0x10080000 ${avm_name}.avm
COMMENT "Creating UF2 file ${avm_name}.uf2"
VERBATIM
)
add_dependencies(${avm_name}.uf2 ${avm_name})

endmacro()


Expand Down Expand Up @@ -153,3 +161,45 @@ macro(pack_test test_avm_name)
add_dependencies(${test_avm_name} ${ARCHIVE_TARGETS} PackBEAM)

endmacro()

macro(pack_uf2 avm_name main)

add_custom_command(
OUTPUT ${main}.beam
COMMAND erlc -I ${CMAKE_SOURCE_DIR}/libs/include ${CMAKE_CURRENT_SOURCE_DIR}/${main}.erl
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${main}.erl
COMMENT "Compiling ${main}.erl"
VERBATIM
)

add_custom_target(
${avm_name}_main
DEPENDS ${main}.beam
)

foreach(archive_name ${ARGN})
if(NOT ${archive_name} STREQUAL "exavmlib")
set(ARCHIVES ${ARCHIVES} ${CMAKE_BINARY_DIR}/libs/${archive_name}/src/${archive_name}.avm)
else()
set(ARCHIVES ${ARCHIVES} ${CMAKE_BINARY_DIR}/libs/${archive_name}/lib/${archive_name}.avm)
endif()
set(ARCHIVE_TARGETS ${ARCHIVE_TARGETS} ${archive_name})
endforeach()

add_custom_target(
${avm_name}.avm ALL
COMMAND ${CMAKE_BINARY_DIR}/tools/packbeam/PackBEAM ${avm_name}.avm ${main}.beam ${ARCHIVES}
COMMENT "Packing runnable ${avm_name}.avm"
VERBATIM
)
add_dependencies(${avm_name}.avm ${avm_name}_main ${ARCHIVE_TARGETS} PackBEAM)

add_custom_target(
${avm_name}.uf2 ALL
COMMAND ${CMAKE_BINARY_DIR}/tools/uf2tool/uf2tool create -o ${avm_name}.uf2 -s 0x100A0000 ${avm_name}.avm
COMMENT "Creating UF2 file ${avm_name}.uf2"
VERBATIM
)
add_dependencies(${avm_name}.uf2 ${avm_name}.avm uf2tool)

endmacro()
1 change: 1 addition & 0 deletions README.Md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Supported Platforms
* Linux, macOS, FreeBSD ([generic unix](src/platforms/generic_unix))
* ESP32 SoC (with IDF/FreeRTOS, see [README.ESP32.Md](README.ESP32.Md))
* STM32 MCUs (with LibOpenCM3, see [README.STM32.Md](README.STM32.Md))
* Raspberry Pi Pico (see [README.PICO.Md](README.PICO.Md))

AtomVM aims to be easily portable to new platforms with a minimum effort, so additional platforms
might be supported in a near future.
Expand Down
79 changes: 79 additions & 0 deletions README.PICO.Md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!--
Copyright 2022 Paul Guyot <pguyot@kallisys.net>
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
-->

Building AtomVM for Raspberry Pico
==================================

* build:

```
cd src/platforms/rp2040/
mkdir build
cd build
cmake .. -G Ninja
ninja
```

> Note: requires cmake and ninja
You may want to build with option `AVM_REBOOT_ON_NOT_OK` so Pico restarts on
error.

Installing AtomVM on Raspberry Pico
===================================

VM binary is file `src/platforms/rp2040/build/src/AtomVM.uf2`. Simply copy it
to the pico. The VM will crash because there is no application.

Installing atomvm library to Raspberry Pico
===========================================

AtomVM library must be installed as well.

Building it
-----------

Build of standard libraries is part of the generic unix build.

From the root of the project:

```
mkdir build
cd build
cmake .. -G Ninja
ninja
```

> Note: requires cmake, ninja, Erlang/OTP and Elixir for elixir libs
The library to install is `build/libs/atomvmlib.uf2`
The VM currently expects the library to be loaded at address 0x10080000.

Running BEAM code on Raspberry Pico
===================================

* BEAM module must be stripped before using PackBEAM:

```
./PackBEAM packed.avm module.beam
```

Then the BEAM file must be converted to UF2.
The VM currently expects the application to be loaded at address 0x100A0000.

```sh
./uf2tool create -o packed.uf2 -s 0x10080000 packed.avm
```

Copy this UF2 to the Pico. You probably also need atomvmlib.uf2 first.

Running Hello Pico
==================

This example will print a Hello Pico message repeatedly.

It is built into `build/examples/erlang/rp2040/hello_pico.uf2`.

1 change: 1 addition & 0 deletions examples/erlang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ project(examples_erlang)
include(BuildErlang)

add_subdirectory(esp32)
add_subdirectory(rp2040)

pack_runnable(hello_world hello_world eavmlib)
pack_runnable(udp_server udp_server estdlib eavmlib)
Expand Down
26 changes: 26 additions & 0 deletions examples/erlang/rp2040/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# This file is part of AtomVM.
#
# Copyright 2022 Paul Guyot <pguyot@kallisys.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

project(examples_erlang_rp2040)

include(BuildErlang)

pack_uf2(hello_pico hello_pico eavmlib estdlib)
pack_uf2(pico_rtc pico_rtc eavmlib estdlib)
35 changes: 35 additions & 0 deletions examples/erlang/rp2040/hello_pico.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
%
% This file is part of AtomVM.
%
% Copyright 2022 Paul Guyot <pguyot@kallisys.net>
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
%

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

start() ->
% Pico's serial may be too fast to use hello_world example, so this
% version loops.
hello_pico_loop().

hello_pico_loop() ->
console:puts("Hello Pico\n"),
receive
ok -> ok
after 3000 -> ok
end,
hello_pico_loop().
68 changes: 68 additions & 0 deletions examples/erlang/rp2040/pico_rtc.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
%
% This file is part of AtomVM.
%
% Copyright 2022 Paul Guyot <pguyot@kallisys.net>
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
%

% This example demonstrates the usage of the Pico's hardware RTC.

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

-define(START_DATE, {{2022, 11, 16}, {22, 09, 00}}).

start() ->
case atomvm:platform() of
pico ->
pico_rtc_loop();
Other ->
erlang:display({unexpected, Other})
end.

pico_rtc_loop() ->
Date = erlang:universaltime(),
print_date(Date),
receive
ok -> ok
after 5000 -> ok
end,
if
Date < ?START_DATE ->
pico:rtc_set_datetime(?START_DATE);
true ->
ok
end,
pico_rtc_loop().

print_date({{Year, Month, Day}, {Hour, Min, Sec}}) ->
% Only ~p and ~s seem to exist for now.
YearStr = integer_to_list(Year),
MonthStr = format_2_digits(Month),
DayStr = format_2_digits(Day),
HourStr = format_2_digits(Hour),
MinStr = format_2_digits(Min),
SecStr = format_2_digits(Sec),
console:puts(
lists:flatten([
YearStr, "-", MonthStr, "-", DayStr, "T", HourStr, ":", MinStr, ":", SecStr, "\n"
])
).

format_2_digits(Num) when Num < 10 ->
["0", integer_to_list(Num)];
format_2_digits(Num) ->
integer_to_list(Num).
1 change: 1 addition & 0 deletions libs/eavmlib/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ set(ERLANG_MODULES
logger
network
network_fsm
pico
port
spi
timer_manager
Expand Down
40 changes: 40 additions & 0 deletions libs/eavmlib/src/pico.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
%
% This file is part of AtomVM.
%
% Copyright 2022 Paul Guyot <pguyot@kallisys.net>
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
%

%%-----------------------------------------------------------------------------
%% @doc PICO-specific APIs
%%
%% This module contains functions that are specific to the PICO platform.
%% @end
%%-----------------------------------------------------------------------------
-module(pico).

-export([
rtc_set_datetime/1
]).

%%-----------------------------------------------------------------------------
%% @doc Set the datetime on the RTC.
%% The datetime can be obtained through bif erlang:localtime()
%% @end
%%-----------------------------------------------------------------------------
-spec rtc_set_datetime(calendar:datetime()) -> ok.
rtc_set_datetime(_Datetime) ->
throw(nif_error).
20 changes: 20 additions & 0 deletions src/platforms/rp2040/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# This file is part of AtomVM.
#
# Copyright 2022 Paul Guyot <pguyot@kallisys.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#
build
Loading

0 comments on commit 8ddcf9d

Please sign in to comment.