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

Support for FlexPRET platform #2262

Merged
merged 52 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1db738c
Add support for FlexPRET
magnmaeh Apr 21, 2024
8b50948
Remove printing of board properties
magnmaeh Apr 21, 2024
f688bd0
Add check on requested threads vs. number of HW threads on FlexPRET, …
magnmaeh Apr 22, 2024
38c83ed
Add support for port property.
magnmaeh Apr 23, 2024
cb9e163
Add custom install for FlexPRET; add validation for FlexPRET.
magnmaeh Apr 24, 2024
d492a00
Add check on default value for and PlatformOptions. Also add FlexPR…
magnmaeh Apr 25, 2024
1a9510a
Use Option<T> for PlatformOptions and change code to be compatible wi…
magnmaeh May 1, 2024
dde2b88
Add execution of generated bash script at end of lfc. Currently does …
magnmaeh May 1, 2024
eb831ef
Remove warnings on unused variables in generated code; fix flash opti…
magnmaeh May 2, 2024
ace6553
Add tests for FlexPRET - concurrent is failing for some reason...
magnmaeh May 2, 2024
01fce38
Update reactor-c
magnmaeh May 2, 2024
6c30ff0
Bump reactor-c so tests pass
magnmaeh May 3, 2024
cd8e023
Add info message when FP_SDK_FPGA_INTERFACE_PROGRAM is set because LF…
magnmaeh May 3, 2024
f856e38
Add CI tests.
magnmaeh May 3, 2024
6eced85
Bump reactor-c
magnmaeh May 4, 2024
546248e
Merge branch 'master' into add-flexpret-support
magnmaeh May 4, 2024
05672bc
Merge branch 'master' into add-flexpret-support
magnmaeh May 4, 2024
cdc0702
Fix issue reported by CI
magnmaeh May 4, 2024
30b7fa8
Merge branch 'add-flexpret-support' of github.com:magnmaeh/lingua-fra…
magnmaeh May 4, 2024
7f96f28
Apply spotless
magnmaeh May 4, 2024
5291921
Another formatting.
magnmaeh May 4, 2024
0823188
Bump reactor-c to solve Arduino CI issue
magnmaeh May 4, 2024
b0fb028
Bump reactor-c and fix bug in FlexPRET flash command
magnmaeh May 5, 2024
6f3c71f
Fix format violations
magnmaeh May 5, 2024
3f4b96d
Add FlexPRET tests to CI
magnmaeh May 5, 2024
0c2c1ec
Fix minor bug with setting env variable
magnmaeh May 10, 2024
e718747
Attempt to resolve CI issues
magnmaeh May 10, 2024
9db1410
Merge branch 'master' into add-flexpret-support
magnmaeh May 10, 2024
439a4d7
Apply formatter
magnmaeh May 10, 2024
f8965b5
Bump reactor-c
magnmaeh May 14, 2024
273bf4a
Update branch with master
magnmaeh May 14, 2024
4409f60
Merge branch 'master' into add-flexpret-support
magnmaeh May 15, 2024
f4346f2
Bump reactor-c
magnmaeh May 18, 2024
d6a5aa6
Merge remote-tracking branch 'origin/master' into add-flexpret-support
magnmaeh May 18, 2024
908383c
Add all-embedded.yml top-level workflow
magnmaeh May 18, 2024
b4bf936
Update setup-flexpret/action.yml
magnmaeh May 18, 2024
31019be
Update setup-flexpret/action.yml
magnmaeh May 18, 2024
1b80019
Update setup-flexpret/action.yml
magnmaeh May 18, 2024
5a72997
Update c-flexpret-tests.yml
magnmaeh May 18, 2024
5140709
Update CI
magnmaeh May 18, 2024
ba1f764
Update CI
magnmaeh May 18, 2024
980f30e
Formatting
magnmaeh May 18, 2024
4a8c7e0
Apply suggestions from code review
lhstrh May 19, 2024
2c5a495
Change install of riscv compiler for CI
magnmaeh May 19, 2024
e896e16
Merge branch 'add-flexpret-support' of github.com:magnmaeh/lingua-fra…
magnmaeh May 19, 2024
c956598
Remove redundant code
magnmaeh May 19, 2024
1c8c1dc
Apply suggestions from code review
lhstrh May 21, 2024
59545e4
Remove unecessary exceptions in FlexPRETUtil.java
magnmaeh May 21, 2024
c5922c9
Merge branch 'add-flexpret-support' of github.com:magnmaeh/lingua-fra…
magnmaeh May 21, 2024
5597205
Remove use of FP_SDK_FPGA_INTERFACE_PROGRAM
magnmaeh May 21, 2024
602404e
Merge branch 'master' into add-flexpret-support
magnmaeh May 21, 2024
228d5b1
Bump reactor-c
erlingrj May 22, 2024
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
109 changes: 104 additions & 5 deletions core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ CodeBuilder generateCMakeCode(
}
// remove warnings for rp2040 only to make debug easier
cMakeCode.pr("set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -w\")");
break;
case FLEXPRET:
if (System.getenv("FP_PATH") == null) {
messageReporter.
nowhere().
warning("No FP_PATH environment variable found");
}
if (System.getenv("FP_SDK_PATH") == null) {
messageReporter.
nowhere().
warning("No FP_SDK_PATH environment variable found");
}
cMakeCode.newLine();
cMakeCode.pr("# Include toolchain file and set project");
cMakeCode.pr("include($ENV{FP_SDK_PATH}/cmake/riscv-toolchain.cmake)");
cMakeCode.pr("Project(" + executableName + " LANGUAGES C ASM)");
cMakeCode.newLine();

