Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 1 addition & 29 deletions .github/workflows/rex.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,21 @@ on:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
NCT_PROJECTS: ${{ github.workspace }}/NCT_Projects

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get dependencies
run: sudo apt-get install -y gcc-arm-none-eabi cmake make
- name: Get NCT_Projects headers
uses: actions/checkout@v4
with:
repository: ekoeppen/NCT_Projects
path: NCT_Projects
- name: Get tntk
uses: actions/checkout@v4
with:
repository: ekoeppen/tntk
path: tntk
submodules: recursive
- name: Compile tntk
run: |
cmake -S tntk -B tntk/build
cmake --build tntk/build
sudo cmake --install tntk/build
- name: Get DCL
uses: actions/checkout@v4
with:
repository: pguyot/DCL
path: DCL
- name: Compile DCL
run: |
cmake -S DCL -B DCL/build
cmake --build DCL/build
sudo cmake --install DCL/build
- name: Get Einstein sources
uses: actions/checkout@v4
with:
path: Einstein
- name: Compile the REx
run: |
cmake -S Einstein/Drivers -B Einstein/Drivers/build -DCMAKE_TOOLCHAIN_FILE=cmake/newton-cross.cmake
cmake -S Einstein/Drivers -B Einstein/Drivers/build
cmake --build Einstein/Drivers/build
cmake --install Einstein/Drivers/build
- name: Store the REx
uses: actions/upload-artifact@v4
with:
Expand Down
157 changes: 53 additions & 104 deletions Drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,104 +1,53 @@
cmake_minimum_required(VERSION 3.10)
enable_language(ASM)

set(NCT_PROJECTS $ENV{NCT_PROJECTS})

set(LINK_OPTIONS
-L ${CMAKE_SOURCE_DIR}
-Tprotocol.ld --version-script=protocol.map)

set(INCLUDE_DIRECTORIES
.
${CMAKE_SOURCE_DIR}/..
${NCT_PROJECTS}/DDKIncludes
${NCT_PROJECTS}/DDKIncludes/Bootstrap
${NCT_PROJECTS}/DDKIncludes/CLibrary
${NCT_PROJECTS}/DDKIncludes/CommAPI
${NCT_PROJECTS}/DDKIncludes/Communications
${NCT_PROJECTS}/DDKIncludes/Frames
${NCT_PROJECTS}/DDKIncludes/HAL
${NCT_PROJECTS}/DDKIncludes/Lantern
${NCT_PROJECTS}/DDKIncludes/OS600
${NCT_PROJECTS}/DDKIncludes/Packages
${NCT_PROJECTS}/DDKIncludes/Power
${NCT_PROJECTS}/DDKIncludes/QD
${NCT_PROJECTS}/DDKIncludes/Toolbox
${NCT_PROJECTS}/DDKIncludes/UtilityClasses
${NCT_PROJECTS}/DDKIncludes/PCMCIA
${NCT_PROJECTS}/Includes
${NCT_PROJECTS}/Includes/CLibrary
${NCT_PROJECTS}/Includes/Frames
${NCT_PROJECTS}/Includes/Utilities
${NCT_PROJECTS}/LanternDriver_DDK/Includes
${NCT_PROJECTS}/NSandDDK
${NCT_PROJECTS})

file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/obj)

# -- Shared runtime, containing the NewtonOS APIs and additional glue code

project(Runtime)
add_library(Runtime
Glue.s UGlue.cpp NewtonRuntime/NewtonRuntime.cpp NewtonRuntime/NewtonPublicAPIs.s NativePrimitives.s)
target_include_directories(Runtime PRIVATE ${INCLUDE_DIRECTORIES})
target_link_options(Runtime PRIVATE ${LINK_OPTIONS})

# -- Drivers to interface with the Einstein emulator and host system

macro(define_driver DRIVER)
project(${DRIVER})
add_executable(${DRIVER} ${ARGN})
add_dependencies(${DRIVER} Runtime)
target_link_libraries(${DRIVER} Runtime)
target_include_directories(${DRIVER} PRIVATE ${INCLUDE_DIRECTORIES})
target_link_options(${DRIVER} PRIVATE ${LINK_OPTIONS})
add_custom_command(TARGET ${DRIVER} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_SOURCE_DIR}/obj/$<TARGET_FILE_NAME:${DRIVER}>.pkg
COMMAND ELFtoPKG -o ${CMAKE_SOURCE_DIR}/obj/$<TARGET_FILE_NAME:${DRIVER}>.pkg $<TARGET_FILE_NAME:${DRIVER}>:Einstein -protocol
$<TARGET_FILE:${DRIVER}> -autoLoad -autoRemove)
endmacro()

