diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2ea6be16..190b9ef3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,4 +10,4 @@ jobs: steps: - uses: actions/checkout@v1 - name: test - run: make && make examples + run: mkdir build && cd build && cmake .. && make diff --git a/CMAKE_README.md b/CMAKE_README.md new file mode 100644 index 00000000..d34aa4d7 --- /dev/null +++ b/CMAKE_README.md @@ -0,0 +1,95 @@ +# How to use CMake + +This document gives an overview of the basics of cmake and how to use +it to make libraries and executables for `pod-embedded`. + +## Cmake basics + +CMake projects are specified using a `CMakeFiles.txt` in each +library/exectutable directory. + +### Basic CMakeFiles.txt layout +A top level CMakeFiles.txt always contains a `cmake_minimum_required` +and a `project` declaration. The rest is populated with `add_subdirectory`, +calls, which include CMakeFiles.txts from subdirectories. + +### Variables +CMake varaibles are specified using `set(VARIABLE_NAME value...)`, which +sets the variable `VARIABLE_NAME` to any subsequent values (multiple values +will make a list.) + +Eg: + +``` +#set importantDirectory to /usr/local/bin +set(importantDirectory /usr/local/bin) + +#set libraries to list containing middleware, drivers, utils +set(libraries middleware + drivers + utils) +``` + +The fundametnal primitives when defining a cmake project are +executables and libraries. + +## Making a library + +To create a library that is imported by other executables, we use the following + +``` +#Define the project for the library +project(foobarlib VERSION 1.0 + DESCRIPTION "The foobar library" + LANGUAGES CXX) + +#Define the library target called foobar with all of its source directories +#Files specified with respect to CMakeLists.txt for the library +add_library(foobar src/somefile.c + src/bin.c + src/baz.c) + +#Add any header files by specifying the include directory, in this case +#called include +target_include_directories(foobar PUBLIC include) + +#add any library dependencies +target_link_libraries(foobar PUBLIC someotherlibrary verynicedependency) +target_link_libraries(foobar PRIVATE thisonelibrary) + +#export library to cmake file so it can be imported elsewhere +export(TARGETS foobar FILE FoobarConfig.cmake) +``` + +In this example we define a project called `foobarlib` in its own CMakeLists.txt +and define a library called `foobar` with its respective source files. +Then any header files are added by specifying an include directory with `target_include_directories(...)`. Then we link any other libraries `foobar` depends on with `target_link_libraries(...)`. Finally we export the library using `export(...)` so the library can be imported elsewhere in the project. + +### PUBLIC vs PRIVATE vs INTERFACE +Whenever a dependency is specified for a project, you must specify if that dependency +is `PUBLIC`, `PRIVATE` or `INTERFACE`. This changes the availability of the dependencies +you're adding to any project that depends on the library you're writing. + +For example, if library `foo` depends on library `bar` publically, then +any library that depends on `foo` will be linked with headers from `bar`. + +The rule of thumb is: + + * If your source files depend on the library, make it `PRIVATE`. + * If your header files depend on the library, make it `INTERFACE` + * If both of the above are true, make it `PUBLIC` + +Dependencies for executables should always be `PRIVATE`. + +## Making an executable + +To make an executable, simply use + +``` +add_executable(binaryName, sourceFile1.c + sourceFile2.c + sourceFileN.c) +``` + +and specify includes and dependencies with `target_include_directories(...)` and `target_link_libraries(...)` in the same way as with libraries. + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..4236a343 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.1) + +project(PodEmbedded VERSION 1.0 + DESCRIPTION "Pod embedded") + +#put binaries in out/ +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out) + +#add cmake projects from subdirectories +add_subdirectory(embedded/app) +add_subdirectory(embedded/data) +add_subdirectory(embedded/drivers) +add_subdirectory(embedded/examples) +add_subdirectory(embedded/peripherals) +add_subdirectory(embedded/utils) +add_subdirectory(middleware) diff --git a/README.md b/README.md index a3f764be..9c8a2c5a 100644 --- a/README.md +++ b/README.md @@ -2,39 +2,38 @@ [![Actions Status](https://github.com/badgerloop-software/pod-embedded/workflows/CI/badge.svg)](https://github.com/badgerloop-software/pod-embedded/actions) -*Developers: Rohan Daruwala, Ezra Boley* +*Developers: Rohan Daruwala, Ezra Boley, Nic Hodlofski* The embedded repository for Badgerloop's pod in the Hyperloop Competition ## Beaglebone Make Instructions -There are currently 3 sets of targets: +To build all compile targets: -1) Making the main programs (`badgerloop_LV` and `badgerloop_HV`), placed in the `out/` folder +1) Make a directory called build in the root of the repository and enter it ``` -make +mkdir build +cd build ``` -The main target can also be executed in a special debug mode, adding useful -print outs from various modules. Any of the following targets can also take -advantage of the added debug functionality. To build in debug mode, run: +2) Run cmake on the parent directory ``` -make DEBUG=1 +cmake .. ``` -2) Making the examples, placed into the `out/tests` folder +3) Build the project with make ``` -make examples +make ``` -3) Making utilities for showcasing various parts of the pod's functionality +There are currently 3 sets of targets: -``` -make utils -``` +The main programs (`badgerloop_LV` and `badgerloop_HV`) are placed in the `out/` directory + +Tests will be placed in `out/tests`, and utilities in `out/utils`. ### Adding Tests diff --git a/embedded/app/CMakeLists.txt b/embedded/app/CMakeLists.txt new file mode 100644 index 00000000..e23bdf41 --- /dev/null +++ b/embedded/app/CMakeLists.txt @@ -0,0 +1,42 @@ +#setup library for the stuff in src/ because it's used elsewhere >_> +project(applib VERSION 1.0 + DESCRIPTION "main" + LANGUAGES CXX) + +#yeah, it's annoying, but glob has problems with needing to run cmake again, +#and it's SUPER discouraged. +set(dependecies src/bms_fault_checking.c + src/nav.c + src/state_machine.c + src/init.c + src/pressure_fault_checking.c + src/states.c + src/motor.c + src/rms_fault_checking.c + src/transitions.c) + +#required libraries for the main pod executables +set(libraries middleware + data + peripherals + drivers + Threads::Threads) #so pthreads work + +#configure app library +add_library(app ${dependecies}) +target_include_directories(app PUBLIC include) +target_link_libraries(app PRIVATE ${libraries}) + +#export app library so it can be used externally +export(TARGETS app FILE AppLibConfig.cmake) + +#configure HV and LV executables +find_package(Threads REQUIRED) +add_executable(badgerloop_HV main/badgerloop_HV.cpp ${dependecies}) +add_executable(badgerloop_LV main/badgerloop_LV.cpp ${dependecies}) + +target_link_libraries(badgerloop_HV PRIVATE ${libraries}) +target_link_libraries(badgerloop_LV PRIVATE ${libraries}) + +target_include_directories(badgerloop_HV PRIVATE include) +target_include_directories(badgerloop_LV PRIVATE include) diff --git a/embedded/data/CMakeLists.txt b/embedded/data/CMakeLists.txt new file mode 100644 index 00000000..8d6fdd4b --- /dev/null +++ b/embedded/data/CMakeLists.txt @@ -0,0 +1,9 @@ +project(datalib VERSION 1.0 + DESCRIPTION "data" + LANGUAGES CXX) + +add_library(data src/filters.c) + +target_include_directories(data PUBLIC include) + +export(TARGETS data FILE DataConfig.cmake) diff --git a/embedded/drivers/CMakeLists.txt b/embedded/drivers/CMakeLists.txt new file mode 100644 index 00000000..e8f737b6 --- /dev/null +++ b/embedded/drivers/CMakeLists.txt @@ -0,0 +1,11 @@ +project(driverslib VERSION 1.0 + DESCRIPTION "Drivers for the pod" + LANGUAGES C) + +add_library(drivers src/bbgpio.c + src/can.c + src/i2c.c) + +target_include_directories(drivers PUBLIC include) + +export(TARGETS drivers FILE DriversConfig.cmake) diff --git a/embedded/examples/CMakeLists.txt b/embedded/examples/CMakeLists.txt new file mode 100644 index 00000000..50ed1f09 --- /dev/null +++ b/embedded/examples/CMakeLists.txt @@ -0,0 +1,43 @@ +#Define example executables +add_executable(bmsDisplay bmsDisplay.cpp) +add_executable(dashTest dashTest.cpp) +add_executable(navTest navTest.cpp) +add_executable(solenoidTest solenoidTest.c) +add_executable(brakingTest brakingTest.cpp) +add_executable(gpioHvTest gpioHvTest.c) +add_executable(oldMotorTest oldMotorTest.c) +add_executable(retroTest retroTest.c) +add_executable(stateTest stateTest.c) +add_executable(can_test can_test.c) +add_executable(imu_test imu_test.c) +add_executable(presTest presTest.c) + +#Link library dependencies for each example +target_link_libraries(imu_test PRIVATE peripherals data) +target_link_libraries(can_test PRIVATE drivers peripherals data) +target_link_libraries(stateTest PRIVATE peripherals data app) +target_link_libraries(retroTest PRIVATE drivers peripherals data) +target_link_libraries(oldMotorTest PRIVATE drivers middleware peripherals data) +target_link_libraries(presTest PRIVATE middleware peripherals data) +target_link_libraries(dashTest PRIVATE middleware peripherals data app) +target_link_libraries(navTest PRIVATE middleware peripherals data app) +target_link_libraries(brakingTest PRIVATE drivers middleware peripherals data) +target_link_libraries(bmsDisplay PRIVATE middleware peripherals data) +target_link_libraries(gpioHvTest PRIVATE drivers peripherals data) +target_link_libraries(solenoidTest PRIVATE drivers peripherals data) + +#Make sure each executable generates in out/tests +set_target_properties(bmsDisplay + dashTest + navTest + solenoidTest + brakingTest + gpioHvTest + oldMotorTest + retroTest + stateTest + can_test + imu_test + presTest + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/tests) diff --git a/embedded/peripherals/CMakeLists.txt b/embedded/peripherals/CMakeLists.txt new file mode 100644 index 00000000..9926b96a --- /dev/null +++ b/embedded/peripherals/CMakeLists.txt @@ -0,0 +1,24 @@ +project(peripheralslib VERSION 1.0 + DESCRIPTION "Peripherals" + LANGUAGES CXX) +#Define sources for library +add_library(peripherals src/batt.c + src/braking.c + src/hv_iox.c + src/lv_iox.c + src/lv_iox.c + src/NCD9830DBR2G.c + src/retro.c + src/bms.c + src/can_devices.c + src/imu.c + src/mcp23017.c + src/proc_iox.c + src/rms.c) + +target_include_directories(peripherals PUBLIC include) + +target_link_libraries(peripherals PRIVATE data app) +target_link_libraries(peripherals PUBLIC drivers) + +export(TARGETS peripherals FILE PeripheralsConfig.cmake) diff --git a/embedded/utils/CMakeLists.txt b/embedded/utils/CMakeLists.txt new file mode 100644 index 00000000..3ab1c942 --- /dev/null +++ b/embedded/utils/CMakeLists.txt @@ -0,0 +1,12 @@ +#Define exectutables +add_executable(gpioUtil gpioUtil.c) +add_executable(rmsProg rmsProg.c) + +#Link library dependencies +target_link_libraries(gpioUtil PRIVATE drivers peripherals) +target_link_libraries(rmsProg PRIVATE drivers peripherals data) + +#set output directory to out/utils +set_target_properties(gpioUtil rmsProg + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out/utils") diff --git a/middleware/CMakeLists.txt b/middleware/CMakeLists.txt new file mode 100644 index 00000000..1457a7c7 --- /dev/null +++ b/middleware/CMakeLists.txt @@ -0,0 +1,38 @@ +project(middlewarelib VERSION 1.0 + DESCRIPTION "middleware" + LANGUAGES CXX) + +add_library(middleware src/connStat.c + src/HVTCPSocket.cpp + src/HV_Telem_Recv.cpp + src/LVTelemetry_Loop.cpp + src/data_dump.cpp + src/HVTelemetry_Loop.cpp + src/LVTCPSocket.cpp + src/PracticalSocket.cpp) + +target_include_directories(middleware PUBLIC include include/jsonlib) + +target_link_libraries(middleware PRIVATE data peripherals app drivers) + +export(TARGETS middleware FILE MiddlewareConfig.cmake) + +#examples executables +add_executable(HV_Test examples/HV_Test.cpp) +add_executable(LV_DataLoop_test examples/LV_DataLoop_test.cpp) +add_executable(LV_TCP_test examples/LV_TCP_test.cpp src/LVTCPSocket.cpp) + +#link local includes +target_include_directories(HV_Test PUBLIC include) +target_include_directories(LV_DataLoop_test PUBLIC include) +target_include_directories(LV_TCP_test PUBLIC include) + +#link required libraries +target_link_libraries(HV_Test PRIVATE middleware peripherals data) +target_link_libraries(LV_DataLoop_test PRIVATE middleware peripherals) +target_link_libraries(LV_TCP_test PRIVATE data peripherals) + +#put examples into out/tests +set_target_properties(HV_Test LV_DataLoop_test LV_TCP_test + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out/tests")