mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 03:34:32 +02:00
Merge branch 'bugfix/ulp_jumps_flags' into 'master'
ULP: document JUMPS instruction flags, add tests See merge request idf/esp-idf!2949
This commit is contained in:
@@ -305,7 +305,7 @@ test_fatfs_on_host:
|
|||||||
|
|
||||||
test_mdns_fuzzer_on_host:
|
test_mdns_fuzzer_on_host:
|
||||||
stage: host_test
|
stage: host_test
|
||||||
image: $CI_DOCKER_REGISTRY/afl-fuzzer-test$BOT_DOCKER_IMAGE_TAG
|
image: $CI_DOCKER_REGISTRY/afl-fuzzer-test
|
||||||
tags:
|
tags:
|
||||||
- host_test
|
- host_test
|
||||||
dependencies: []
|
dependencies: []
|
||||||
@@ -512,7 +512,7 @@ check_submodule_sync:
|
|||||||
assign_test:
|
assign_test:
|
||||||
tags:
|
tags:
|
||||||
- assign_test
|
- assign_test
|
||||||
image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG
|
image: $CI_DOCKER_REGISTRY/ubuntu-test-env
|
||||||
stage: assign_test
|
stage: assign_test
|
||||||
# gitlab ci do not support match job with RegEx or wildcard now in dependencies.
|
# 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.
|
# we have a lot build example jobs. now we don't use dependencies, just download all artificats of build stage.
|
||||||
|
@@ -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
components/ulp/test/test_ulp_as.c
Normal file
25
components/ulp/test/test_ulp_as.c
Normal file
@@ -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
components/ulp/test/ulp/test_jumps.S
Normal file
101
components/ulp/test/ulp/test_jumps.S
Normal file
@@ -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
|
@@ -15,8 +15,8 @@ Installing the toolchain
|
|||||||
|
|
||||||
ULP coprocessor code is written in assembly and compiled using the `binutils-esp32ulp 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:
|
1. Download pre-built binaries of the latest toolchain release from:
|
||||||
https://github.com/espressif/binutils-esp32ulp/wiki#downloads
|
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.
|
2. Extract the toolchain into a directory, and add the path to the ``bin/`` directory of the toolchain to the ``PATH`` environment variable.
|
||||||
|
|
||||||
|
@@ -512,10 +512,29 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
|||||||
- *Condition*:
|
- *Condition*:
|
||||||
- *EQ* (equal) – jump if value in stage_cnt == threshold
|
- *EQ* (equal) – jump if value in stage_cnt == threshold
|
||||||
- *LT* (less than) – 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
|
- *GT* (greater than) – jump if value in stage_cnt > threshold
|
||||||
|
- *GE* (greater or equal) — jump if value in stage_cnt >= threshold
|
||||||
|
|
||||||
**Cycles**
|
**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**
|
**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.
|
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.
|
||||||
|
Reference in New Issue
Block a user