define_driver(EinsteinBatteryDriver PMainBatteryDriver.cpp PMainBatteryDriver.impl.s PMainBatteryDriverPrims.s)
define_driver(EinsteinStartupDriver TMainStartupDriver.cpp TMainStartupDriver.impl.s)
define_driver(EinsteinPlatformDriver TMainPlatformDriver.cpp TMainPlatformDriver.impl.s TMainPlatformDriverPrims.s)
define_driver(EinsteinSoundDriver PMainSoundDriver.cpp PMainSoundDriver.impl.s PMainSoundDriverPrims.s)
define_driver(EinsteinScreenDriver TMainDisplayDriver.cpp TMainDisplayDriver.impl.s TMainDisplayDriverPrims.s)
define_driver(EinsteinTabletDriver TMainTabletDriver.cpp TMainTabletDriver.impl.s TMainTabletDriverPrims.s)
define_driver(EinsteinVersionString TMainVersionString.cpp TMainVersionString.impl.s)
define_driver(EinsteinSerialVoyager TSerialChipVoyager.cpp TSerialChipVoyager.impl.s TSerialChipVoyagerPrims.s)
define_driver(EinsteinInTranslator PEinsteinInTranslator.cpp PEinsteinInTranslator.impl.s PEinsteinInTranslatorPrims.s)
define_driver(EinsteinOutTranslator PEinsteinOutTranslator.cpp PEinsteinOutTranslator.impl.s PEinsteinOutTranslatorPrims.s)
define_driver(EinsteinNativeCalls TEinsteinNativeCalls.cpp TEinsteinNativeCalls.impl.s TEinsteinNativeCallsPrims.s)
define_driver(EinsteinSerialDriver TSerialChipEinstein.cpp TSerialChipEinstein.impl.s TSerialChipEinsteinPrims.s)
define_driver(EinsteinFlashDriver TEinsteinFlashDriver.cpp TEinsteinFlashDriver.impl.s TEinsteinFlashDriverPrims.s)
add_custom_command(TARGET EinsteinFlashDriver POST_BUILD
COMMAND ${OBJCOPY} -O binary $<TARGET_FILE:EinsteinFlashDriver> ${CMAKE_SOURCE_DIR}/obj/$<TARGET_FILE_NAME:EinsteinFlashDriver>.bin)

# -- Additional packages

add_subdirectory(EinsteinPortEnabler)

# -- Custom target to create the REx, will be always built and installed to the _Data_ directory

project(Einstein)
add_custom_target(Einstein ALL)
add_dependencies(Einstein
EinsteinBatteryDriver
EinsteinStartupDriver
EinsteinFlashDriver
EinsteinPlatformDriver
EinsteinSoundDriver
EinsteinScreenDriver
EinsteinTabletDriver
EinsteinVersionString
EinsteinSerialDriver
EinsteinSerialVoyager
EinsteinInTranslator
EinsteinOutTranslator
EinsteinNativeCalls
portenabler)
add_custom_command(TARGET Einstein
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E rm -f Einstein.rex
COMMAND Rex -o Einstein.rex Einstein.rex.src)
install(FILES ${CMAKE_SOURCE_DIR}/Einstein.rex DESTINATION ${CMAKE_SOURCE_DIR}/../_Data_/)
cmake_minimum_required(VERSION 3.14)
project(EinsteinDrivers)

include(ExternalProject)
include(FetchContent)

# -- Check for ARM toolchain
find_program(ARM_GCC arm-none-eabi-gcc)
if (ARM_GCC)
get_filename_component(ARM_GCC_PATH ${ARM_GCC} DIRECTORY)
message(STATUS "Found ARM GCC at: ${ARM_GCC_PATH}")
message(STATUS "Newton drivers will be built.")

# -- Fetch NCT_Projects (Headers and platform file)
FetchContent_Declare(
nct_projects
GIT_REPOSITORY https://github.com/ekoeppen/NCT_Projects.git
GIT_TAG main
)
FetchContent_MakeAvailable(nct_projects)
set(NCT_PROJECTS_DIR ${nct_projects_SOURCE_DIR})

# -- Setup Host Tools (DCL tools and tntk)
add_subdirectory(host)

# -- Build REx
ExternalProject_Add(drivers_target
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/target
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/target-build
# We depend on the tools targets defined in the host sub-project
DEPENDS dcl_host tntk_host
CMAKE_ARGS
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/newton-cross.cmake
-DREX_TOOL=${DCL_BIN_DIR}/Rex
-DELFTOPKG_TOOL=${DCL_BIN_DIR}/ELFtoPKG
-DELFTONTK_TOOL=${DCL_BIN_DIR}/ELFtoNTK
-DTNTK_TOOL=${TNTK_BIN_DIR}/tntk
-DNCT_PROJECTS=${NCT_PROJECTS_DIR}
-DEINSTEIN_ROOT=${CMAKE_CURRENT_SOURCE_DIR}/..
INSTALL_COMMAND ""
BUILD_ALWAYS 1
)

