Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raspberry Pi Pico target support #1831

Merged
merged 58 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
99baeeb
target property pico
gundralaa Jun 8, 2023
b79ba35
tests and main
gundralaa Jun 8, 2023
462f70c
pico-sdk find and include
gundralaa Jun 8, 2023
223165f
cmake generator for pico
gundralaa Jun 9, 2023
e42b4bd
swithc to reactor-c pico support branch
gundralaa Jun 9, 2023
9140286
patch newline
gundralaa Jun 9, 2023
de397f0
for use in lf-pico
gundralaa Jun 14, 2023
ea6f05a
extra launch scripts
gundralaa Jun 19, 2023
9bf2553
merge master
gundralaa Jun 26, 2023
6508f75
bump reactor-cpp
gundralaa Jun 26, 2023
ae8a25f
update to main
gundralaa Jul 1, 2023
b5f5081
no warnings [temp]
gundralaa Jul 7, 2023
7907b9f
[merge] merge in master
gundralaa Jul 7, 2023
e6f81b4
change to rp2040 target
gundralaa Jul 11, 2023
80edc92
remove resources and refactor
gundralaa Jul 11, 2023
23051f1
generator changes: pico->rp2040
gundralaa Jul 11, 2023
485b4c6
test refactor
gundralaa Jul 11, 2023
50ef79a
formatter and update reactor-c threads
gundralaa Jul 12, 2023
b99931b
[refactor] break in switch
gundralaa Jul 12, 2023
ae0e4eb
[refactor] add reactor-c changes
gundralaa Jul 17, 2023
c41feed
[threads] cond_var changes
gundralaa Jul 17, 2023
c014196
Aligned with pico-support branch of reactor-c
edwardalee Jul 17, 2023
1074f84
[threaded] compilation check from threaded
gundralaa Jul 17, 2023
319e19c
Merge branch 'pico' of github.com:lf-lang/lingua-franca into pico
gundralaa Jul 17, 2023
17fd565
[merge] merge master, update reactor-c
gundralaa Jul 19, 2023
890a1e8
[feature] add board property with usb/uart switch
gundralaa Jul 21, 2023
9103508
[refactor] remove tests, set to basic reactor-c branch
gundralaa Jul 21, 2023
bb70407
[format] apply formatter
gundralaa Jul 21, 2023
49a2003
default board stdio
gundralaa Jul 21, 2023
07cb011
resolve comments
gundralaa Jul 22, 2023
5348166
cmake warnings and format
gundralaa Jul 22, 2023
928db8e
[submodule] merge main
gundralaa Jul 22, 2023
2b28705
Merge branch 'master' into pico
gundralaa Jul 22, 2023
e698907
[cmake] add defaults for null board
gundralaa Jul 24, 2023
e6c4b63
exception for null target property string
gundralaa Jul 24, 2023
e057e0a
[format] spotless apply
gundralaa Jul 24, 2023
82e8a0c
Merge branch 'master' into pico
lhstrh Jul 26, 2023
ea2bf26
update reactor-c
gundralaa Jul 27, 2023
06c20b1
[merge] lingua-franca
gundralaa Jul 27, 2023
f75519b
[merge] master
gundralaa Jul 27, 2023
8daafda
[merge] master
gundralaa Jul 27, 2023
9b800f0
[submodule] update reactor-c to main
gundralaa Jul 27, 2023
2cb4f52
Merge master into pico
lhstrh Jul 30, 2023
d166945
Attempt to deal with comment in #1831
edwardalee Jul 30, 2023
6cec307
Update core/src/main/java/org/lflang/generator/c/CMainFunctionGenerat…
lhstrh Jul 30, 2023
75ebf6d
Attempt to find pico-sdk path relative to package root
edwardalee Jul 30, 2023
45fb5cb
Align reactor-c to main
edwardalee Jul 30, 2023
a9c9afd
Merge branch 'master' into pico
lhstrh Jul 31, 2023
bb83f62
[format] apply spotless
gundralaa Jul 31, 2023
d04d038
Fix whitespace-related bug.
petervdonovan Jul 31, 2023
246c143
Apply formatter
lhstrh Jul 31, 2023
ef92075
[refactor] resolve cmake comments
gundralaa Jul 31, 2023
b7f9e0a
Merge branch 'pico' of github.com:lf-lang/lingua-franca into pico
gundralaa Jul 31, 2023
0eae94e
[refactor] whitespace
gundralaa Jul 31, 2023
9e18ee5
Look for Pico SDK in package root, not output path
lhstrh Aug 2, 2023
c813b24
Do checks in validator. This could be done more elegantly but require…
lhstrh Aug 3, 2023
b018184
Apply formatter
lhstrh Aug 3, 2023
ba76cac
Merge branch 'master' into pico
hokeun Aug 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/src/main/java/org/lflang/TargetConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,9 @@ public static class PlatformOptions {
/**
* The string value used to determine what type of embedded board we work with and can be used
* to simplify the build process. For example, when we want to flash to an Arduino Nano 33 BLE
* board, we can use the string arduino:mbed_nano:nano33ble
* board, we can use the string arduino:mbed_nano:nano33ble TODO: move to lingo Can also be used
gundralaa marked this conversation as resolved.
Show resolved Hide resolved
* to specify uart output setting on rp2040 boards where arduino_nano_rp2040_connect:uart or
* arduino_nano_rp2040_connect:usb (usb) fully specifies the board and uart output
*/
public String board = null;

Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/org/lflang/TargetProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,7 @@ public enum Platform {
AUTO,
ARDUINO,
NRF52("Nrf52"),
RP2040("Rp2040"),
LINUX("Linux"),
MAC("Darwin"),
ZEPHYR("Zephyr"),
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/lflang/generator/CodeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public int length() {

/** Add a new line. */
public void newLine() {
this.pr("");
this.pr("\n");
petervdonovan marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
150 changes: 115 additions & 35 deletions core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,25 +116,40 @@ CodeBuilder generateCMakeCode(

cMakeCode.pr("cmake_minimum_required(VERSION " + MIN_CMAKE_VERSION + ")");

if (targetConfig.platformOptions.platform == Platform.ZEPHYR) {
cMakeCode.pr("# Set default configuration file. To add custom configurations,");
cMakeCode.pr("# pass -- -DOVERLAY_CONFIG=my_config.prj to either cmake or west");
cMakeCode.pr("set(CONF_FILE prj_lf.conf)");
if (targetConfig.platformOptions.board != null) {
cMakeCode.pr("# Selecting board specified in target property");
cMakeCode.pr("set(BOARD " + targetConfig.platformOptions.board + ")");
} else {
cMakeCode.pr("# Selecting default board");
cMakeCode.pr("set(BOARD qemu_cortex_m3)");
}
cMakeCode.pr("# We recommend Zephyr v3.3.0 but we are compatible with older versions also");
cMakeCode.pr("find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} 3.3.0)");
cMakeCode.newLine();
// Setup the project header for different platforms
switch (targetConfig.platformOptions.platform) {
case ZEPHYR:
cMakeCode.pr("# Set default configuration file. To add custom configurations,");
cMakeCode.pr("# pass -- -DOVERLAY_CONFIG=my_config.prj to either cmake or west");
cMakeCode.pr("set(CONF_FILE prj_lf.conf)");
if (targetConfig.platformOptions.board != null) {
cMakeCode.pr("# Selecting board specified in target property");
cMakeCode.pr("set(BOARD " + targetConfig.platformOptions.board + ")");
} else {
cMakeCode.pr("# Selecting default board");
cMakeCode.pr("set(BOARD qemu_cortex_m3)");
}
cMakeCode.pr("# We recommend Zephyr v3.3.0 but we are compatible with older versions also");
cMakeCode.pr("find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} 3.3.0)");
cMakeCode.newLine();
cMakeCode.pr("project(" + executableName + " LANGUAGES C)");
cMakeCode.newLine();
break;
case RP2040:
cMakeCode.pr("include(pico_sdk_import.cmake)");
cMakeCode.pr("project(" + executableName + " LANGUAGES C CXX ASM)");
cMakeCode.newLine();
// board type for rp2040 based boards
if (targetConfig.platformOptions.board != null) {
String[] bProps = targetConfig.platformOptions.board.split(":");
cMakeCode.pr("set(PICO_BOARD \"" + bProps[0] + "\")");
}
break;
default:
cMakeCode.pr("project(" + executableName + " LANGUAGES C)");
cMakeCode.newLine();
}

cMakeCode.pr("project(" + executableName + " LANGUAGES C)");
cMakeCode.newLine();

// The Test build type is the Debug type plus coverage generation
cMakeCode.pr("if(CMAKE_BUILD_TYPE STREQUAL \"Test\")");
cMakeCode.pr(" set(CMAKE_BUILD_TYPE \"Debug\")");
Expand All @@ -153,6 +168,8 @@ CodeBuilder generateCMakeCode(
+ " gcc\")");
cMakeCode.pr(" endif()");
cMakeCode.pr("endif()");
// remove warnings for making building easier
cMakeCode.pr("set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -w\")");
petervdonovan marked this conversation as resolved.
Show resolved Hide resolved

cMakeCode.pr("# Require C11");
cMakeCode.pr("set(CMAKE_C_STANDARD 11)");
Expand Down Expand Up @@ -200,18 +217,28 @@ CodeBuilder generateCMakeCode(
}
cMakeCode.newLine();

if (targetConfig.platformOptions.platform == Platform.ZEPHYR) {
cMakeCode.pr(
setUpMainTargetZephyr(
hasMain,
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
} else {
cMakeCode.pr(
setUpMainTarget.getCmakeCode(
hasMain,
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
// Setup main target for different platforms
switch (targetConfig.platformOptions.platform) {
case ZEPHYR:
cMakeCode.pr(
setUpMainTargetZephyr(
hasMain,
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
break;
case RP2040:
cMakeCode.pr(
setUpMainTargetRp2040(
hasMain,
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
break;
default:
cMakeCode.pr(
setUpMainTarget.getCmakeCode(
hasMain,
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
}

// Ensure that the math library is linked
Expand All @@ -230,6 +257,27 @@ CodeBuilder generateCMakeCode(
cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC include/core/modal_models)");
cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC include/core/utils)");

// post target definition board configurations
if (targetConfig.platformOptions.board != null) {
switch (targetConfig.platformOptions.platform) {
case RP2040:
String[] bProps = targetConfig.platformOptions.board.split(":");
gundralaa marked this conversation as resolved.
Show resolved Hide resolved
cMakeCode.pr("# Set pico-sdk default build configurations");
// uart ouput option provided
if (bProps.length > 1 && bProps[1].equals("uart")) {
cMakeCode.pr("pico_enable_stdio_usb(${LF_MAIN_TARGET} 0)");
cMakeCode.pr("pico_enable_stdio_uart(${LF_MAIN_TARGET} 1)");
} else if (bProps.length > 1 && bProps[1].equals("usb")) {
cMakeCode.pr("pico_enable_stdio_usb(${LF_MAIN_TARGET} 1)");
cMakeCode.pr("pico_enable_stdio_uart(${LF_MAIN_TARGET} 0)");
} else {
cMakeCode.pr("pico_enable_stdio_usb(${LF_MAIN_TARGET} 1)");
cMakeCode.pr("pico_enable_stdio_uart(${LF_MAIN_TARGET} 1)");
}
break;
}
}

if (targetConfig.auth) {
// If security is requested, add the auth option.
var osName = System.getProperty("os.name").toLowerCase();
Expand All @@ -247,12 +295,13 @@ CodeBuilder generateCMakeCode(
}

if (targetConfig.threading || targetConfig.tracing != null) {
// If threaded computation is requested, add the threads option.
cMakeCode.pr("# Find threads and link to it");
cMakeCode.pr("find_package(Threads REQUIRED)");
cMakeCode.pr("target_link_libraries(${LF_MAIN_TARGET} PRIVATE Threads::Threads)");
cMakeCode.newLine();

if (targetConfig.platformOptions.platform != Platform.RP2040) {
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
// If threaded computation is requested, add the threads option.
cMakeCode.pr("# Find threads and link to it");
cMakeCode.pr("find_package(Threads REQUIRED)");
cMakeCode.pr("target_link_libraries(${LF_MAIN_TARGET} PRIVATE Threads::Threads)");
cMakeCode.newLine();
}
// If the LF program itself is threaded or if tracing is enabled, we need to define
// NUMBER_OF_WORKERS so that platform-specific C files will contain the appropriate functions
cMakeCode.pr("# Set the number of workers to enable threading/tracing");
Expand Down Expand Up @@ -397,4 +446,35 @@ private static String setUpMainTargetZephyr(
code.newLine();
return code.toString();
}

private static String setUpMainTargetRp2040(
edwardalee marked this conversation as resolved.
Show resolved Hide resolved
boolean hasMain, String executableName, Stream<String> cSources) {
var code = new CodeBuilder();
// initialize sdk
code.pr("pico_sdk_init()");
code.newLine();
code.pr("add_subdirectory(core)");
code.pr("target_link_libraries(core PUBLIC pico_stdlib)");
code.pr("target_link_libraries(core PUBLIC pico_multicore)");
code.pr("target_link_libraries(core PUBLIC pico_sync)");
code.newLine();
code.pr("set(LF_MAIN_TARGET " + executableName + ")");

if (hasMain) {
code.pr("# Declare a new executable target and list all its sources");
code.pr("add_executable(");
} else {
code.pr("# Declare a new library target and list all its sources");
code.pr("add_library(");
}
code.indent();
code.pr("${LF_MAIN_TARGET}");
cSources.forEach(code::pr);
code.unindent();
code.pr(")");
code.newLine();
code.pr("pico_add_extra_outputs(${LF_MAIN_TARGET})");
code.newLine();
return code.toString();
}
}
10 changes: 10 additions & 0 deletions core/src/main/java/org/lflang/generator/c/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@ protected void copyTargetFiles() throws IOException {
FileUtil.copyFileFromClassPath(
"/lib/platform/zephyr/Kconfig", fileConfig.getSrcGenPath(), true);
}

// For the pico src-gen, copy over vscode configurations for debugging
if (targetConfig.platformOptions.platform == Platform.RP2040) {
Path vscodePath = Path.of(fileConfig.getSrcGenPath() + File.separator + ".vscode");
gundralaa marked this conversation as resolved.
Show resolved Hide resolved
// If pico-sdk-path not defined, this can be used to pull the sdk into src-gen
FileUtil.copyFileFromClassPath(
"/lib/platform/rp2040/pico_sdk_import.cmake", fileConfig.getSrcGenPath(), true);
// VS Code configurations
FileUtil.copyFileFromClassPath("/lib/platform/rp2040/launch.json", vscodePath, true);
}
}

////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ private String generateMainFunction() {
" int res = lf_reactor_c_main(0, NULL);",
" exit(res);",
"}");
} else if (targetConfig.platformOptions.platform == Platform.RP2040) {
// Pico platform cannont use command line args.
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
return String.join("\n", "int main(void) {", " return lf_reactor_c_main(0, NULL);", "}");
} else {
return String.join(
"\n",
Expand Down
29 changes: 29 additions & 0 deletions core/src/main/resources/lib/platform/rp2040/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug",
"cwd": "${workspaceRoot}",
"executable": "${command:cmake.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
// This may need to be "arm-none-eabi-gdb" for some previous builds
"gdbPath" : "gdb-multiarch",
"device": "RP2040",
"configFiles": [
"interface/cmsis-dap.cfg",
"target/rp2040.cfg"
],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToEntryPoint": "main",
// Work around for stopping at main on restart
"postRestartCommands": [
"break main",
"continue"
],
"showDevDebugOutput": "raw",
"openOCDLaunchCommands": ["adapter speed 5000"]
}
]
}
73 changes: 73 additions & 0 deletions core/src/main/resources/lib/platform/rp2040/pico_sdk_import.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake

# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()

if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()

set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")

if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()

if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()

get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()

set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()

set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)

include(${PICO_SDK_INIT_CMAKE_FILE})