From b0af8ad22f3653fe47f292ff11f03ecebcacb3cb Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 26 Jun 2018 12:39:27 +0800 Subject: [PATCH 1/7] =?UTF-8?q?unit-test-app:=20don=E2=80=99t=20include=20?= =?UTF-8?q?project.mk=20for=20ut-=20targets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If project.mk is included twice in recursive invocation of Make, some variables defined on the first pass will not be redefined on the second pass. Rather than cleaning up these variables before calling Make recursively, don’t include IDF project.mk at all, if one of the ut- targets is requested. --- tools/unit-test-app/Makefile | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/tools/unit-test-app/Makefile b/tools/unit-test-app/Makefile index a7b3c45ff..222cfb136 100644 --- a/tools/unit-test-app/Makefile +++ b/tools/unit-test-app/Makefile @@ -5,9 +5,10 @@ PROJECT_NAME := unit-test-app -include $(IDF_PATH)/make/project.mk - ifeq ($(MAKELEVEL),0) +# Set default target +all: + # Define helper targets only when not recursing # List of unit-test-app configurations. @@ -22,8 +23,9 @@ CONFIG_CLEAN_TARGETS := $(addprefix ut-clean-,$(CONFIG_NAMES)) CONFIG_APPLY_TARGETS := $(addprefix ut-apply-config-,$(CONFIG_NAMES)) # Build (intermediate) and output (artifact) directories -BUILDS_DIR := $(PROJECT_PATH)/builds -BINARIES_DIR := $(PROJECT_PATH)/output +PROJECT_DIR := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) +BUILDS_DIR := $(PROJECT_DIR)/builds +BINARIES_DIR := $(PROJECT_DIR)/output # This generates per-config targets (clean, build, apply-config). define GenerateConfigTargets @@ -57,14 +59,14 @@ $(BINARIES_DIR)/%/$(PROJECT_NAME).bin: configs/% mkdir -p $(BINARIES_DIR)/$*/bootloader mkdir -p $(BUILDS_DIR)/$* # Prepare configuration: top-level sdkconfig.defaults file plus the current configuration (configs/$*) - $(summary) CONFIG $(BUILDS_DIR)/$*/sdkconfig + echo CONFIG $(BUILDS_DIR)/$*/sdkconfig rm -f $(BUILDS_DIR)/$*/sdkconfig cat sdkconfig.defaults > $(BUILDS_DIR)/$*/sdkconfig.defaults echo "" >> $(BUILDS_DIR)/$*/sdkconfig.defaults # in case there is no trailing newline in sdkconfig.defaults cat configs/$* >> $(BUILDS_DIR)/$*/sdkconfig.defaults # Build, tweaking paths to sdkconfig and sdkconfig.defaults - $(summary) BUILD_CONFIG $(BUILDS_DIR)/$* + echo BUILD_CONFIG $(BUILDS_DIR)/$* # 'TEST_COMPONENTS=names' option can be added to configs/$* to limit the set # of tests to build for given configuration. # Build all tests if this option is not present. @@ -78,7 +80,7 @@ $(BINARIES_DIR)/%/$(PROJECT_NAME).bin: configs/% TEST_COMPONENTS="$${test_components}" \ TESTS_ALL=$${tests_all} \ EXCLUDE_COMPONENTS="$${exclude_components}" - $(MAKE) print_flash_cmd \ + $(MAKE) --silent print_flash_cmd \ BUILD_DIR_BASE=$(BUILDS_DIR)/$* \ SDKCONFIG=$(BUILDS_DIR)/$*/sdkconfig \ | sed -e 's:'$(BUILDS_DIR)/$*/'::g' \ @@ -113,17 +115,29 @@ ut-help: help: ut-help -.PHONY: ut-build-all-configs ut-clean-all-configs \ - $(CONFIG_BUILD_TARGETS) $(CONFIG_CLEAN_TARGETS) $(CONFIG_APPLY_TARGETS) \ +LOCAL_TARGETS := ut-build-all-configs ut-clean-all-configs \ + $(CONFIG_BUILD_TARGETS) $(CONFIG_CLEAN_TARGETS) \ ut-help +.PHONY: $(LOCAL_TARGETS) + NON_INTERACTIVE_TARGET += ut-apply-config-% ut-clean-% ut-build-% \ ut-build-all-configs ut-clean-all-configs -else # MAKELEVEL == 0 +endif # MAKELEVEL == 0 + + +# When targets defined in this makefile are built, don't need to include the main project makefile. +# This prevents some variables which depend on build directory from being set erroneously. +ifeq ($(filter $(LOCAL_TARGETS),$(MAKECMDGOALS)),) + +include $(IDF_PATH)/make/project.mk + +endif # If recursing, print the actual list of tests being built +ifneq ($(MAKELEVEL),0) $(info TESTS $(foreach comp,$(TEST_COMPONENT_NAMES),$(patsubst %_test,%,$(comp)))) -endif # MAKELEVEL == 0 +endif # MAKELEVEL != 0 From 253930acd1ec91a1add19252edf95f144344a803 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 26 Jun 2018 14:37:36 +0800 Subject: [PATCH 2/7] spi_master, ulp: fix aliasing errors in unit tests --- components/driver/test/test_spi_master.c | 2 +- components/ulp/test/test_ulp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/driver/test/test_spi_master.c b/components/driver/test/test_spi_master.c index 8814088f6..5a7b49010 100644 --- a/components/driver/test/test_spi_master.c +++ b/components/driver/test/test_spi_master.c @@ -759,7 +759,7 @@ static void task_slave(void* arg) do { TEST_ESP_OK( spi_slave_transmit( context->spi, &t, portMAX_DELAY ) ); } while ( t.trans_len == 0 ); - *(uint32_t*)recvbuf = t.trans_len; + memcpy(recvbuf, &t.trans_len, sizeof(uint32_t)); *(uint8_t**)(recvbuf+4) = txdata.start; ESP_LOGI( SLAVE_TAG, "received: %d", t.trans_len ); xRingbufferSend( ringbuf, recvbuf, 8+(t.trans_len+7)/8, portMAX_DELAY ); diff --git a/components/ulp/test/test_ulp.c b/components/ulp/test/test_ulp.c index 197a12b61..766a71742 100644 --- a/components/ulp/test/test_ulp.c +++ b/components/ulp/test/test_ulp.c @@ -271,7 +271,7 @@ TEST_CASE("ulp power consumption in deep sleep", "[ulp][ignore]") { assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 4 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); ulp_insn_t insn = I_HALT(); - RTC_SLOW_MEM[0] = *(uint32_t*) &insn; + memcpy(&RTC_SLOW_MEM[0], &insn, sizeof(insn)); REG_WRITE(SENS_ULP_CP_SLEEP_CYC0_REG, 0x8000); From 7a154d6a4e9c470755faf534ab8d343b2a73ce0f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 27 Jun 2018 14:46:20 +0800 Subject: [PATCH 3/7] heap: fix unit test for the case when less than 10k of IRAM is available --- components/heap/test/test_malloc_caps.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/components/heap/test/test_malloc_caps.c b/components/heap/test/test_malloc_caps.c index 0be5f6a6c..f1db712b7 100644 --- a/components/heap/test/test_malloc_caps.c +++ b/components/heap/test/test_malloc_caps.c @@ -9,6 +9,7 @@ #include "esp_heap_caps.h" #include "esp_spi_flash.h" #include +#include TEST_CASE("Capabilities allocator test", "[heap]") { @@ -38,18 +39,24 @@ TEST_CASE("Capabilities allocator test", "[heap]") TEST_ASSERT((((int)m1)&0xFF000000)==0x3F000000); free(m1); - printf("Freeing; allocating 10K of 32K-capable RAM\n"); - m1 = heap_caps_malloc(10*1024, MALLOC_CAP_32BIT); + //The goal here is to allocate from IRAM. Since there is no external IRAM (yet) + //the following gives size of IRAM-only (not D/IRAM) memory. + size_t free_iram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL) - + heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + size_t alloc32 = MIN(free_iram / 2, 10*1024); + printf("Freeing; allocating %u bytes of 32K-capable RAM\n", alloc32); + m1 = heap_caps_malloc(alloc32, MALLOC_CAP_32BIT); printf("--> %p\n", m1); + //Check that we got IRAM back + TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); free8 = heap_caps_get_free_size(MALLOC_CAP_8BIT); free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT); printf("Free 8bit-capable memory (after 32-bit): %dK, 32-bit capable memory %dK\n", free8, free32); - //Only 32-bit should have gone down by 10K: 32-bit isn't necessarily 8bit capable - TEST_ASSERT(free32<(free32start-10*1024)); + //Only 32-bit should have gone down by alloc32: 32-bit isn't necessarily 8bit capable + TEST_ASSERT(free32<(free32start-alloc32)); TEST_ASSERT(free8==free8start); - //Assume we got IRAM back - TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); free(m1); + printf("Allocating impossible caps\n"); m1= heap_caps_malloc(10*1024, MALLOC_CAP_8BIT|MALLOC_CAP_EXEC); printf("--> %p\n", m1); @@ -57,14 +64,15 @@ TEST_CASE("Capabilities allocator test", "[heap]") printf("Testing changeover iram -> dram"); // priorities will exhaust IRAM first, then start allocating from DRAM for (x=0; x<10; x++) { - m2[x]= heap_caps_malloc(10*1024, MALLOC_CAP_32BIT); + m2[x]= heap_caps_malloc(alloc32, MALLOC_CAP_32BIT); printf("--> %p\n", m2[x]); } TEST_ASSERT((((int)m2[0])&0xFF000000)==0x40000000); TEST_ASSERT((((int)m2[9])&0xFF000000)==0x3F000000); printf("Test if allocating executable code still gives IRAM, even with dedicated IRAM region depleted\n"); // (the allocation should come from D/IRAM) - m1= heap_caps_malloc(10*1024, MALLOC_CAP_EXEC); + free_iram = heap_caps_get_free_size(MALLOC_CAP_EXEC); + m1= heap_caps_malloc(MIN(free_iram / 2, 10*1024), MALLOC_CAP_EXEC); printf("--> %p\n", m1); TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); free(m1); From 81ce7e4afa6dcdd3540bf0bab1d1b1b1da6af161 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 27 Jun 2018 14:47:05 +0800 Subject: [PATCH 4/7] newlib: fix unit test for psram config --- components/newlib/test/test_newlib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c index 2836fc3d2..10d81e163 100644 --- a/components/newlib/test/test_newlib.c +++ b/components/newlib/test/test_newlib.c @@ -124,15 +124,20 @@ static bool fn_in_rom(void *fn, const char *name) TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") { -#ifdef CONFIG_NEWLIB_NANO_FORMAT +#if defined(CONFIG_NEWLIB_NANO_FORMAT) && !defined(CONFIG_SPIRAM_SUPPORT) TEST_ASSERT(fn_in_rom(printf, "printf")); TEST_ASSERT(fn_in_rom(sscanf, "sscanf")); #else TEST_ASSERT_FALSE(fn_in_rom(printf, "printf")); TEST_ASSERT_FALSE(fn_in_rom(sscanf, "sscanf")); #endif +#if !defined(CONFIG_SPIRAM_SUPPORT) TEST_ASSERT(fn_in_rom(atoi, "atoi")); TEST_ASSERT(fn_in_rom(strtol, "strtol")); +#else + TEST_ASSERT_FALSE(fn_in_rom(atoi, "atoi")); + TEST_ASSERT_FALSE(fn_in_rom(strtol, "strtol")); +#endif } #ifndef CONFIG_NEWLIB_NANO_FORMAT From 964087b7c8046a3c8345dd47f5907b7f9e4095e1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 27 Jun 2018 14:47:31 +0800 Subject: [PATCH 5/7] freertos: bump limit for spinlock performance test to 300 cycles --- components/idf_test/include/idf_performance.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/idf_test/include/idf_performance.h b/components/idf_test/include/idf_performance.h index f98f75c31..fc128eecb 100644 --- a/components/idf_test/include/idf_performance.h +++ b/components/idf_test/include/idf_performance.h @@ -11,7 +11,7 @@ /* declare the performance here */ #define IDF_PERFORMANCE_MAX_HTTPS_REQUEST_BIN_SIZE 800 #define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP 200 -#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_PSRAM 270 +#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_PSRAM 300 #define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_UNICORE 130 #define IDF_PERFORMANCE_MAX_ESP_TIMER_GET_TIME_PER_CALL 1000 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 30 From a981e73e22930c8c9c7d9c974e8bc63b47c9f8b2 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 27 Jun 2018 17:16:38 +0800 Subject: [PATCH 6/7] heap: move get_all_caps to IRAM, used in unit test --- components/heap/heap_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/heap/heap_private.h b/components/heap/heap_private.h index 5103cfd17..a8a0ac9fd 100644 --- a/components/heap/heap_private.h +++ b/components/heap/heap_private.h @@ -49,7 +49,7 @@ extern SLIST_HEAD(registered_heap_ll, heap_t_) registered_heaps; bool heap_caps_match(const heap_t *heap, uint32_t caps); /* return all possible capabilities (across all priorities) for a given heap */ -inline static uint32_t get_all_caps(const heap_t *heap) +inline static IRAM_ATTR uint32_t get_all_caps(const heap_t *heap) { if (heap->heap == NULL) { return 0; From f3260cc30f96f56390a14ac961ed06b66e12a64e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 17 Jul 2018 14:10:33 +0300 Subject: [PATCH 7/7] test/uart: fix compilation warning --- components/driver/test/test_uart.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/components/driver/test/test_uart.c b/components/driver/test/test_uart.c index 32223d898..4b93037b8 100644 --- a/components/driver/test/test_uart.c +++ b/components/driver/test/test_uart.c @@ -1,4 +1,5 @@ #include +#include #include "unity.h" #include "test_utils.h" // unity_send_signal #include "driver/uart.h" // for the uart driver access @@ -159,26 +160,19 @@ static uint16_t get_buffer_crc16( uint8_t * frame_ptr, uint16_t length ) static uint16_t buffer_fill_random(uint8_t *buffer, size_t length) { TEST_ASSERT( buffer != NULL); - uint8_t *byte_buffer = (uint8_t *)buffer; - uint32_t random; - // Pcket is too short + // Packet is too short if (length < 4) { return 0; } - for (int i = 0; i < length; i++) { - if (i == 0 || i % 4 == 0) { - // Generates random int32_t number - random = esp_random(); - } - - // Place each byte of the uint32_t random number into buffer - byte_buffer[i] = random >> ((i % 4) * 8); + for (int i = 0; i < length; i += 4) { + uint32_t random = esp_random(); + memcpy(buffer + i, &random, MIN(length - i, 4)); } // Get checksum of the buffer - uint16_t crc = get_buffer_crc16((uint8_t*)byte_buffer, (length - 2)); + uint16_t crc = get_buffer_crc16((uint8_t*)buffer, (length - 2)); // Apply checksum bytes into packet - byte_buffer[length - 2] = (uint8_t)(crc & 0xFF); // Set Low byte CRC - byte_buffer[length - 1] = (uint8_t)(crc >> 8); // Set High byte CRC + buffer[length - 2] = (uint8_t)(crc & 0xFF); // Set Low byte CRC + buffer[length - 1] = (uint8_t)(crc >> 8); // Set High byte CRC return crc; } @@ -241,7 +235,7 @@ static void rs485_slave() if (len > 2) { esp_err_t status = print_packet_data("Received ", slave_data, len); - // If recieved packet is correct then send it back + // If received packet is correct then send it back if (status == ESP_OK) { uart_write_bytes(UART_NUM1, (char*)slave_data, len); good_count++;