Skip to content

Commit

Permalink
🎉 Created package for libhal linux on the new repo
Browse files Browse the repository at this point in the history
  • Loading branch information
PhazonicRidley committed May 9, 2024
1 parent 7326ad1 commit 4ec3ee4
Show file tree
Hide file tree
Showing 26 changed files with 914 additions and 125 deletions.
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ libhal_test_and_make_library(

SOURCES
src/output_pin.cpp
src/input_pin.cpp
src/i2c.cpp
src/serial.cpp

TEST_SOURCES
tests/output_pin.test.cpp
Expand All @@ -33,4 +36,4 @@ libhal_test_and_make_library(
LINK_LIBRARIES
libhal::libhal
libhal::util
)
)
47 changes: 47 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM --platform=arm64 ubuntu:22.04

RUN apt update && apt upgrade -y
RUN apt install gcc g++ valgrind neofetch git wget python3-pip clang-format software-properties-common locales pkg-config automake autoconf autoconf-archive libtool m4 -y

RUN wget https://apt.llvm.org/llvm.sh
RUN chmod +x llvm.sh
RUN ./llvm.sh 17
RUN apt install libc++-17-dev libc++abi-17-dev -y

RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN apt install -y build-essential g++-12
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
RUN add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main"
RUN apt-get install clang-tidy-17 -y
RUN python3 -m pip install "conan>=2.2.2" cmake

# Compile gpiod
WORKDIR /opt
RUN git clone https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
RUN locale-gen "en_US.UTF-8"
WORKDIR /opt/libgpiod
RUN ./autogen.sh --enable-bindings-cxx
RUN make -j
RUN make install

# Configure conan for libhal
RUN conan remote add libhal-trunk https://libhal.jfrog.io/artifactory/api/conan/trunk-conan
RUN conan config install -sf profiles/baremetal/v2 https://github.com/libhal/conan-config.git
RUN conan profile detect --force
# Set profile based on arch x86 or arm64
# RUN if [[ -z "$arg" ]] ; then echo Argument not provided ; else echo Argument is $arg ; fi
RUN conan config install -sf profiles/armv8/linux/ -tf profiles https://github.com/libhal/conan-config.git

# Test by building demos
RUN mkdir /test_libhal
WORKDIR /test_libhal
RUN git clone https://github.com/libhal/libhal-lpc40
WORKDIR /test_libhal/libhal-lpc40
RUN conan config install -sf conan/profiles/v2 -tf profiles https://github.com/libhal/libhal-lpc40.git
RUN conan config install -tf profiles -sf conan/profiles/v1 https://github.com/libhal/arm-gnu-toolchain.git
RUN conan build demos -pr lpc4078 -pr arm-gcc-12.3 -s build_type=MinSizeRel -b missing

RUN mkdir /code
WORKDIR /code

CMD ["/bin/bash"]
40 changes: 8 additions & 32 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,46 +33,22 @@ class libhal_linux_conan(ConanFile):
python_requires = "libhal-bootstrap/[^1.0.0]"
python_requires_extend = "libhal-bootstrap.library"

options = {
"platform": [
"profile1",
"profile2",
"ANY"
],
}

default_options = {
"platform": "ANY",
}

@property
def _use_linker_script(self):
return (self.options.platform == "profile1" or
self.options.platform == "profile2")

def add_linker_scripts_to_link_flags(self):
platform = str(self.options.platform)
self.cpp_info.exelinkflags = [
"-L" + os.path.join(self.package_folder, "linker_scripts"),
"-T" + os.path.join("libhal-linux", platform + ".ld"),
]

def requirements(self):
# Replace with appropriate processor library
self.requires("libhal-armcortex/[^3.0.2]")
self.requires("libhal/[^3.3.0]", transitive_headers=True)
self.requires("libhal-util/[^4.1.0]", transitive_headers=True)


def package_info(self):
self.cpp_info.set_property("cmake_target_name", "libhal::linux")
self.cpp_info.libs = ["libhal-linux"]

if self.settings.os == "baremetal" and self._use_linker_script:
self.add_linker_scripts_to_link_flags()

self.buildenv_info.define("LIBHAL_PLATFORM",
str(self.options.platform))
self.buildenv_info.define("LIBHAL_PLATFORM_LIBRARY",
"linux")