String selectedBoard = platformOptions.board();
if (selectedBoard != null) {
cMakeCode.pr("# Board selected from target property");
cMakeCode.pr("set(TARGET " + selectedBoard + ")");
cMakeCode.newLine();
} // No TARGET will automatically become emulator

var selectedFlashDevice = platformOptions.port();
if (selectedFlashDevice != null) {
cMakeCode.pr("# Flash device selected from target property");
cMakeCode.pr("set(FP_FLASH_DEVICE " + selectedFlashDevice + ")");
cMakeCode.newLine();
} // No FP_FLASH_DEVICE will automatically become /dev/ttyUSB0

break;
default:
cMakeCode.pr("project(" + executableName + " LANGUAGES C)");
Expand Down Expand Up @@ -289,6 +321,13 @@ CodeBuilder generateCMakeCode(
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
break;
case FLEXPRET:
cMakeCode.pr(
setUpMainTargetFlexPRET(
hasMain,
executableName,
Stream.concat(additionalSources.stream(), sources.stream())));
break;
default:
cMakeCode.pr(
setUpMainTarget.getCmakeCode(
Expand All @@ -312,6 +351,7 @@ CodeBuilder generateCMakeCode(
cMakeCode.pr("target_include_directories(${LF_MAIN_TARGET} PUBLIC include/core/platform)");
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)");
cMakeCode.newLine();

// post target definition board configurations
switch (platformOptions.platform()) {
Expand All @@ -326,6 +366,12 @@ CodeBuilder generateCMakeCode(
cMakeCode.pr("pico_enable_stdio_usb(${LF_MAIN_TARGET} " + (usb ? 1 : 0) + ")");
cMakeCode.pr("pico_enable_stdio_uart(${LF_MAIN_TARGET} " + (uart ? 1 : 0) + ")");
break;
case FLEXPRET:
cMakeCode.pr("# Include necessary commands to generate .mem, .dump, and executable files");
cMakeCode.pr("include($ENV{FP_SDK_PATH}/cmake/fp-app.cmake)");
cMakeCode.pr("fp_add_outputs(${LF_MAIN_TARGET})");
cMakeCode.newLine();
break;
}

if (targetConfig.get(AuthProperty.INSTANCE)) {
Expand All @@ -345,7 +391,8 @@ CodeBuilder generateCMakeCode(
}

if (!targetConfig.get(SingleThreadedProperty.INSTANCE)
&& platformOptions.platform() != Platform.ZEPHYR) {
&& platformOptions.platform() != Platform.ZEPHYR
&& platformOptions.platform() != Platform.FLEXPRET) {
// If threaded computation is requested, add the threads option.
cMakeCode.pr("# Find threads and link to it");
cMakeCode.pr("find_package(Threads REQUIRED)");
Expand All @@ -364,7 +411,7 @@ CodeBuilder generateCMakeCode(
cMakeCode.newLine();
} else {
cMakeCode.pr("# Set flag to indicate a single-threaded runtime");
cMakeCode.pr("target_compile_definitions( ${LF_MAIN_TARGET} PUBLIC LF_SINGLE_THREADED=1)");
cMakeCode.pr("target_compile_definitions(${LF_MAIN_TARGET} PUBLIC LF_SINGLE_THREADED=1)");
}
cMakeCode.newLine();

Expand Down Expand Up @@ -398,9 +445,27 @@ CodeBuilder generateCMakeCode(
cMakeCode.newLine();
}

// Add the install option
cMakeCode.pr(installCode);
cMakeCode.newLine();
if (platformOptions.platform() == Platform.FLEXPRET) {
cMakeCode.pr("""
# FlexPRET SDK generates a script that runs the program;
# install it to the top-level bin
install(
FILES ${CMAKE_SOURCE_DIR}/bin/${LF_MAIN_TARGET}
DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS
OWNER_EXECUTE # Need execute, the others are normal permissions
OWNER_READ
OWNER_WRITE
GROUP_READ
WORLD_READ
)
""");
cMakeCode.newLine();
} else {
// Add the install option
cMakeCode.pr(installCode);
cMakeCode.newLine();
}

// Add the include file
for (String includeFile : targetConfig.getOrDefault(CmakeIncludeProperty.INSTANCE)) {
Expand Down Expand Up @@ -513,4 +578,38 @@ private static String setUpMainTargetRp2040(
code.newLine();
return code.toString();
}

private static String setUpMainTargetFlexPRET(
boolean hasMain, String executableName, Stream<String> cSources) {
var code = new CodeBuilder();
code.pr("add_subdirectory(core)");
code.newLine();

code.pr("# Add FlexPRET's out-of-tree SDK");
code.pr("add_subdirectory($ENV{FP_SDK_PATH} BINARY_DIR)");
code.newLine();

code.pr("set(LF_MAIN_TARGET " + executableName + ")");
code.newLine();

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("target_link_libraries(${LF_MAIN_TARGET} PRIVATE fp-sdk)");
code.newLine();

return code.toString();
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/lflang/generator/c/CCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public boolean runCCompiler(GeneratorBase generator, LFGeneratorContext context)
+ " finished with no errors.");
}
var options = targetConfig.getOrDefault(PlatformProperty.INSTANCE);
if (options.platform() == Platform.ZEPHYR && options.flash()) {
if (options.platform() == Platform.ZEPHYR && options.flash().value()) {
messageReporter.nowhere().info("Invoking flash command for Zephyr");
LFCommand flash = buildWestFlashCommand(options);
int flashRet = flash.run();
Expand Down
122 changes: 109 additions & 13 deletions core/src/main/java/org/lflang/target/property/PlatformProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.lflang.target.property.type.DictionaryType.DictionaryElement;
import org.lflang.target.property.type.PlatformType;
import org.lflang.target.property.type.PlatformType.Platform;

import org.lflang.target.property.type.PrimitiveType;
import org.lflang.target.property.type.TargetPropertyType;
import org.lflang.target.property.type.UnionType;
Expand All @@ -32,16 +33,23 @@ private PlatformProperty() {

@Override
public PlatformOptions initialValue() {
return new PlatformOptions(Platform.AUTO, null, null, 9600, false, 0);
FlashOption flash = new FlashOption(false, false);
BaudRateOption baudRate = new BaudRateOption(false, 0);

return new PlatformOptions(Platform.AUTO, null, null, baudRate, flash, 0);
}

@Override
public PlatformOptions fromAst(Element node, MessageReporter reporter) {
var platform = Platform.AUTO;
String board = null;
String port = null;
var baudRate = 9600;
var flash = false;

int baudRateValue = 0; // Default value
boolean baudRateSet = false;

boolean flashValue = false;
boolean flashSet = false;
var userThreads = 0;
if (node.getLiteral() != null || node.getId() != null) {
platform = new PlatformType().forName(ASTUtils.elementToSingleString(node));
Expand All @@ -55,15 +63,25 @@ public PlatformOptions fromAst(Element node, MessageReporter reporter) {
platform =
new PlatformType().forName(ASTUtils.elementToSingleString(entry.getValue()));
}
case BAUDRATE -> baudRate = ASTUtils.toInteger(entry.getValue());
case BAUDRATE -> {
baudRateSet = true;
baudRateValue = ASTUtils.toInteger(entry.getValue());
}
case BOARD -> board = ASTUtils.elementToSingleString(entry.getValue());
case FLASH -> flash = ASTUtils.toBoolean(entry.getValue());
case FLASH -> {
flashSet = true;
flashValue = ASTUtils.toBoolean(entry.getValue());
}
case PORT -> port = ASTUtils.elementToSingleString(entry.getValue());
case USER_THREADS -> userThreads = ASTUtils.toInteger(entry.getValue());
}
}
}
}

FlashOption flash = new FlashOption(flashSet, flashValue);
BaudRateOption baudRate = new BaudRateOption(baudRateSet, baudRateValue);

return new PlatformOptions(platform, board, port, baudRate, flash, userThreads);
}

Expand All @@ -74,11 +92,62 @@ protected PlatformOptions fromString(String string, MessageReporter reporter) {

@Override
public void validate(TargetConfig config, MessageReporter reporter) {
var platform = config.get(PlatformProperty.INSTANCE).platform;
switch (platform) {
case RP2040:
validateRP2040(config, reporter);
break;
case FLEXPRET:
validateFlexPRET(config, reporter);
break;
default:
break;
}
}

private void validateRP2040(TargetConfig config, MessageReporter reporter) {
var singleThreaded = config.get(SingleThreadedProperty.INSTANCE);
if (!singleThreaded && config.get(PlatformProperty.INSTANCE).platform == Platform.RP2040) {
if (!singleThreaded) {
reporter
.at(config.lookup(this), Literals.KEY_VALUE_PAIR__VALUE)
.error("Platform " + Platform.RP2040 + " does not support threading.");
}
}

private void validateFlexPRET(TargetConfig config, MessageReporter reporter) {
var platform = config.get(PlatformProperty.INSTANCE);
var board = platform.board();
if (board != null) {
if (!board.equals("emulator") && !board.equals("fpga")) {
reporter
.at(config.lookup(this), Literals.KEY_VALUE_PAIR__VALUE)
.error("Platform " + Platform.RP2040 + " does not support threading.");
.error("Only \"emulator\" and \"fpga\" are valid options for board property. Got " + board + ".");
}

// Do validation specific to emulator
if (board.equals("emulator")) {
if (platform.port() != null) {
reporter
.at(config.lookup(this), Literals.KEY_VALUE_PAIR__VALUE)
.warning("Port property ignored for emulator");
}
if (platform.flash().setByUser()) {
reporter
.at(config.lookup(this), Literals.KEY_VALUE_PAIR__VALUE)
.warning("Flash property ignored for emulator");
}
if (platform.baudRate().setByUser()) {
reporter
.at(config.lookup(this), Literals.KEY_VALUE_PAIR__VALUE)
.warning("Baudrate property ignored for emulator");
}
} else {
if (platform.baudRate().setByUser()) {
reporter
.at(config.lookup(this), Literals.KEY_VALUE_PAIR__VALUE)
.error("Baudrate property is entirely controlled by FlexPRET's SDK and cannot be set by the user");
}
}
}
}

Expand All @@ -91,9 +160,9 @@ public Element toAstElement(PlatformOptions value) {
pair.setName(opt.toString());
switch (opt) {
case NAME -> pair.setValue(ASTUtils.toElement(value.platform.toString()));
case BAUDRATE -> pair.setValue(ASTUtils.toElement(value.baudRate));
case BAUDRATE -> pair.setValue(ASTUtils.toElement(value.baudRate().value()));
case BOARD -> pair.setValue(ASTUtils.toElement(value.board));
case FLASH -> pair.setValue(ASTUtils.toElement(value.flash));
case FLASH -> pair.setValue(ASTUtils.toElement(value.flash().value()));
case PORT -> pair.setValue(ASTUtils.toElement(value.port));
case USER_THREADS -> pair.setValue(ASTUtils.toElement(value.userThreads));
}
Expand All @@ -111,6 +180,34 @@ public String name() {
return "platform";
}

/**
* The purpose of this record is to keep track of whether the flash option
* was set by the user or is a default value. This is useful for producing
* warnings or errors.
*/
public record FlashOption(
magnmaeh marked this conversation as resolved.
Show resolved Hide resolved
/**
* Whether the user set the option
*/
boolean setByUser,

/**
* The value (either set by the user or a default value)
*/
boolean value) {}

/** Same reasoning as FlashOption */
public record BaudRateOption(
/**
* Whether the user set the option
*/
boolean setByUser,

/**
* The value (either set by the user or a default value)
*/
int value) {}

/** Settings related to Platform Options. */
public record PlatformOptions(
/**
Expand All @@ -136,17 +233,16 @@ public record PlatformOptions(
* The baud rate used as a parameter to certain embedded platforms. 9600 is a standard rate
* amongst systems like Arduino, so it's the default value.
*/
int baudRate,
BaudRateOption baudRate,

/**
* Whether we should automatically attempt to flash once we compile. This may require the use
* of board and port values depending on the infrastructure you use to flash the boards.
*/
boolean flash,
FlashOption flash,

/**
* The baud rate used as a parameter to certain embedded platforms. 9600 is a standard rate
* amongst systems like Arduino, so it's the default value.
* The number of threads requested by the user.
*/
int userThreads) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum Platform {
LINUX("Linux", true),
MAC("Darwin", true),
ZEPHYR("Zephyr", true),
FLEXPRET("FlexPRET", true),
WINDOWS("Windows", true);

final String cMakeName;
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/lflang/util/ArduinoUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public void buildArduino(FileConfig fileConfig, TargetConfig targetConfig) {
"SUCCESS: Compiling generated code for "
+ fileConfig.name
+ " finished with no errors.");
if (targetConfig.get(PlatformProperty.INSTANCE).flash()) {
if (targetConfig.get(PlatformProperty.INSTANCE).flash().value()) {
if (targetConfig.get(PlatformProperty.INSTANCE).port() != null) {
messageReporter.nowhere().info("Invoking flash command for Arduino");
LFCommand flash =
Expand Down
Loading
Loading