diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ea363158c4..7818a02f93 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -305,7 +305,7 @@ test_fatfs_on_host: test_mdns_fuzzer_on_host: stage: host_test - image: $CI_DOCKER_REGISTRY/afl-fuzzer-test$BOT_DOCKER_IMAGE_TAG + image: $CI_DOCKER_REGISTRY/afl-fuzzer-test tags: - host_test dependencies: [] @@ -512,7 +512,7 @@ check_submodule_sync: assign_test: tags: - assign_test - image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG + image: $CI_DOCKER_REGISTRY/ubuntu-test-env stage: assign_test # gitlab ci do not support match job with RegEx or wildcard now in dependencies. # we have a lot build example jobs. now we don't use dependencies, just download all artificats of build stage. diff --git a/components/ulp/test/component.mk b/components/ulp/test/component.mk index ce464a212a..41228b2576 100644 --- a/components/ulp/test/component.mk +++ b/components/ulp/test/component.mk @@ -1 +1,11 @@ -COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive +ULP_APP_NAME = ulp_test + +ULP_S_SOURCES = $(addprefix $(COMPONENT_PATH)/ulp/, \ + test_jumps.S \ + ) + +ULP_EXP_DEP_OBJECTS := test_ulp_as.o + +include $(IDF_PATH)/components/ulp/component_ulp_common.mk + +COMPONENT_ADD_LDFLAGS += -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/ulp/test/test_ulp_as.c b/components/ulp/test/test_ulp_as.c new file mode 100644 index 0000000000..b0a080717a --- /dev/null +++ b/components/ulp/test/test_ulp_as.c @@ -0,0 +1,25 @@ +#include +#include "unity.h" +#include "soc/rtc_cntl_reg.h" +#include "esp32/ulp.h" +#include "ulp_test.h" + + +extern const uint8_t ulp_test_bin_start[] asm("_binary_ulp_test_bin_start"); +extern const uint8_t ulp_test_bin_end[] asm("_binary_ulp_test_bin_end"); + + +TEST_CASE("jumps condition", "[ulp]") +{ + esp_err_t err = ulp_load_binary(0, ulp_test_bin_start, + (ulp_test_bin_end - ulp_test_bin_start) / sizeof(uint32_t)); + TEST_ESP_OK(err); + + REG_CLR_BIT(RTC_CNTL_INT_RAW_REG, RTC_CNTL_ULP_CP_INT_RAW); + TEST_ESP_OK(ulp_run(&ulp_test_jumps - RTC_SLOW_MEM)); + usleep(10000); + + TEST_ASSERT_NOT_EQUAL(0, REG_GET_BIT(RTC_CNTL_INT_RAW_REG, RTC_CNTL_ULP_CP_INT_RAW)); + TEST_ASSERT_EQUAL(0, ulp_jumps_fail & UINT16_MAX); + TEST_ASSERT_EQUAL(1, ulp_jumps_pass & UINT16_MAX); +} diff --git a/components/ulp/test/ulp/test_jumps.S b/components/ulp/test/ulp/test_jumps.S new file mode 100644 index 0000000000..65df226037 --- /dev/null +++ b/components/ulp/test/ulp/test_jumps.S @@ -0,0 +1,101 @@ +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc_io_reg.h" +#include "soc/soc_ulp.h" + + .bss + + .global jumps_pass +jumps_pass: + .long 0 + + .global jumps_fail +jumps_fail: + .long 0 + + .text + .global test_jumps +test_jumps: + + /* tests for LT (less than) condition */ + stage_rst /* cnt = 0 */ + jumps test_fail, 0, LT /* 0 < 0: false, should not jump */ + jumps 1f, 1, LT /* 0 < 1: true, should jump */ + jump test_fail +1: + stage_inc 2 /* cnt = 2 */ + jumps 1f, 3, LT /* 2 < 1: true */ + jump test_fail +1: + jumps test_fail, 1, LT /* 2 < 1: false */ + jumps test_fail, 2, LT /* 2 < 2: false */ + + /* tests for LE (less or equal) condition */ + stage_rst /* cnt = 0 */ + jumps 1f, 0, LE /* 0 <= 0: true */ + jump test_fail +1: + jumps 1f, 1, LE /* 0 <= 1: true */ + jump test_fail +1: + stage_inc 2 /* cnt = 2 */ + jumps test_fail, 1, LE /* 2 <= 1: false */ + + /* tests for EQ (equal) condition */ + stage_rst /* cnt = 0 */ + jumps 1f, 0, EQ /* 0 = 0: true */ + jump test_fail +1: + jumps test_fail, 1, EQ /* 0 = 1: false */ + + stage_inc 1 /* cnt = 1 */ + jumps test_fail, 0, EQ /* 1 = 0: false */ + jumps test_fail, 2, EQ /* 1 = 2: false */ + jumps 1f, 1, EQ /* 1 = 1: true */ +1: + + /* tests for GE (greater or equal) condition */ + stage_rst /* cnt = 0 */ + jumps 1f, 0, GE /* 0 >= 0: true */ + jump test_fail +1: + jumps test_fail, 1, GE /* 0 >= 1: false */ + + stage_inc 1 /* cnt = 1 */ + jumps 1f, 0, GE /* 1 >= 0: true */ + jump test_fail +1: + jumps 1f, 1, GE /* 1 >= 1: true */ + jump test_fail +1: + jumps test_fail, 2, GE /* 1 >= 2: false */ + + /* tests for GT (greater than) condition */ + stage_rst /* cnt = 0 */ + jumps test_fail, 0, GT /* 0 > 0: false */ + jumps test_fail, 1, GE /* 0 > 1: false */ + + stage_inc 1 /* cnt = 1 */ + jumps 1f, 0, GT /* 1 > 0: true */ + jump test_fail +1: + jumps test_fail, 1, GT /* 1 > 1: false */ + jumps test_fail, 2, GT /* 1 > 2: false */ + + jump test_pass + +test_fail: + move r0, jumps_fail + move r1, 1 + st r1, r0, 0 + jump done + +test_pass: + move r0, jumps_pass + move r1, 1 + st r1, r0, 0 + jump done + + .global done +done: + wake + halt diff --git a/docs/en/api-guides/ulp.rst b/docs/en/api-guides/ulp.rst index a5e54d062f..a712b8ec02 100644 --- a/docs/en/api-guides/ulp.rst +++ b/docs/en/api-guides/ulp.rst @@ -15,8 +15,8 @@ Installing the toolchain ULP coprocessor code is written in assembly and compiled using the `binutils-esp32ulp toolchain`_. -1. Download the toolchain using the links listed on this page: -https://github.com/espressif/binutils-esp32ulp/wiki#downloads +1. Download pre-built binaries of the latest toolchain release from: +https://github.com/espressif/binutils-esp32ulp/releases. 2. Extract the toolchain into a directory, and add the path to the ``bin/`` directory of the toolchain to the ``PATH`` environment variable. diff --git a/docs/en/api-guides/ulp_instruction_set.rst b/docs/en/api-guides/ulp_instruction_set.rst index c4519d49d2..71d35d83a0 100644 --- a/docs/en/api-guides/ulp_instruction_set.rst +++ b/docs/en/api-guides/ulp_instruction_set.rst @@ -512,10 +512,29 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low - *Condition*: - *EQ* (equal) – jump if value in stage_cnt == threshold - *LT* (less than) – jump if value in stage_cnt < threshold + - *LE* (less or equal) - jump if value in stage_cnt <= threshold - *GT* (greater than) – jump if value in stage_cnt > threshold + - *GE* (greater or equal) — jump if value in stage_cnt >= threshold **Cycles** - 2 cycles to execute, 2 cycles to fetch next instruction + Conditions *LE*, *LT*, *GE*: 2 cycles to execute, 2 cycles to fetch next instruction + + Conditions *EQ*, *GT* are implemented in the assembler using two **JUMPS** instructions:: + + // JUMPS target, threshold, EQ is implemented as: + + JUMPS next, threshold, LT + JUMPS target, threshold, LE + next: + + // JUMPS target, threshold, GT is implemented as: + + JUMPS next, threshold, LE + JUMPS target, threshold, GE + next: + + Therefore the execution time will depend on the branches taken: either 2 cycles to execute + 2 cycles to fetch, or 4 cycles to execute + 4 cycles to fetch. + **Description** The instruction makes a jump to a relative address if condition is true. Condition is the result of comparison of count register value and threshold value.