def package_id(self):
if self.info.options.get_safe("platform"):
del self.info.options.platform

self.buildenv_info.define("LIBHAL_PLATFORM",
"linux")
self.buildenv_info.define("LIBHAL_PLATFORM_LIBRARY",
"linux")
1 change: 1 addition & 0 deletions datasheets/placeholder.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I am building a (free) operating system, just a small project, not meant to be anything large
33 changes: 22 additions & 11 deletions demos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,29 @@
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.15)
cmake_minimum_required(VERSION 3.20)

# Set project name to demos
project(demos LANGUAGES CXX)
project(linux_demos VERSION 0.0.1 LANGUAGES CXX)

libhal_build_demos(
DEMOS
blinker
# Generate compile commands for anyone using our libraries.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

PACKAGES
libhal-linux
# Always run this custom target by making it depend on ALL
# add_custom_target(copy_compile_commands ALL
# COMMAND ${CMAKE_COMMAND} -E copy_if_different
# ${CMAKE_BINARY_DIR}/compile_commands.json
# ${CMAKE_SOURCE_DIR}/compile_commands.json
# DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json)

LINK_LIBRARIES
libhal::linux
)

find_package(libhal-linux REQUIRED CONFIG)

set(DEMOS gpio blinker i2c_test uart steady_clock_test)
foreach(DEMO ${DEMOS})
message(STATUS "Generating Demo for \"${PROJECT_NAME}_${DEMO}")
add_executable(${PROJECT_NAME}_${DEMO} main.cpp applications/${DEMO}.cpp)
target_include_directories(${PROJECT_NAME}_${DEMO} PUBLIC .)
target_compile_features(${PROJECT_NAME}_${DEMO} PRIVATE cxx_std_23)
target_link_libraries(${PROJECT_NAME}_${DEMO} PRIVATE libhal::linux -static-libstdc++)

endforeach()
7 changes: 4 additions & 3 deletions demos/applications/blinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
// limitations under the License.

#include <libhal-linux/output_pin.hpp>
#include <libhal-armcortex/dwt_counter.hpp>
#include <libhal-linux/steady_clock.hpp>
#include <libhal-util/steady_clock.hpp>
#include <libhal/steady_clock.hpp>

