crownstone / bluenet

Bluenet is the in-house firmware on Crownstone hardware. Functions: switching, dimming, energy monitoring, presence detection, indoor localization, switchcraft.
https://crownstone.rocks
91 stars 62 forks source link

Cross-platform runtime tools within cmake #155

Closed mrquincle closed 2 years ago

mrquincle commented 2 years ago

Buffering

Currently there is a method in which we can prevent delays when we execute something through cmake. However, this method is not cross-platform and doesn't pick up runtime values very easily. Each value has to be obtained through a call to get_config.cmake and then piped through the shell (bash) towards the given tool. See https://github.com/crownstone/bluenet/issues/110.

Split up reading config and using config

There's another way to approach this and that's similar on how using cstool is being used. It's divided into two steps:

make write_config
make setup

In this way we first write the configuration values and afterwards we can perform some set up using these values. This means that we can have our favorite cmake-like manner to do cross-platform parsing of all configuration files (the default, the target config file, the target overwrite file, and the runtime file). Then, when running the next target, we only have one file to parse.

How to use config?

Note that the above doesn't yet tell on how to get configuration values as arguments to a given tool. It would be great if we would have something simple that we could use there.

mrquincle commented 2 years ago

Fixing it now in the following way. There is a writescripts.cmake file that only load the configuration (also runtime values) but that also takes particular files and configures those files.

This is the content of writescripts.cmake:

# Load default config
if(DEFINED DEFAULT_CONFIG_FILE)
    if(EXISTS "${DEFAULT_CONFIG_FILE}")
        message(STATUS "Load from default config file: " ${DEFAULT_CONFIG_FILE})
        load_configuration(${DEFAULT_CONFIG_FILE} CONFIG_LIST)
    endif()
endif()

# Load target file
if(DEFINED TARGET_CONFIG_FILE)
    if(EXISTS "${TARGET_CONFIG_FILE}")
        message(STATUS "Load from target config file: " ${TARGET_CONFIG_FILE})
        load_configuration(${TARGET_CONFIG_FILE} CONFIG_LIST)
    endif()
endif()

# Load target overwrite file
if(DEFINED TARGET_CONFIG_OVERWRITE_FILE)
    if(EXISTS ${TARGET_CONFIG_OVERWRITE_FILE})
        message(STATUS "Load from target overwrite file: " ${TARGET_CONFIG_OVERWRITE_FILE})
        load_configuration(${TARGET_CONFIG_OVERWRITE_FILE} CONFIG_LIST)
    endif()
endif()

# Overwrite with runtime config
if(DEFINED CONFIG_FILE)
    if(EXISTS "${CONFIG_FILE}")
        message(STATUS "Load from runtime config file: " ${CONFIG_FILE})
        load_configuration(${CONFIG_FILE} CONFIG_LIST)
    else()
        message(STATUS "Note, there is no runtime config file...")
    endif()
endif()

set(TEMPLATE_DIR ${DEFAULT_MODULES_PATH}/../../../../scripts/templates)
message(STATUS "Generate log-client.sh script")
configure_file(${TEMPLATE_DIR}/log-client.sh.in tmp/log-client.sh)
file(COPY tmp/log-client.sh DESTINATION . FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)

set(CONF_DIR ${DEFAULT_MODULES_PATH}/../..)
message(STATUS "Generate debug-application.sh script")
configure_file(${TEMPLATE_DIR}/debug-application.sh.in tmp/debug-application.sh)
file(COPY tmp/debug-application.sh DESTINATION . FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)

set(CONF_DIR ${DEFAULT_MODULES_PATH}/../..)
message(STATUS "Generate debug-bootloader.sh script")
configure_file(${TEMPLATE_DIR}/debug-bootloader.sh.in tmp/debug-bootloader.sh)
file(COPY tmp/debug-bootloader.sh DESTINATION . FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)

Then we scripts like log-client.sh.in

#!/bin/sh
@WORKSPACE_DIR@/scripts/log-client.py -d @UART_DEVICE@ -l @CMAKE_CURRENT_BINARY_DIR@/extracted_logs.json

These will be configured as log-client.sh scripts in the build directory of the given target:

#!/bin/sh

$HOME/workspace/bluenet/scripts/log-client.py -d /dev/ttyACM0 -l $HOME/workspace/bluenet/build/microapp-pca10056/extracted_logs.json

Same with debug-application.sh.in, etc:

#!/bin/sh

@COMPILER_PATH@/bin/arm-none-eabi-gdb-py --command @CONF_DIR@/gdb/gdbinit --eval-command="target remote localhost:@GDB_PORT@" --command @CONF_DIR@/gdb/gdbstart --exec=@PROJECT_NAME@.elf @PROJECT_NAME@.elf

Now, each of these .sh files can be made cross-platform, or perhaps easier we can have a couple of templates and generate .bat files, etc. when necessary.

mrquincle commented 2 years ago

Added bunch of extra scripts in https://github.com/crownstone/bluenet/tree/cmake-and-runtime branch