diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 490780e..cb68ca3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,6 @@ name: ✅ CI on: workflow_dispatch: pull_request: - release: - types: - - published - - deleted push: branches: - main @@ -29,22 +25,27 @@ on: jobs: ci: - uses: libhal/ci/.github/workflows/library.yml@4.x.y + uses: libhal/ci/.github/workflows/library_check.yml@5.x.y secrets: inherit - deploy: - uses: libhal/ci/.github/workflows/deploy.yml@4.x.y + + deploy_all_check: + uses: libhal/ci/.github/workflows/deploy_all.yml@5.x.y secrets: inherit - build_lpc4074: - uses: libhal/ci/.github/workflows/demo_builder.yml@4.x.y + + demo_check_lpc4074: + uses: libhal/ci/.github/workflows/demo_builder.yml@5.x.y with: - profile: lpc4074 - processor_profile: https://github.com/libhal/libhal-armcortex.git - platform_profile: https://github.com/libhal/libhal-lpc40.git + compiler_profile_url: https://github.com/libhal/arm-gnu-toolchain.git + compiler_profile: v1/arm-gcc-12.3 + platform_profile_url: https://github.com/libhal/libhal-lpc40.git + platform_profile: v2/lpc4074 secrets: inherit - build_lpc4078: - uses: libhal/ci/.github/workflows/demo_builder.yml@4.x.y + + demo_check_lpc4078: + uses: libhal/ci/.github/workflows/demo_builder.yml@5.x.y with: - profile: lpc4078 - processor_profile: https://github.com/libhal/libhal-armcortex.git - platform_profile: https://github.com/libhal/libhal-lpc40.git + compiler_profile_url: https://github.com/libhal/arm-gnu-toolchain.git + compiler_profile: v1/arm-gcc-12.3 + platform_profile_url: https://github.com/libhal/libhal-lpc40.git + platform_profile: v2/lpc4078 secrets: inherit diff --git a/conanfile.py b/conanfile.py index 3ba3633..3644434 100644 --- a/conanfile.py +++ b/conanfile.py @@ -19,12 +19,11 @@ import os -required_conan_version = ">=2.0.6" +required_conan_version = ">=2.0.14" class libhal___device___conan(ConanFile): name = "libhal-__device__" - version = "0.0.1" license = "Apache-2.0" url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/libhal/libhal-__device__" @@ -47,23 +46,20 @@ def _compilers_minimum_version(self): "apple-clang": "14.0.0" } - @property - def _bare_metal(self): - return self.settings.os == "baremetal" - def validate(self): if self.settings.get_safe("compiler.cppstd"): check_min_cppstd(self, self._min_cppstd) def build_requirements(self): self.tool_requires("cmake/3.27.1") - self.tool_requires("libhal-cmake-util/3.0.1") - self.test_requires("libhal-mock/[^2.0.1]") + self.tool_requires("libhal-cmake-util/4.0.2") + self.test_requires("boost-ext-ut/1.1.9") + self.test_requires("libhal-mock/[^3.0.0]") def requirements(self): - self.requires("libhal/[^2.0.3]", transitive_headers=True) - self.requires("libhal-util/[^3.0.1]") + self.requires("libhal/[^3.0.0]", transitive_headers=True) + self.requires("libhal-util/[^4.0.0]") def layout(self): cmake_layout(self) diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index 10cd58a..303f2e1 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -16,44 +16,20 @@ cmake_minimum_required(VERSION 3.20) project(demos LANGUAGES CXX) -set(platform_library $ENV{LIBHAL_PLATFORM_LIBRARY}) -set(platform $ENV{LIBHAL_PLATFORM}) - -message(WARNING "${platform_library}") - -if("${platform_library}" STREQUAL "") - message(FATAL_ERROR - "Build environment variable LIBHAL_PLATFORM_LIBRARY is required for " "this project.") -endif() - -find_package(libhal-${platform_library} REQUIRED CONFIG) -find_package(libhal-__device__ REQUIRED CONFIG) -find_package(libhal-util REQUIRED CONFIG) - -set(DEMOS __device__) - -add_library(startup_code - main.cpp - platforms/${platform}.cpp) -target_include_directories(startup_code PUBLIC .) -target_compile_features(startup_code PRIVATE cxx_std_20) -target_link_libraries(startup_code PRIVATE - libhal::${platform_library} - libhal::__device__ - libhal::util) - -foreach(demo IN LISTS DEMOS) - set(current_project ${demo}.elf) - message(STATUS "Generating Demo for \"${current_project}\"") - add_executable(${current_project} applications/${demo}.cpp) - target_include_directories(${current_project} PUBLIC .) - target_compile_features(${current_project} PRIVATE cxx_std_20) - target_compile_options(${current_project} PRIVATE -g) - target_link_options(${current_project} PRIVATE --oslib=semihost) - target_link_libraries(${current_project} PRIVATE - libhal::${platform_library} - libhal::__device__ - libhal::util - startup_code) - libhal_post_build(${current_project}) -endforeach() +libhal_build_demos( + DEMOS + __device__ + + PACKAGES + libhal-__device__ + prebuilt-picolibc + + LINK_LIBRARIES + libhal::__device__ + picolibc + + LINK_FLAGS + -Wl,--wrap=__cxa_allocate_exception + -Wl,--wrap=__cxa_free_exception + -Wl,--wrap=__cxa_call_unexpected +) diff --git a/demos/applications/__device__.cpp b/demos/applications/__device__.cpp index 8043849..75ecebc 100644 --- a/demos/applications/__device__.cpp +++ b/demos/applications/__device__.cpp @@ -17,7 +17,7 @@ #include "../hardware_map.hpp" -hal::status application(hardware_map& p_map) +void application(hardware_map& p_map) { using namespace std::chrono_literals; using namespace hal::literals; @@ -31,6 +31,4 @@ hal::status application(hardware_map& p_map) hal::delay(clock, 500ms); hal::print(console, "Hello, world\n"); } - - return hal::success(); } diff --git a/demos/conanfile.py b/demos/conanfile.py index 4877000..e729b90 100644 --- a/demos/conanfile.py +++ b/demos/conanfile.py @@ -24,13 +24,14 @@ class demos(ConanFile): def build_requirements(self): self.tool_requires("cmake/3.27.1") - self.tool_requires("libhal-cmake-util/1.0.0") + self.tool_requires("libhal-cmake-util/4.0.2") def requirements(self): + self.requires(f"prebuilt-picolibc/{self.settings.compiler.version}") if str(self.options.platform).startswith("lpc40"): - self.requires("libhal-lpc40/[^2.1.5]") - self.requires("libhal-__device__/0.0.1") - self.requires("libhal-util/[^3.0.1]") + self.requires("libhal-lpc40/[^3.0.0]") + self.requires("libhal-__device__/[>=0.0.0]") + self.requires("libhal-util/[^4.0.0]") def layout(self): platform_directory = "build/" + str(self.options.platform) diff --git a/demos/hardware_map.hpp b/demos/hardware_map.hpp index 3794348..0567aad 100644 --- a/demos/hardware_map.hpp +++ b/demos/hardware_map.hpp @@ -23,10 +23,9 @@ struct hardware_map hal::serial* console; hal::steady_clock* clock; hal::callback reset; + // Add more driver interfaces here ... }; -// Application function must be implemented by one of the compilation units -// (.cpp) files. -hal::status application(hardware_map& p_map); -hal::status initialize_processor(); -hal::result initialize_platform(); +// Application function is implemented by one of the .cpp files. +void application(hardware_map& p_map); +hardware_map initialize_platform(); diff --git a/demos/main.cpp b/demos/main.cpp index e9bc8b8..872e2ed 100644 --- a/demos/main.cpp +++ b/demos/main.cpp @@ -12,31 +12,84 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include "hardware_map.hpp" +hardware_map global_map{}; + int main() { - auto platform_status = initialize_platform(); - - if (!platform_status) { + try { + global_map = initialize_platform(); + } catch (...) { hal::halt(); } - auto hardware_map = platform_status.value(); - auto is_finished = application(hardware_map); - - if (!is_finished) { - hardware_map.reset(); - } else { - hal::halt(); - } + application(global_map); return 0; } -namespace boost { -void throw_exception([[maybe_unused]] std::exception const& e) -{ - hal::halt(); +namespace __cxxabiv1 { // NOLINT +std::terminate_handler __terminate_handler = []() { // NOLINT + global_map.reset(); +}; } -} // namespace boost + +extern "C" +{ + void _exit([[maybe_unused]] int rc) + { + std::terminate(); + } + + int kill(int, int) + { + return -1; + } + + struct _reent* _impure_ptr = nullptr; // NOLINT + + int getpid() + { + return 1; + } + + std::array exception_storage{}; + + void* __wrap___cxa_allocate_exception(unsigned int p_size) // NOLINT + { + // Size of the GCC exception object header + constexpr size_t header_size = 128; + + if (exception_storage.size() < header_size + p_size) { + std::terminate(); + } + + // Required for GCC's impl to work correctly as it assumes that all bytes + // default to 0. + exception_storage.fill(0); + return exception_storage.data() + header_size; + } + + void __wrap___cxa_call_unexpected(void*) // NOLINT + { + std::terminate(); + } + + void __wrap___cxa_free_exception(void*) // NOLINT + { + // Clear the contents of the storage buffer as the exception runtime expects + // the contents to already be cleared. + exception_storage.fill(0); + } + + void __assert_func([[maybe_unused]] const char* p_file, + [[maybe_unused]] int p_line, + [[maybe_unused]] const char* p_function, + [[maybe_unused]] const char* p_failed_expr) + { + abort(); + } +} // extern "C" diff --git a/demos/platforms/lpc4074.cpp b/demos/platforms/lpc4074.cpp index a319250..179cb18 100644 --- a/demos/platforms/lpc4074.cpp +++ b/demos/platforms/lpc4074.cpp @@ -12,40 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include -#include - -#include -#include -#include - -#include "../hardware_map.hpp" - -hal::result initialize_platform() -{ - using namespace hal::literals; - - // Set the MCU to the maximum clock speed - HAL_CHECK(hal::lpc40::clock::maximum(10.0_MHz)); - - // Create a hardware counter - auto& clock = hal::lpc40::clock::get(); - auto cpu_frequency = clock.get_frequency(hal::lpc40::peripheral::cpu); - static hal::cortex_m::dwt_counter counter(cpu_frequency); - - static std::array uart0_buffer{}; - - // Get and initialize UART0 for UART based logging - static auto uart0 = HAL_CHECK((hal::lpc40::uart::get(0, - uart0_buffer, - hal::serial::settings{ - .baud_rate = 115200, - }))); - - return hardware_map{ - .console = &uart0, - .clock = &counter, - .reset = []() { hal::cortex_m::reset(); }, - }; -} +#include "lpc4078.cpp" diff --git a/demos/platforms/lpc4078.cpp b/demos/platforms/lpc4078.cpp index 9c83314..52bed6e 100644 --- a/demos/platforms/lpc4078.cpp +++ b/demos/platforms/lpc4078.cpp @@ -22,25 +22,24 @@ #include "../hardware_map.hpp" -hal::result initialize_platform() +hardware_map initialize_platform() { using namespace hal::literals; // Set the MCU to the maximum clock speed - HAL_CHECK(hal::lpc40::clock::maximum(10.0_MHz)); + hal::lpc40::maximum(10.0_MHz); // Create a hardware counter - auto& clock = hal::lpc40::clock::get(); - auto cpu_frequency = clock.get_frequency(hal::lpc40::peripheral::cpu); - static hal::cortex_m::dwt_counter counter(cpu_frequency); + static hal::cortex_m::dwt_counter counter( + hal::lpc40::get_frequency(hal::lpc40::peripheral::cpu)); static std::array uart0_buffer{}; // Get and initialize UART0 for UART based logging - static auto uart0 = HAL_CHECK(hal::lpc40::uart::get(0, - uart0_buffer, - hal::serial::settings{ - .baud_rate = 115200, - })); + static hal::lpc40::uart uart0(0, + uart0_buffer, + hal::serial::settings{ + .baud_rate = 115200, + }); return hardware_map{ .console = &uart0, diff --git a/include/libhal-__device__/__device__.hpp b/include/libhal-__device__/__device__.hpp index 48d48bb..60c9344 100644 --- a/include/libhal-__device__/__device__.hpp +++ b/include/libhal-__device__/__device__.hpp @@ -14,7 +14,7 @@ #pragma once -namespace hal::__device__ { // NOLINT -class __device___replace_me // NOLINT +namespace hal::__device__ { // NOLINT +struct __device___replace_me // NOLINT {}; } // namespace hal::__device__ diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 1409fe5..886091a 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -20,9 +20,5 @@ find_package(libhal-__device__ REQUIRED CONFIG) add_executable(${PROJECT_NAME} main.cpp) target_include_directories(${PROJECT_NAME} PUBLIC .) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20) - -if(BAREMETAL) - target_link_options(${PROJECT_NAME} PRIVATE --oslib=semihost) -endif() - +set_target_properties(${PROJECT_NAME} PROPERTIES CXX_EXTENSIONS OFF) target_link_libraries(${PROJECT_NAME} PRIVATE libhal::__device__) diff --git a/test_package/conanfile.py b/test_package/conanfile.py index 157e112..c9a9bd6 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -22,10 +22,6 @@ class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" - @property - def _bare_metal(self): - return self.settings.os == "baremetal" - def build_requirements(self): self.tool_requires("cmake/3.27.1") @@ -37,7 +33,7 @@ def layout(self): def build(self): cmake = CMake(self) - cmake.configure(variables={"BAREMETAL": self._bare_metal}) + cmake.configure() cmake.build() def test(self): diff --git a/test_package/main.cpp b/test_package/main.cpp index cbc63c9..b9a7f66 100644 --- a/test_package/main.cpp +++ b/test_package/main.cpp @@ -19,10 +19,3 @@ int main() { hal::__device__::__device___replace_me bar; } - -namespace boost { -void throw_exception(std::exception const& e) -{ - hal::halt(); -} -} // namespace boost