# Expose the final artifact to the parent project
add_custom_target(EinsteinDrivers ALL)
add_dependencies(EinsteinDrivers drivers_target)

# Copy the finished REx to the build dir so the root can find it
add_custom_command(TARGET EinsteinDrivers POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Einstein.rex ${CMAKE_CURRENT_SOURCE_DIR}/../_Data_/Einstein.rex)
else()
message(STATUS "ARM toolchain NOT found. Skipping driver and host tool build.")
endif()
1 change: 1 addition & 0 deletions Drivers/Einstein.rex.src
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ package "obj/EinsteinSerialVoyager.pkg"
package "obj/EinsteinInTranslator.pkg"
package "obj/EinsteinOutTranslator.pkg"
package "obj/EinsteinNativeCalls.pkg"
package "EinsteinPortEnabler/portenabler.pkg"
package "PrinterDriver/printerDriver.pkg"
// Handlers & NS runtime.
package "NSRuntime/Einstein NS Runtime.pkg"
Expand Down
38 changes: 31 additions & 7 deletions Drivers/EinsteinPortEnabler/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.14)
project(portenabler)
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
enable_language(ASM)

find_program(TNTK tntk)
if(${TNTK} STREQUAL "TNTK-NOTFOUND")
message("tntk not found, using precompiled package")
# Resolve tntk: prefer passed tool, then fetched binary, then system PATH
if(DEFINED TNTK_TOOL)
set(TNTK ${TNTK_TOOL})
elseif(DEFINED TNTK_BINARY_DIR)
set(TNTK ${TNTK_BINARY_DIR}/tntk)
message(STATUS "portenabler: will use fetched tntk at ${TNTK}")
else()
find_program(TNTK tntk)
endif()

# Resolve ELFtoNTK: prefer passed tool, then fetched DCL binary, then system PATH
if(DEFINED ELFTONTK_TOOL)
set(ELFTONTK ${ELFTONTK_TOOL})
elseif(DEFINED DCL_BINARY_DIR)
set(ELFTONTK ${DCL_BINARY_DIR}/ELFtoNTK)
else()
find_program(ELFTONTK ELFtoNTK)
endif()

# If tntk is unavailable even after the above, fall back to precompiled package
if(NOT TNTK)
message(STATUS "tntk not found, using precompiled package")
add_custom_target(portenabler ALL)
return()
endif()

