Bladeren bron

Merge branch 'bugfix/ulp_jumps_flags' into 'master'

ULP: document JUMPS instruction flags, add tests

See merge request idf/esp-idf!2949
Ivan Grokhotkov 7 jaren geleden
bovenliggende
commit
a85a8aef62

+ 2 - 2
.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.

+ 11 - 1
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

+ 25 - 0
components/ulp/test/test_ulp_as.c

@@ -0,0 +1,25 @@
+#include <unistd.h>
+#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);
+}

+ 101 - 0
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

+ 2 - 2
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.
 

+ 20 - 1
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.