void application()
{
using namespace hal::literals;
// TODO(libhal-target): Set the correct frequency and output pin driver
hal::cortex_m::dwt_counter clock(1.0_MHz);
hal::linux::output_pin led;
hal::gnu_linux::output_pin led("/dev/gpiochip0", 2);
auto clock = hal::gnu_linux::steady_clock<std::chrono::steady_clock>();

while (true) {
using namespace std::chrono_literals;
Expand Down
39 changes: 39 additions & 0 deletions demos/applications/gpio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2024 Khalil Estell
//
// 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.

#include <iostream>
#include <libhal-linux/input_pin.hpp>
#include <libhal-linux/output_pin.hpp>
#include <libhal/error.hpp>
#include <unistd.h>

void application()
{
auto output_gpio = hal::gnu_linux::output_pin("/dev/gpiochip0", 2);
auto input_gpio = hal::gnu_linux::input_pin("/dev/gpiochip0", 3);
std::cout << "blinking gpio 2 on gpiochip0\n";
bool state = output_gpio.level();
bool saved_state = false;
while (true) {
output_gpio.level(state);
saved_state = output_gpio.level();
std::cout << "current state: " << saved_state << std::endl;
sleep(1);
state ^= 1;
if (!input_gpio.level()) {
std::cout << "quiting, bye bye\n";
break;
}
}
}
51 changes: 51 additions & 0 deletions demos/applications/i2c_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2024 Khalil Estell
//
// 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.

#include <array>
#include <iostream>
#include <libhal-linux/i2c.hpp>
#include <libhal-util/i2c.hpp>
#include <libhal/error.hpp>
#include <unistd.h>

double rad_to_deg(double rad)
{
return rad * 180 / 3.14;
}

void print_data(std::array<hal::byte, 6>& data)
{
uint16_t x = data[0] << 8 | data[1];
uint16_t y = data[2] << 8 | data[3];
uint16_t z = data[4] << 8 | data[5];
std::cout << "X: " << x << " Y: " << y << " Z: " << z << std::endl;
}

void application()
{
auto bus = hal::gnu_linux::i2c("/dev/i2c-1");
const auto addr = 0x68;
const auto wake_sensor = std::array<hal::byte, 2>{ 0x6B, 0 };
hal::write(bus, addr, wake_sensor);
const auto set_scale = std::array<hal::byte, 2>{ 0xC1, 1 };
while (true) {
auto read_buffer = std::array<hal::byte, 6>{};
auto write_op = std::array<hal::byte, 1>{ 0x3B };
std::cout << "write_then_read:\n";
hal::write_then_read(bus, addr, write_op, read_buffer);
// hal::write(bus, addr, write_op);
// hal::read(bus, addr, read_buffer);
print_data(read_buffer);
}
}
32 changes: 32 additions & 0 deletions demos/applications/steady_clock_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 Khalil Estell
//
// 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.

#include <chrono>
#include <iostream>
#include <libhal-linux/steady_clock.hpp>
#include <libhal-util/steady_clock.hpp>
#include <libhal/error.hpp>
#include <unistd.h>

void application()
{
using namespace std::chrono_literals;
using namespace hal::literals;
auto sc = hal::gnu_linux::steady_clock<std::chrono::steady_clock>();
std::cout << "Clock made!\n";
for (int i = 0; i < 10; i++) {
hal::delay(sc, 5s);
std::cout << "Delayed for a second\n";
}
}
29 changes: 29 additions & 0 deletions demos/applications/uart.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <iostream>
#include <libhal-linux/serial.hpp>
#include <libhal-util/serial.hpp>
#include <span>
#include <unistd.h>

void application()
{
std::cout << "UART test\n";
auto serial_file_path = "/dev/serial0";
auto serial_bus = hal::gnu_linux::serial(serial_file_path);
std::string test_str = "Hello from libhal\n";
std::array<hal::byte, 255> input_buffer = { 0 };
while (true) {
hal::print(serial_bus, test_str);
sleep(1);
auto read_res = serial_bus.read(input_buffer);
if (input_buffer.at(0) == '\0') {
std::cout << "Nothing to read\n";
continue;
}
std::cout << "Len of res buffer: " << read_res.data.size()
<< " len of input buffer: " << input_buffer.size() << "\n";
auto subspan = read_res.data.subspan(0, read_res.data.size());
auto read_string = std::string(subspan.begin(), subspan.end());
sleep(1);
std::cout << "Read from serial:" << read_string;
}
}
3 changes: 2 additions & 1 deletion demos/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ class demos(ConanFile):

def requirements(self):
bootstrap = self.python_requires["libhal-bootstrap"]
bootstrap.module.add_demo_requirements(self, is_platform=True)
# bootstrap.module.add_demo_requirements(self, is_platform=True)
# self.requires("libhal-bootstrap/latest")
self.requires("libhal-linux/[^1.0.0 || latest]")
29 changes: 0 additions & 29 deletions demos/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Replace with the correct processor includes
#include <libhal-linux/output_pin.hpp>
#include <libhal-armcortex/dwt_counter.hpp>
#include <libhal-armcortex/system_control.hpp>
#include <libhal-exceptions/control.hpp>
#include <libhal-util/steady_clock.hpp>

// Application function must be implemented by one of the compilation units
// (.cpp) files.
extern void application();

[[noreturn]] void terminate_handler() noexcept
{
using namespace std::chrono_literals;
using namespace hal::literals;
// Replace this with something that makes sense...
hal::cortex_m::dwt_counter clock(12.0_MHz);
hal::linux::output_pin led;

while (true) {
led.level(false);
hal::delay(clock, 100ms);
led.level(true);
hal::delay(clock, 100ms);
led.level(false);
hal::delay(clock, 100ms);
led.level(true);
hal::delay(clock, 1000ms);
}
}

int main()
{
// Add system initialization code here such as changing system clock speed.
// Add necessary code here or delete this and the comment above...

// Set terminate routine...
hal::set_terminate(terminate_handler);

// Run application
application();

// Reset the device if it gets here
hal::cortex_m::reset(); // Replace with something that resets the device
return 0;
}
Loading

0 comments on commit 4ec3ee4

Please sign in to comment.