set(NCT_PROJECTS $ENV{NCT_PROJECTS})
add_executable(portenabler main.cpp ../NewtonRuntime/NewtonPublicAPIs.s ../NewtonRuntime/NewtonPrivateAPIs.s)
if (TARGET tntk_ext)
add_dependencies(portenabler tntk_ext)
endif()
if (TARGET dcl)
add_dependencies(portenabler dcl)
endif()
target_include_directories(portenabler PRIVATE
${NCT_PROJECTS}/DDKIncludes
${NCT_PROJECTS}/DDKIncludes/Bootstrap
Expand Down Expand Up @@ -50,8 +74,8 @@ target_link_options(portenabler PRIVATE
--no-allow-shlib-undefined --no-export-dynamic --no-undefined -x
-Tportenabler.ld --version-script=portenabler.ver)
add_custom_command(TARGET portenabler POST_BUILD
COMMAND rm -f ${PROJECT_SOURCE_DIR}/portenabler.ntkc
COMMAND ELFtoNTK -via ${PROJECT_SOURCE_DIR}/portenabler.exp -o ${PROJECT_SOURCE_DIR}/portenabler.ntkc $<TARGET_FILE:portenabler>)
COMMAND ${CMAKE_COMMAND} -E rm -f ${PROJECT_SOURCE_DIR}/portenabler.ntkc
COMMAND ${ELFTONTK} -via ${PROJECT_SOURCE_DIR}/portenabler.exp -o ${PROJECT_SOURCE_DIR}/portenabler.ntkc $<TARGET_FILE:portenabler>)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
add_custom_command(TARGET portenabler POST_BUILD
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND ${TNTK} -c -P ${NCT_PROJECTS}/Platforms portenabler.nprj)
Expand Down
5 changes: 2 additions & 3 deletions Drivers/EinsteinPortEnabler/portenabler.newt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ constant enablerTemplate := {
prefsEntry := GetAppPrefs(kAppSymbol, kPrefsFrame);
foreach port, default in kPrefsFrame do
if prefsEntry.(port) then partFrame:enable(SPrintObject(port), nil, nil);
return removeFrame;
end,

devRemoveScript: func (partFrame) begin
Expand All @@ -73,8 +74,6 @@ constant enablerTemplate := {
end,

InstallScript: func (partFrame) begin
local removeFrame := EnsureInternal ({ removeScript: partFrame.devRemoveScript });
partFrame:devInstallScript (partFrame, removeFrame);
return removeFrame;
return partFrame:devInstallScript (partFrame, EnsureInternal ({ removeScript: partFrame.devRemoveScript }));
end,
};
Binary file modified Drivers/EinsteinPortEnabler/portenabler.pkg
Binary file not shown.
50 changes: 31 additions & 19 deletions Drivers/README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,60 @@
# Einstein ROM Extension

This directory contains the ROM extension (REx) for Einstein, which implements the protocols to interface with the
host OS. The REx is by default part of the Einstein application. The extension contains native parts which implement
NewtonOS protocols, as well as mixed NewtonScript/native extensions in the form of NewtonOS autoparts.
This directory contains the ROM extension (REx) for Einstein, which implements
the protocols to interface with the host OS. The REx is by default part of the
Einstein application. The extension contains native parts which implement
NewtonOS protocols, as well as mixed NewtonScript/native extensions in the
form of NewtonOS autoparts.

## Prerequisites

The REx is a collection of NewtonOS binaries (wrapped into NewtonOS packages), and thus the sources need to be cross
compiled with a NewtonOS compatible tool chain. Compilation also requires NewtonOS specific tools.
The REx is a collection of NewtonOS binaries (wrapped into NewtonOS packages),
and thus the sources need to be cross-compiled with a NewtonOS-compatible tool
chain. Compilation also requires NewtonOS-specific tools.

CMake will fetch missing dependencies automatically except for GCC. If GCC is
not found, the build will be skipped.

### GCC

GCC up to version 12.x as an ARM cross compiler, e.g. [gcc-arm-none-eabi](https://packages.ubuntu.com/search?keywords=gcc-arm-none-eabi&searchon=names)
GCC with support for `armv4` as an ARM cross compiler, e.g. [gcc-arm-none-eabi](https://packages.ubuntu.com/search?keywords=gcc-arm-none-eabi&searchon=names)
for an Ubuntu package, [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)
for the general ARM provided downloads, or a [brew tap](https://github.com/armmbed/homebrew-formulae) for installation
for the general ARM-provided downloads, or a
[brew tap](https://github.com/armmbed/homebrew-formulae) for installation
via Homebrew.

### DCL

Conversion of the compiles binaries requires the `Rex` and `ELFtoPKG` tools. It can be installed by compiling and installing the [DCL](https://github.com/pguyot/DCL).
Conversion of the compiled binaries requires the `Rex` and `ELFtoPKG` tools
provided by [DCL](https://github.com/pguyot/DCL).

### NCT and DDK Headers

The C++ headers can be obtained by cloning this [repository](https://github.com/ekoeppen/NCT_Projects).

The environment variable `NCT_PROJECTS` needs to point to the location of the directory containing the `Includes` and `DDKIncludes` directories.
The C++ headers and Newton Platform file are obtained by cloning this
[repository](https://github.com/ekoeppen/NCT_Projects).

### tntk

[tntk](https://github.com/ekoeppen/tntk) is an optional prerequisite to compile NewtonScript packages. If it not installed, the precompiled
[tntk](https://github.com/ekoeppen/tntk) is an optional prerequisite to
compile NewtonScript packages. If it is not installed, the precompiled
packages are included in the REx.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Building

After installing GCC and the DCL tools, and setting `NCT_PROJECTS` correctly, the REx can be built with `cmake`:
The CMake script will pull in the dependencies and build first the DCL, then
tntk using the CMake file in `./host`, followed by compiling the REx using the
CMake file in `./target`. This is driven by the top level CMake file, e.g.
executing in the directory here:

cmake -S Drivers -B Drivers/build -DCMAKE_TOOLCHAIN_FILE=cmake/newton-cross.cmake
cmake --build Drivers/build
cmake --install Drivers/build
cmake -S . -B build
cmake --build build

## Components

- Protocols: The NewtonOS to host implementation is provided as NewtonOS protocol implementations, which will either
handle the calls directly natively, or will invoke the Einstein drivers via coprocessor instructions
- Protocols: The NewtonOS to host implementation is provided as NewtonOS
protocol implementations, which will either handle the calls directly
natively, or will invoke the Einstein drivers via coprocessor instructions
- NSRuntime: Helper package
- EinsteinPortEnabler: Autopart which will initialize serial drivers when enabled via the Newton preferences app
- EinsteinPortEnabler: Autopart which will initialize serial drivers when
enabled via the Newton preferences app
- Additional packages in the `packages` directory can be included in the REx
Loading