From 7bc3ceb47bbbdc2cfde028cc1744ddc76c22d99b Mon Sep 17 00:00:00 2001 From: Kyunghwan Kwon Date: Wed, 3 Jan 2024 11:10:06 +0900 Subject: [PATCH] add libmcu --- .github/workflows/ci.yml | 6 +- .gitmodules | 3 + CMakeLists.txt | 7 +- Makefile | 8 +- external/libmcu | 1 + include/metrics.def | 13 +++ ports/{esp_idf => esp-idf}/build.cmake | 33 ++++++- ports/{esp_idf => esp-idf}/partitions.csv | 0 ports/{esp_idf => esp-idf}/sdkconfig.defaults | 4 +- ports/esp-idf/start.c | 27 ++++++ projects/external.cmake | 8 ++ projects/sources.cmake | 24 ++++++ projects/version.cmake | 30 +++++++ src/main.c | 86 ++++++++++--------- 14 files changed, 198 insertions(+), 52 deletions(-) create mode 100644 .gitmodules create mode 160000 external/libmcu create mode 100644 include/metrics.def rename ports/{esp_idf => esp-idf}/build.cmake (70%) rename ports/{esp_idf => esp-idf}/partitions.csv (100%) rename ports/{esp_idf => esp-idf}/sdkconfig.defaults (54%) create mode 100644 ports/esp-idf/start.c create mode 100644 projects/external.cmake create mode 100644 projects/sources.cmake create mode 100644 projects/version.cmake diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 232f670..8c08d49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,10 +38,10 @@ jobs: - name: Process Memory Usage continue-on-error: true run: | - git checkout main $MEMSEG_BASE || cp $MEMSEG_BASE.template $MEMSEG_BASE + git checkout origin/main -- $MEMSEG_BASE || cp $MEMSEG_BASE.template $MEMSEG_BASE . $IDF_PATH/export.sh xtensa-esp32s3-elf-size build/*.elf > $MEMSEG_BASE_TMP - echo -n "\`\`\`\n " > $MEMSEG_RESULT + echo -en "\`\`\`\n " > $MEMSEG_RESULT cat $MEMSEG_BASE_TMP | sed -n 1p >> $MEMSEG_RESULT echo -n "current " >> $MEMSEG_RESULT cat $MEMSEG_BASE_TMP | sed -n 2p >> $MEMSEG_RESULT @@ -51,7 +51,7 @@ jobs: paste $MEMSEG_BASE $MEMSEG_BASE_TMP | \ sed -n 2p | \ awk '{printf "%7d %7d %7d", $7-$1, $8-$2, $9-$3}' >> $MEMSEG_RESULT - echo "\n\`\`\`" >> $MEMSEG_RESULT + echo -e "\n\`\`\`" >> $MEMSEG_RESULT cp $MEMSEG_BASE_TMP $MEMSEG_BASE - name: Comment Memory Size if: github.event_name == 'pull_request' diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c69c68f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/libmcu"] + path = external/libmcu + url = https://github.com/libmcu/libmcu.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f228aa..620563c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,5 +13,10 @@ set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/tools/cmake/toolchain-${IDF_TARGET}.cmak project(template) +include(${CMAKE_SOURCE_DIR}/projects/version.cmake) +include(${CMAKE_SOURCE_DIR}/projects/sources.cmake) +include(${CMAKE_SOURCE_DIR}/projects/external.cmake) + include($ENV{IDF_PATH}/tools/cmake/idf.cmake) -include(${CMAKE_SOURCE_DIR}/ports/esp_idf/build.cmake) + +include(${CMAKE_SOURCE_DIR}/ports/esp-idf/build.cmake) diff --git a/Makefile b/Makefile index aac99bd..b440347 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,9 @@ include version.mk all: build size +.PHONY: build build: - cmake -GNinja -B build - cmake --build build + idf.py build .PHONY: confirm confirm: @@ -55,13 +55,15 @@ clean: confirm size: $(Q)xtensa-esp32s3-elf-size $(BUILDIR)/$(PROJECT).elf +PORT ?= /dev/tty.usbmodem1101 .PHONY: flash -flash: $(BUILDIR)/esp32s3.bin +flash: $(BUILDIR)/$(PROJECT).bin $(Q)python $(IDF_PATH)/components/esptool_py/esptool/esptool.py \ --chip esp32s3 -p $(PORT) -b 921600 \ --before=default_reset --after=no_reset --no-stub \ write_flash \ --flash_mode dio --flash_freq 80m --flash_size keep \ + 0x0 $(BUILDIR)/bootloader/bootloader.bin \ 0x20000 $< \ 0xe000 $(BUILDIR)/partition_table/partition-table.bin \ 0x1d000 $(BUILDIR)/ota_data_initial.bin \ diff --git a/external/libmcu b/external/libmcu new file mode 160000 index 0000000..3038d5b --- /dev/null +++ b/external/libmcu @@ -0,0 +1 @@ +Subproject commit 3038d5b91f2ed705693763f95c682e049048c5e3 diff --git a/include/metrics.def b/include/metrics.def new file mode 100644 index 0000000..853f968 --- /dev/null +++ b/include/metrics.def @@ -0,0 +1,13 @@ +METRICS_DEFINE(HeartbeatInterval) +METRICS_DEFINE(UnixTime) +METRICS_DEFINE(MonotonicTime) +METRICS_DEFINE(ResetCount) +METRICS_DEFINE(ResetReason) +METRICS_DEFINE(Assertions) +METRICS_DEFINE(FaultExceptions) +METRICS_DEFINE(OOM) +METRICS_DEFINE(CPULoad) +METRICS_DEFINE(HeapLowWatermark) +METRICS_DEFINE(MainStackHighWatermark) +METRICS_DEFINE(HeapAllocFailure) +METRICS_DEFINE(BootingTime) diff --git a/ports/esp_idf/build.cmake b/ports/esp-idf/build.cmake similarity index 70% rename from ports/esp_idf/build.cmake rename to ports/esp-idf/build.cmake index 42d5cb3..7c471f5 100644 --- a/ports/esp_idf/build.cmake +++ b/ports/esp-idf/build.cmake @@ -34,17 +34,44 @@ set(build_component_paths_json "[]") configure_file("${IDF_PATH}/tools/cmake/project_description.json.in" "${CMAKE_CURRENT_BINARY_DIR}/project_description.json") +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_LIST_DIR} PORT_SRCS) + +target_include_directories(libmcu PUBLIC + ${CMAKE_SOURCE_DIR}/external/libmcu/modules/common/include/libmcu/posix) +target_compile_definitions(libmcu PRIVATE timer_start=libmcu_timer_start) + +set(LIBMCU_ROOT ${PROJECT_SOURCE_DIR}/external/libmcu) +if ($ENV{IDF_VERSION} VERSION_LESS "5.1.0") + list(APPEND PORT_SRCS ${LIBMCU_ROOT}/ports/freertos/semaphore.c) +endif() + add_executable(${PROJECT_EXECUTABLE} - ${CMAKE_SOURCE_DIR}/src/main.c + ${APP_SRCS} + ${PORT_SRCS} + + ${LIBMCU_ROOT}/ports/esp-idf/board.c + ${LIBMCU_ROOT}/ports/esp-idf/actor.c + ${LIBMCU_ROOT}/ports/esp-idf/pthread.c + ${LIBMCU_ROOT}/ports/esp-idf/wifi.c + ${LIBMCU_ROOT}/ports/esp-idf/metrics.c + ${LIBMCU_ROOT}/ports/esp-idf/nvs_kvstore.c + ${LIBMCU_ROOT}/ports/freertos/timext.c + ${LIBMCU_ROOT}/ports/freertos/hooks.c + ${LIBMCU_ROOT}/ports/posix/logging.c + ${LIBMCU_ROOT}/ports/posix/button.c ) target_compile_definitions(${PROJECT_EXECUTABLE} PRIVATE + ${APP_DEFS} + ESP_PLATFORM=1 xPortIsInsideInterrupt=xPortInIsrContext ) target_include_directories(${PROJECT_EXECUTABLE} PRIVATE + ${APP_INCS} + $ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos $ENV{IDF_PATH}/components/freertos/include/freertos ${CMAKE_CURRENT_LIST_DIR} @@ -60,6 +87,10 @@ target_link_libraries(${PROJECT_EXECUTABLE} idf::esp_http_client idf::esp_https_ota idf::app_update + idf::esp_timer + idf::esp_wifi + + libmcu -Wl,--cref -Wl,--Map=\"${mapfile}\" diff --git a/ports/esp_idf/partitions.csv b/ports/esp-idf/partitions.csv similarity index 100% rename from ports/esp_idf/partitions.csv rename to ports/esp-idf/partitions.csv diff --git a/ports/esp_idf/sdkconfig.defaults b/ports/esp-idf/sdkconfig.defaults similarity index 54% rename from ports/esp_idf/sdkconfig.defaults rename to ports/esp-idf/sdkconfig.defaults index e043cb0..d1ce696 100644 --- a/ports/esp_idf/sdkconfig.defaults +++ b/ports/esp-idf/sdkconfig.defaults @@ -1,6 +1,6 @@ CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="ports/esp_idf/partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="ports/esp_idf/partitions.csv" +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="ports/esp-idf/partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="ports/esp-idf/partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0xE000 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y diff --git a/ports/esp-idf/start.c b/ports/esp-idf/start.c new file mode 100644 index 0000000..14c0fd0 --- /dev/null +++ b/ports/esp-idf/start.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 Kyunghwan Kwon + * + * SPDX-License-Identifier: MIT + */ + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_system.h" + +extern int main(void); +extern void app_main(void); + +static void esp_init(void) +{ + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); +} + +void app_main(void) +{ + esp_init(); + main(); +} diff --git a/projects/external.cmake b/projects/external.cmake new file mode 100644 index 0000000..7a24a01 --- /dev/null +++ b/projects/external.cmake @@ -0,0 +1,8 @@ +add_subdirectory(external/libmcu) + +target_compile_definitions(libmcu PUBLIC + _POSIX_THREADS + _POSIX_C_SOURCE=200809L + LIBMCU_NOINIT=__attribute__\(\(section\(\".rtc.data.libmcu\"\)\)\) + METRICS_USER_DEFINES=\"${PROJECT_SOURCE_DIR}/include/metrics.def\" +) diff --git a/projects/sources.cmake b/projects/sources.cmake new file mode 100644 index 0000000..e942a99 --- /dev/null +++ b/projects/sources.cmake @@ -0,0 +1,24 @@ +set(fpl-src-dirs src) +foreach(dir ${fpl-src-dirs}) + file(GLOB_RECURSE fpl_${dir}_SRCS RELATIVE ${CMAKE_SOURCE_DIR} ${dir}/*.c) + file(GLOB_RECURSE fpl_${dir}_CPP_SRCS RELATIVE ${CMAKE_SOURCE_DIR} ${dir}/*.cpp) + list(APPEND FPL_SRCS ${fpl_${dir}_SRCS} ${fpl_${dir}_CPP_SRCS}) +endforeach() + +set(APP_SRCS + ${CMAKE_SOURCE_DIR}/src/main.c +) +set(APP_INCS + ${CMAKE_SOURCE_DIR}/include +) +set(APP_DEFS + BUILD_DATE=${BUILD_DATE} + VERSION_MAJOR=${VERSION_MAJOR} + VERSION_MINOR=${VERSION_MINOR} + VERSION_PATCH=${VERSION_PATCH} + VERSION_TAG=${VERSION_TAG} + VERSION=${VERSION} + + _POSIX_THREADS + _POSIX_C_SOURCE=200809L +) diff --git a/projects/version.cmake b/projects/version.cmake new file mode 100644 index 0000000..6c16856 --- /dev/null +++ b/projects/version.cmake @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: Apache-2.0 + +execute_process( + COMMAND git describe --long --tags --dirty --always + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +string(REPLACE "-" ";" VERSION_STR ${VERSION}) +list(GET VERSION_STR 0 VERSION_NUMBER) +string(REPLACE "v" "" VERSION_NUMBER_LIST ${VERSION_NUMBER}) +string(REPLACE "." ";" VERSION_NUMBER_LIST ${VERSION_NUMBER_LIST}) +list(GET VERSION_NUMBER_LIST 0 VERSION_MAJOR) + +list(LENGTH VERSION_NUMBER_LIST VERSION_NUMBER_LIST_COUNT) + +if (${VERSION_NUMBER_LIST_COUNT} GREATER_EQUAL 2) +list(GET VERSION_NUMBER_LIST 1 VERSION_MINOR) +list(GET VERSION_STR 1 VERSION_PATCH) +endif() + +if (${VERSION_NUMBER_LIST_COUNT} GREATER_EQUAL 3) + list(GET VERSION_NUMBER_LIST 2 BUILD_NUMBER_ORG) + MATH(EXPR VERSION_PATCH "${BUILD_NUMBER_ORG} + ${VERSION_PATCH}") +endif() + +set(VERSION_TAG "v${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") + +string(TIMESTAMP BUILD_DATE "\"%Y-%m-%dT%H:%M:%SZ\"" UTC) diff --git a/src/main.c b/src/main.c index a282898..129083d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,49 +1,51 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023 Kyunghwan Kwon * - * SPDX-License-Identifier: CC0-1.0 + * SPDX-License-Identifier: MIT */ #include -#include -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_chip_info.h" -#include "esp_flash.h" - -void app_main(void) + +#include "libmcu/board.h" +#include "libmcu/logging.h" + +static size_t logging_stdout_writer(const void *data, size_t size) +{ + unused(size); + static char buf[LOGGING_MESSAGE_MAXLEN]; + size_t len = logging_stringify(buf, sizeof(buf)-1, data); + + buf[len++] = '\n'; + buf[len] = '\0'; + + int rc = fwrite(buf, len, 1, stdout); + + return rc == 0? len : 0; +} + +static void logging_stdout_backend_init(void) { - printf("Hello world!\n"); - - /* Print chip information */ - esp_chip_info_t chip_info; - uint32_t flash_size; - esp_chip_info(&chip_info); - printf("This is %s chip with %d CPU core(s), WiFi%s%s, ", - CONFIG_IDF_TARGET, - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); - - unsigned major_rev = chip_info.revision / 100; - unsigned minor_rev = chip_info.revision % 100; - printf("silicon revision v%d.%d, ", major_rev, minor_rev); - if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) { - printf("Get flash size failed"); - return; - } - - printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); - - printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); - - for (int i = 10; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - printf("Restarting now.\n"); - fflush(stdout); - esp_restart(); + static struct logging_backend log_console = { + .write = logging_stdout_writer, + }; + + logging_add_backend(&log_console); +} + +int main(void) +{ + board_init(); /* should be called very first. */ + logging_init(board_get_time_since_boot_ms); + + logging_stdout_backend_init(); + + const board_reboot_reason_t reboot_reason = board_get_reboot_reason(); + + info("[%s] %s %s", board_get_reboot_reason_string(reboot_reason), + board_get_serial_number_string(), + board_get_version_string()); + + while (1) { + /* hang */ + } }