forked from espressif/esp-idf
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
054e82b4b3 | ||
|
|
7d4a9db191 | ||
|
|
8f81157432 | ||
|
|
5141570f24 | ||
|
|
f86d512672 | ||
|
|
ab341359f5 | ||
|
|
f98da26b38 | ||
|
|
d0cd624d2b | ||
|
|
c8c4bd099e | ||
|
|
36c14cf214 | ||
|
|
a7c9cf3a6b | ||
|
|
9aee394dc6 | ||
|
|
05eb9d155f | ||
|
|
0669fe8f02 | ||
|
|
cabb97f9a9 | ||
|
|
41b1db4dc6 | ||
|
|
8bc76b3684 | ||
|
|
245b753904 | ||
|
|
86a6c21e79 | ||
|
|
8cc0379da1 | ||
|
|
e56bfadc58 | ||
|
|
583e80708b | ||
|
|
5cf4d8a1ec | ||
|
|
ef3c6ac276 | ||
|
|
4129436f7e | ||
|
|
0808a04ee8 | ||
|
|
c99977b67c |
127
.gitlab-ci.yml
127
.gitlab-ci.yml
@@ -1,9 +1,9 @@
|
||||
stages:
|
||||
- build
|
||||
- assign_test
|
||||
- host_test
|
||||
- unit_test
|
||||
- test
|
||||
- test_report
|
||||
- integration_test
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
@@ -133,6 +133,8 @@ build_ssc_01:
|
||||
build_ssc_02:
|
||||
<<: *build_ssc_template
|
||||
|
||||
# If you want to add new build ssc jobs, please add it into dependencies of `assign_test` and `.test_template`
|
||||
|
||||
build_esp_idf_tests:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
@@ -140,7 +142,7 @@ build_esp_idf_tests:
|
||||
- tools/unit-test-app/output
|
||||
- components/idf_test/unit_test/TestCaseAll.yml
|
||||
- components/idf_test/unit_test/CIConfigs/*.yml
|
||||
expire_in: 6 mos
|
||||
expire_in: 1 mos
|
||||
script:
|
||||
- cd tools/unit-test-app
|
||||
- make help # make sure kconfig tools are built in single process
|
||||
@@ -199,6 +201,7 @@ build_examples_06:
|
||||
build_examples_07:
|
||||
<<: *build_examples_template
|
||||
|
||||
# If you want to add new build example jobs, please add it into dependencies of `.example_test_template`
|
||||
|
||||
build_docs:
|
||||
stage: build
|
||||
@@ -222,54 +225,44 @@ build_docs:
|
||||
- make html
|
||||
- ./check_doc_warnings.sh
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
.host_test_template: &host_test_template
|
||||
stage: host_test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
|
||||
tags:
|
||||
- nvs_host_test
|
||||
- host_test
|
||||
dependencies: []
|
||||
|
||||
test_nvs_on_host:
|
||||
<<: *host_test_template
|
||||
script:
|
||||
- cd components/nvs_flash/test_nvs_host
|
||||
- make test
|
||||
|
||||
test_partition_table_on_host:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
<<: *host_test_template
|
||||
tags:
|
||||
- build
|
||||
dependencies: []
|
||||
script:
|
||||
- cd components/partition_table/test_gen_esp32part_host
|
||||
- ./gen_esp32part_tests.py
|
||||
|
||||
test_wl_on_host:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
tags:
|
||||
- wl_host_test
|
||||
<<: *host_test_template
|
||||
artifacts:
|
||||
paths:
|
||||
- components/wear_levelling/test_wl_host/coverage_report.zip
|
||||
dependencies: []
|
||||
script:
|
||||
- cd components/wear_levelling/test_wl_host
|
||||
- make test
|
||||
|
||||
test_multi_heap_on_host:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
tags:
|
||||
- wl_host_test
|
||||
<<: *host_test_template
|
||||
script:
|
||||
- cd components/heap/test_multi_heap_host
|
||||
- ./test_all_configs.sh
|
||||
|
||||
test_build_system:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
tags:
|
||||
- build_test
|
||||
dependencies: []
|
||||
<<: *host_test_template
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
|
||||
- rm -rf test_build_system
|
||||
@@ -277,60 +270,6 @@ test_build_system:
|
||||
- cd test_build_system
|
||||
- ${IDF_PATH}/tools/ci/test_build_system.sh
|
||||
|
||||
test_report:
|
||||
stage: test_report
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
tags:
|
||||
- report
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
variables:
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
|
||||
REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/tools/ModuleDefinition.yml"
|
||||
#dependencies:
|
||||
#We need all UT* and IT* artifacts except for only a few other
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORT_PATH
|
||||
- $LOG_PATH
|
||||
expire_in: 12 mos
|
||||
script:
|
||||
# calc log path
|
||||
- VER_NUM=`git rev-list HEAD | wc -l | awk '{print $1}'`
|
||||
- SHA_ID=`echo $CI_COMMIT_SHA | cut -c 1-7`
|
||||
- REVISION="${VER_NUM}_${SHA_ID}"
|
||||
# replace / to _ in branch name
|
||||
- ESCAPED_BRANCH_NAME=`echo $CI_COMMIT_REF_NAME | sed 's/\//___/g'`
|
||||
# result path and artifacts path
|
||||
- RESULT_PATH="$CI_PROJECT_NAME/$ESCAPED_BRANCH_NAME/$REVISION"
|
||||
- ARTIFACTS_PATH="$GITLAB_HTTP_SERVER/idf/esp-idf/builds/$CI_JOB_ID/artifacts/browse/$CI_COMMIT_SHA"
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script
|
||||
# generate report
|
||||
- TEST_RESULT=Pass
|
||||
- python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || TEST_RESULT=Fail
|
||||
# commit to CI-test-result project
|
||||
- git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git
|
||||
- rm -rf "CI-test-result/RawData/$RESULT_PATH"
|
||||
- cp -R $CI_PROJECT_NAME CI-test-result/RawData
|
||||
- cd CI-test-result
|
||||
# config git user
|
||||
- git config --global user.email "ci-test-result@espressif.com"
|
||||
- git config --global user.name "ci-test-result"
|
||||
# commit test result
|
||||
- git add .
|
||||
- git commit . -m "update test result for $CI_PROJECT_NAME/$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA, pipeline ID $CI_PIPELINE_ID" || exit 0
|
||||
- git push origin master
|
||||
- test "${TEST_RESULT}" = "Pass" || exit 1
|
||||
|
||||
push_master_to_github:
|
||||
stage: deploy
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
@@ -362,8 +301,8 @@ push_master_to_github:
|
||||
|
||||
|
||||
deploy_docs:
|
||||
stage: deploy
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
stage: host_test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
|
||||
tags:
|
||||
- deploy
|
||||
only:
|
||||
@@ -389,8 +328,8 @@ deploy_docs:
|
||||
- ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"
|
||||
|
||||
check_doc_links:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env
|
||||
stage: host_test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env$BOT_DOCKER_IMAGE_TAG
|
||||
tags:
|
||||
- check_doc_links
|
||||
only:
|
||||
@@ -478,21 +417,28 @@ assign_test:
|
||||
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/SSC/ssc_bin
|
||||
|
||||
.example_test_template: &example_test_template
|
||||
stage: test
|
||||
stage: integration_test
|
||||
when: on_success
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
- triggers
|
||||
# gitlab ci do not support match job with RegEx or wildcard now in dependencies.
|
||||
# we have a lot build example jobs and the binaries them exceed the limitation of artifacts.
|
||||
# we can't artifact them in one job. For example test jobs, download all artifacts from previous stages.
|
||||
dependencies:
|
||||
- assign_test
|
||||
- build_examples_00
|
||||
- build_examples_01
|
||||
- build_examples_02
|
||||
- build_examples_03
|
||||
- build_examples_04
|
||||
- build_examples_05
|
||||
- build_examples_06
|
||||
- build_examples_07
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
expire_in: 1 mos
|
||||
variables:
|
||||
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
|
||||
TEST_CASE_PATH: "$CI_PROJECT_DIR/examples"
|
||||
@@ -506,14 +452,13 @@ assign_test:
|
||||
- python Runner.py $TEST_CASE_PATH -c $CONFIG_FILE
|
||||
|
||||
.test_template: &test_template
|
||||
stage: test
|
||||
stage: integration_test
|
||||
when: on_success
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
- triggers
|
||||
allow_failure: true
|
||||
dependencies:
|
||||
- assign_test
|
||||
- build_ssc_00
|
||||
@@ -523,7 +468,7 @@ assign_test:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
expire_in: 1 mos
|
||||
variables:
|
||||
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
|
||||
@@ -564,7 +509,7 @@ nvs_compatible_test:
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
- nvs_wifi.bin
|
||||
expire_in: 6 mos
|
||||
expire_in: 1 mos
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- NVS_Compatible
|
||||
|
||||
@@ -156,6 +156,38 @@ config BT_ACL_CONNECTIONS
|
||||
help
|
||||
Maximum BT/BLE connection count
|
||||
|
||||
config BLE_SCAN_DUPLICATE
|
||||
bool "BLE Scan Duplicate Options "
|
||||
depends on BLUEDROID_ENABLED
|
||||
default y
|
||||
help
|
||||
This select enables parameters setting of BLE scan duplicate.
|
||||
|
||||
config DUPLICATE_SCAN_CACHE_SIZE
|
||||
int "Maximum number of devices in scan duplicate filter"
|
||||
depends on BLE_SCAN_DUPLICATE
|
||||
range 10 200
|
||||
default 20
|
||||
help
|
||||
Maximum number of devices which can be recorded in scan duplicate filter.
|
||||
When the maximum amount of device in the filter is reached, the cache will be refreshed.
|
||||
|
||||
config BLE_MESH_SCAN_DUPLICATE_EN
|
||||
bool "Special duplicate scan mechanism for BLE Mesh scan"
|
||||
depends on BLE_SCAN_DUPLICATE
|
||||
default n
|
||||
help
|
||||
This enables the BLE scan duplicate for special BLE Mesh scan.
|
||||
|
||||
config MESH_DUPLICATE_SCAN_CACHE_SIZE
|
||||
int "Maximum number of Mesh adv packets in scan duplicate filter"
|
||||
depends on BLE_MESH_SCAN_DUPLICATE_EN
|
||||
range 10 200
|
||||
default 50
|
||||
help
|
||||
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
|
||||
When the maximum amount of device in the filter is reached, the cache will be refreshed.
|
||||
|
||||
config SMP_ENABLE
|
||||
bool
|
||||
depends on BLUEDROID_ENABLED
|
||||
|
||||
@@ -264,6 +264,13 @@ typedef enum {
|
||||
3. directed advertising packets addressed to this device.*/
|
||||
} esp_ble_scan_filter_t;
|
||||
|
||||
/// Ble scan duplicate type
|
||||
typedef enum {
|
||||
BLE_SCAN_DUPLICATE_DISABLE = 0x0, /*!< the Link Layer should generate advertising reports to the host for each packet received */
|
||||
BLE_SCAN_DUPLICATE_ENABLE = 0x1, /*!< the Link Layer should filter out duplicate advertising reports to the Host */
|
||||
BLE_SCAN_DUPLICATE_MAX = 0x2, /*!< 0x02 – 0xFF, Reserved for future use */
|
||||
} esp_ble_scan_duplicate_t;
|
||||
|
||||
/// Ble scan parameters
|
||||
typedef struct {
|
||||
esp_ble_scan_type_t scan_type; /*!< Scan type */
|
||||
@@ -279,6 +286,9 @@ typedef struct {
|
||||
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
|
||||
Time = N * 0.625 msec
|
||||
Time Range: 2.5 msec to 10240 msec */
|
||||
esp_ble_scan_duplicate_t scan_duplicate; /*!< The Scan_Duplicates parameter controls whether the Link Layer should filter out
|
||||
duplicate advertising reports (BLE_SCAN_DUPLICATE_ENABLE) to the Host, or if the Link Layer should generate
|
||||
advertising reports for each packet received */
|
||||
} esp_ble_scan_params_t;
|
||||
|
||||
/// Connection update parameters
|
||||
|
||||
@@ -4568,6 +4568,7 @@ void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
|
||||
p_data->ble_set_scan_fil_params.scan_window,
|
||||
p_data->ble_set_scan_fil_params.scan_mode,
|
||||
p_data->ble_set_scan_fil_params.addr_type_own,
|
||||
p_data->ble_set_scan_fil_params.scan_duplicate_filter,
|
||||
p_data->ble_set_scan_fil_params.scan_filter_policy,
|
||||
p_data->ble_set_scan_fil_params.scan_param_setup_cback);
|
||||
}
|
||||
|
||||
@@ -968,6 +968,7 @@ void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
** scan_interval - scan interval
|
||||
** scan_window - scan window
|
||||
** scan_mode - scan mode
|
||||
** scan_duplicate_filter - scan duplicate filter
|
||||
** scan_param_setup_status_cback - Set scan param status callback
|
||||
**
|
||||
** Returns void
|
||||
@@ -975,7 +976,7 @@ void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
*******************************************************************************/
|
||||
void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
UINT32 scan_window, tBLE_SCAN_MODE scan_mode, UINT8 scan_fil_poilcy,
|
||||
UINT8 addr_type_own, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback)
|
||||
UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback)
|
||||
{
|
||||
tBTA_DM_API_BLE_SCAN_FILTER_PARAMS *p_msg;
|
||||
|
||||
@@ -987,6 +988,7 @@ void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
p_msg->scan_window = scan_window;
|
||||
p_msg->scan_mode = scan_mode;
|
||||
p_msg->addr_type_own = addr_type_own;
|
||||
p_msg->scan_duplicate_filter = scan_duplicate_filter;
|
||||
p_msg->scan_filter_policy = scan_fil_poilcy;
|
||||
p_msg->scan_param_setup_cback = scan_param_setup_cback;
|
||||
|
||||
|
||||
@@ -485,6 +485,7 @@ typedef struct {
|
||||
UINT32 scan_window;
|
||||
tBLE_SCAN_MODE scan_mode;
|
||||
UINT8 addr_type_own;
|
||||
UINT8 scan_duplicate_filter;
|
||||
UINT8 scan_filter_policy;
|
||||
tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback;
|
||||
} tBTA_DM_API_BLE_SCAN_FILTER_PARAMS;
|
||||
|
||||
@@ -1902,6 +1902,7 @@ extern void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
** scan_interval - scan interval
|
||||
** scan_window - scan window
|
||||
** scan_mode - scan mode
|
||||
** scan_duplicate_filter - scan duplicate filter
|
||||
** scan_param_setup_status_cback - Set scan param status callback
|
||||
**
|
||||
** Returns void
|
||||
@@ -1909,7 +1910,7 @@ extern void BTA_DmSetBleScanParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
*******************************************************************************/
|
||||
extern void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
UINT32 scan_window, tBLE_SCAN_MODE scan_mode, UINT8 scan_fil_poilcy,
|
||||
UINT8 addr_type_own, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback);
|
||||
UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -560,6 +560,7 @@ static void btc_ble_set_scan_params(esp_ble_scan_params_t *scan_params, tBLE_SCA
|
||||
BLE_ISVALID_PARAM(scan_params->scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX) &&
|
||||
BLE_ISVALID_PARAM(scan_params->own_addr_type, BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_RPA_RANDOM) &&
|
||||
BLE_ISVALID_PARAM(scan_params->scan_filter_policy, BLE_SCAN_FILTER_ALLOW_ALL, BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR) &&
|
||||
BLE_ISVALID_PARAM(scan_params->scan_duplicate, BLE_SCAN_DUPLICATE_DISABLE, BLE_SCAN_DUPLICATE_MAX -1) &&
|
||||
(scan_params->scan_type == BTM_BLE_SCAN_MODE_ACTI || scan_params->scan_type == BTM_BLE_SCAN_MODE_PASS)) {
|
||||
BTA_DmSetBleScanFilterParams(ESP_DEFAULT_GATT_IF, /*client_if*/
|
||||
scan_params->scan_interval,
|
||||
@@ -567,6 +568,7 @@ static void btc_ble_set_scan_params(esp_ble_scan_params_t *scan_params, tBLE_SCA
|
||||
scan_params->scan_type,
|
||||
scan_params->scan_filter_policy,
|
||||
scan_params->own_addr_type,
|
||||
scan_params->scan_duplicate,
|
||||
scan_param_setup_cback);
|
||||
} else {
|
||||
btc_scan_params_callback(ESP_DEFAULT_GATT_IF, BTM_ILLEGAL_VALUE);
|
||||
|
||||
@@ -671,7 +671,7 @@ void btc_gattc_call_handler(btc_msg_t *msg)
|
||||
btc_ble_gattc_args_t *arg = (btc_ble_gattc_args_t *)(msg->arg);
|
||||
switch (msg->act) {
|
||||
case BTC_GATTC_ACT_APP_REGISTER:
|
||||
LOG_ERROR("%s()", __func__);
|
||||
LOG_DEBUG("%s()", __func__);
|
||||
btc_gattc_app_register(arg);
|
||||
break;
|
||||
case BTC_GATTC_ACT_APP_UNREGISTER:
|
||||
|
||||
@@ -403,7 +403,6 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
|
||||
BTM_BLE_DEFAULT_SFP);
|
||||
}
|
||||
|
||||
p_inq->scan_duplicate_filter = BTM_BLE_DUPLICATE_DISABLE;
|
||||
status = btm_ble_start_scan();
|
||||
}
|
||||
|
||||
@@ -442,7 +441,6 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
|
||||
tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
|
||||
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
|
||||
{
|
||||
tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
|
||||
tBTM_STATUS status = BTM_WRONG_MODE;
|
||||
|
||||
if (!controller_get_interface()->supports_ble()) {
|
||||
@@ -467,7 +465,6 @@ tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
|
||||
/* enable resolving list */
|
||||
btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN);
|
||||
#endif
|
||||
p_inq->scan_duplicate_filter = BTM_BLE_DUPLICATE_DISABLE;
|
||||
status = btm_ble_start_scan();
|
||||
}
|
||||
|
||||
@@ -1370,7 +1367,7 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_
|
||||
}
|
||||
|
||||
void BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window,
|
||||
tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, tBTM_BLE_SFP scan_filter_policy,
|
||||
tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBTM_BLE_SFP scan_filter_policy,
|
||||
tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback)
|
||||
{
|
||||
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
|
||||
@@ -1413,6 +1410,7 @@ void BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32
|
||||
p_cb->scan_window = scan_window;
|
||||
p_cb->sfp = scan_filter_policy;
|
||||
p_cb->scan_params_set = TRUE;
|
||||
p_cb->scan_duplicate_filter = scan_duplicate_filter;
|
||||
|
||||
btsnd_hcic_ble_set_scan_params(p_cb->scan_type, (UINT16)scan_interval,
|
||||
(UINT16)scan_window,
|
||||
@@ -2282,7 +2280,6 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration)
|
||||
/* enable IRK list */
|
||||
btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN);
|
||||
#endif
|
||||
p_ble_cb->inq_var.scan_duplicate_filter = BTM_BLE_DUPLICATE_DISABLE;
|
||||
status = btm_ble_start_scan();
|
||||
} else if ((p_ble_cb->inq_var.scan_interval != BTM_BLE_LOW_LATENCY_SCAN_INT) ||
|
||||
(p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) {
|
||||
@@ -3196,6 +3193,9 @@ tBTM_STATUS btm_ble_start_scan(void)
|
||||
tBTM_STATUS status = BTM_CMD_STARTED;
|
||||
// recoverly the scan parameters to the controller before start scan
|
||||
btm_ble_recover_scan_params();
|
||||
if(p_inq->scan_duplicate_filter > BTM_BLE_DUPLICATE_MAX) {
|
||||
p_inq->scan_duplicate_filter = BTM_BLE_DUPLICATE_DISABLE;
|
||||
}
|
||||
/* start scan, disable duplicate filtering */
|
||||
if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) {
|
||||
status = BTM_NO_RESOURCES;
|
||||
|
||||
@@ -906,7 +906,30 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
|
||||
case HCI_BLE_CLEAR_WHITE_LIST:
|
||||
btm_ble_clear_white_list_complete(p, evt_len);
|
||||
break;
|
||||
|
||||
case HCI_BLE_WRITE_ADV_PARAMS: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
if(status != HCI_SUCCESS) {
|
||||
HCI_TRACE_ERROR("hci write adv params error 0x%x", status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_BLE_RC_PARAM_REQ_REPLY: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
if(status != HCI_SUCCESS) {
|
||||
HCI_TRACE_ERROR("hci connection params reply command error 0x%x", status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_BLE_RC_PARAM_REQ_NEG_REPLY: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
if(status != HCI_SUCCESS) {
|
||||
HCI_TRACE_ERROR("hci connection params neg reply command error 0x%x", status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_BLE_REMOVE_WHITE_LIST:
|
||||
btm_ble_remove_from_white_list_complete(p, evt_len);
|
||||
break;
|
||||
|
||||
@@ -1050,6 +1050,7 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
** scan_window - Scan window
|
||||
** scan_type - Scan type
|
||||
** addr_type_own - owner address type
|
||||
** scan_duplicate_filter - scan duplicate filter
|
||||
** scan_filter_policy - scan filter policy
|
||||
** scan_setup_status_cback - Scan setup status callback
|
||||
**
|
||||
@@ -1057,7 +1058,7 @@ void BTM_BleSetScanParams(tGATT_IF client_if, UINT32 scan_interval,
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32 scan_window,
|
||||
tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, tBTM_BLE_SFP scan_filter_policy,
|
||||
tBLE_SCAN_MODE scan_mode, UINT8 addr_type_own, UINT8 scan_duplicate_filter, tBTM_BLE_SFP scan_filter_policy,
|
||||
tBLE_SCAN_PARAM_SETUP_CBACK scan_setup_status_cback);
|
||||
|
||||
|
||||
|
||||
@@ -55,8 +55,9 @@
|
||||
|
||||
#define BTM_BLE_ENC_MASK 0x03
|
||||
|
||||
#define BTM_BLE_DUPLICATE_ENABLE 1
|
||||
#define BTM_BLE_DUPLICATE_DISABLE 0
|
||||
#define BTM_BLE_DUPLICATE_ENABLE 1
|
||||
#define BTM_BLE_DUPLICATE_MAX BTM_BLE_DUPLICATE_ENABLE
|
||||
|
||||
#define BTM_BLE_GAP_DISC_SCAN_INT 18 /* Interval(scan_int) = 11.25 ms= 0x0010 * 0.625 ms */
|
||||
#define BTM_BLE_GAP_DISC_SCAN_WIN 18 /* scan_window = 11.25 ms= 0x0010 * 0.625 ms */
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
#define BTDM_CFG_BT_DATA_RELEASE (1<<0)
|
||||
#define BTDM_CFG_HCI_UART (1<<1)
|
||||
#define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1<<2)
|
||||
#define BTDM_CFG_SCAN_DUPLICATE_OPTIONS (1<<3)
|
||||
#define BTDM_CFG_SEND_ADV_RESERVED_SIZE (1<<4)
|
||||
/* Other reserved for future */
|
||||
|
||||
/* not for user call, so don't put to include file */
|
||||
@@ -600,6 +602,10 @@ static uint32_t btdm_config_mask_load(void)
|
||||
#if CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE == 1
|
||||
mask |= BTDM_CFG_CONTROLLER_RUN_APP_CPU;
|
||||
#endif
|
||||
mask |= BTDM_CFG_SCAN_DUPLICATE_OPTIONS;
|
||||
|
||||
mask |= BTDM_CFG_SEND_ADV_RESERVED_SIZE;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,19 @@ typedef struct {
|
||||
uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
|
||||
uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
|
||||
uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
|
||||
uint8_t scan_duplicate_mode; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
|
||||
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
|
||||
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
|
||||
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
|
||||
uint32_t controller_debug_flag; /*!< Controller debug log flag */
|
||||
} esp_bt_controller_config_t;
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
|
||||
the adv packet will be discarded until the memory is restored. */
|
||||
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
|
||||
/* open controller log debug when adv lost */
|
||||
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
|
||||
|
||||
#ifdef CONFIG_BT_HCI_UART_NO
|
||||
#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
|
||||
@@ -51,11 +61,42 @@ typedef struct {
|
||||
#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
|
||||
#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */
|
||||
|
||||
/* normal adv cache size */
|
||||
#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE
|
||||
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
|
||||
#else
|
||||
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
|
||||
#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE
|
||||
#endif
|
||||
|
||||
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
|
||||
#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
|
||||
|
||||
#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
|
||||
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
|
||||
#ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
|
||||
#define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
|
||||
#else
|
||||
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
|
||||
#endif
|
||||
#else
|
||||
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY
|
||||
#define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
|
||||
#endif
|
||||
|
||||
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
|
||||
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
|
||||
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
|
||||
.hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
|
||||
.hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
|
||||
.scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
|
||||
.normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
|
||||
.mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
|
||||
.send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
|
||||
.controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
|
||||
};
|
||||
#else
|
||||
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h");
|
||||
|
||||
Submodule components/bt/lib updated: b76cf6aa30...959eeeb517
@@ -43,6 +43,8 @@ static const char* UART_TAG = "uart";
|
||||
#define UART_EMPTY_THRESH_DEFAULT (10)
|
||||
#define UART_FULL_THRESH_DEFAULT (120)
|
||||
#define UART_TOUT_THRESH_DEFAULT (10)
|
||||
#define UART_CLKDIV_FRAG_BIT_WIDTH (3)
|
||||
#define UART_TOUT_REF_FACTOR_DEFAULT (UART_CLK_FREQ/(REF_CLK_FREQ<<UART_CLKDIV_FRAG_BIT_WIDTH))
|
||||
#define UART_TX_IDLE_NUM_DEFAULT (0)
|
||||
#define UART_PATTERN_DET_QLEN_DEFAULT (10)
|
||||
|
||||
@@ -654,7 +656,13 @@ esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_
|
||||
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
|
||||
UART[uart_num]->int_clr.val = UART_INTR_MASK;
|
||||
if(intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) {
|
||||
UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V);
|
||||
//Hardware issue workaround: when using ref_tick, the rx timeout threshold needs increase to 10 times.
|
||||
//T_ref = T_apb * APB_CLK/(REF_TICK << CLKDIV_FRAG_BIT_WIDTH)
|
||||
if(UART[uart_num]->conf0.tick_ref_always_on == 0) {
|
||||
UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh * UART_TOUT_REF_FACTOR_DEFAULT) & UART_RX_TOUT_THRHD_V);
|
||||
} else {
|
||||
UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V);
|
||||
}
|
||||
UART[uart_num]->conf1.rx_tout_en = 1;
|
||||
} else {
|
||||
UART[uart_num]->conf1.rx_tout_en = 0;
|
||||
|
||||
@@ -38,3 +38,7 @@ CFLAGS+=-mfix-esp32-psram-cache-issue
|
||||
CXXFLAGS+=-mfix-esp32-psram-cache-issue
|
||||
endif
|
||||
|
||||
# Enable dynamic esp_timer overflow value if building unit tests
|
||||
ifneq ("$(TEST_COMPONENTS_LIST)","")
|
||||
CPPFLAGS += -DESP_TIMER_DYNAMIC_OVERFLOW_VAL
|
||||
endif
|
||||
|
||||
@@ -82,7 +82,18 @@
|
||||
* ISR happens follow set_alarm, so change the ALARM_OVERFLOW_VAL to resolve this problem.
|
||||
* Set it to 0xefffffffUL. The remain 0x10000000UL(about 3 second) is enough to handle ISR.
|
||||
*/
|
||||
#define ALARM_OVERFLOW_VAL 0xefffffffUL
|
||||
#define DEFAULT_ALARM_OVERFLOW_VAL 0xefffffffUL
|
||||
|
||||
/* Provision to set lower overflow value for unit testing. Lowering the
|
||||
* overflow value helps check for race conditions which occur near overflow
|
||||
* moment.
|
||||
*/
|
||||
#ifndef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
|
||||
#define ALARM_OVERFLOW_VAL DEFAULT_ALARM_OVERFLOW_VAL
|
||||
#else
|
||||
static uint32_t s_alarm_overflow_val = DEFAULT_ALARM_OVERFLOW_VAL;
|
||||
#define ALARM_OVERFLOW_VAL (s_alarm_overflow_val)
|
||||
#endif
|
||||
|
||||
static const char* TAG = "esp_timer_impl";
|
||||
|
||||
@@ -206,18 +217,6 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
|
||||
// Adjust current time if overflow has happened
|
||||
bool overflow = timer_overflow_happened();
|
||||
uint64_t cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
|
||||
uint32_t offset = s_timer_ticks_per_us * 2; //remain 2us for more safe
|
||||
|
||||
//If overflow is going to happen in 1us, let's wait until it happens,
|
||||
//else we think it will not happen before new alarm set.
|
||||
//And we should wait current timer count less than ALARM_OVERFLOW_VAL,
|
||||
//maybe equals to 0.
|
||||
if (cur_count + offset >= ALARM_OVERFLOW_VAL) {
|
||||
do {
|
||||
overflow = timer_overflow_happened();
|
||||
cur_count = REG_READ(FRC_TIMER_COUNT_REG(1));
|
||||
} while(!overflow || cur_count == ALARM_OVERFLOW_VAL);
|
||||
}
|
||||
|
||||
if (overflow) {
|
||||
assert(time_after_timebase_us > s_timer_us_per_overflow);
|
||||
@@ -227,13 +226,17 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp)
|
||||
// Calculate desired timer compare value (may exceed 2^32-1)
|
||||
uint64_t compare_val = time_after_timebase_us * s_timer_ticks_per_us;
|
||||
uint32_t alarm_reg_val = ALARM_OVERFLOW_VAL;
|
||||
// Use calculated alarm value if it is less than 2^32-1
|
||||
// Use calculated alarm value if it is less than ALARM_OVERFLOW_VAL.
|
||||
// Note that if by the time we update ALARM_REG, COUNT_REG value is higher,
|
||||
// interrupt will not happen for another ALARM_OVERFLOW_VAL timer ticks,
|
||||
// so need to check if alarm value is too close in the future (e.g. <2 us away).
|
||||
const uint32_t offset = s_timer_ticks_per_us * 2;
|
||||
if (compare_val < ALARM_OVERFLOW_VAL) {
|
||||
// If we by the time we update ALARM_REG, COUNT_REG value is higher,
|
||||
// interrupt will not happen for another 2^32 timer ticks, so need to
|
||||
// check if alarm value is too close in the future (e.g. <1 us away).
|
||||
if (compare_val < cur_count + offset) {
|
||||
compare_val = cur_count + offset;
|
||||
if (compare_val > ALARM_OVERFLOW_VAL) {
|
||||
compare_val = ALARM_OVERFLOW_VAL;
|
||||
}
|
||||
}
|
||||
alarm_reg_val = (uint32_t) compare_val;
|
||||
}
|
||||
@@ -361,3 +364,17 @@ uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
#ifdef ESP_TIMER_DYNAMIC_OVERFLOW_VAL
|
||||
uint32_t esp_timer_impl_get_overflow_val()
|
||||
{
|
||||
return s_alarm_overflow_val;
|
||||
}
|
||||
|
||||
void esp_timer_impl_set_overflow_val(uint32_t overflow_val)
|
||||
{
|
||||
s_alarm_overflow_val = overflow_val;
|
||||
/* update alarm value */
|
||||
esp_timer_impl_update_apb_freq(esp_clk_apb_freq() / 1000000);
|
||||
}
|
||||
#endif // ESP_TIMER_DYNAMIC_OVERFLOW_VAL
|
||||
|
||||
Submodule components/esp32/lib updated: 3a4f91f9e5...798ce93fbf
@@ -2,8 +2,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/param.h>
|
||||
#include "unity.h"
|
||||
#include "esp_timer.h"
|
||||
#include "../esp_timer_impl.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -14,6 +16,20 @@
|
||||
#define WITH_PROFILING 1
|
||||
#endif
|
||||
|
||||
extern uint32_t esp_timer_impl_get_overflow_val();
|
||||
extern void esp_timer_impl_set_overflow_val(uint32_t overflow_val);
|
||||
|
||||
static uint32_t s_old_overflow_val;
|
||||
|
||||
static void setup_overflow()
|
||||
{
|
||||
s_old_overflow_val = esp_timer_impl_get_overflow_val();
|
||||
esp_timer_impl_set_overflow_val(0x7fffff); /* overflow every ~0.1 sec */}
|
||||
|
||||
static void teardown_overflow()
|
||||
{
|
||||
esp_timer_impl_set_overflow_val(s_old_overflow_val);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
|
||||
{
|
||||
@@ -26,6 +42,7 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
|
||||
const size_t num_timers = sizeof(timeouts)/sizeof(timeouts[0]);
|
||||
esp_timer_handle_t handles[num_timers];
|
||||
char* names[num_timers];
|
||||
setup_overflow();
|
||||
for (size_t i = 0; i < num_timers; ++i) {
|
||||
asprintf(&names[i], "timer%d", i);
|
||||
esp_timer_create_args_t args = {
|
||||
@@ -35,6 +52,7 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
|
||||
TEST_ESP_OK(esp_timer_create(&args, &handles[i]));
|
||||
TEST_ESP_OK(esp_timer_start_once(handles[i], timeouts[i] * 100));
|
||||
}
|
||||
teardown_overflow();
|
||||
char* stream_str[1024];
|
||||
FILE* stream = fmemopen(stream_str, sizeof(stream_str), "r+");
|
||||
TEST_ESP_OK(esp_timer_dump(stream));
|
||||
@@ -67,6 +85,42 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]")
|
||||
fclose(stream);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_timer_impl_set_alarm stress test", "[esp_timer]")
|
||||
{
|
||||
const int test_time_sec = 10;
|
||||
|
||||
void set_alarm_task(void* arg)
|
||||
{
|
||||
SemaphoreHandle_t done = (SemaphoreHandle_t) arg;
|
||||
|
||||
uint64_t start = esp_timer_impl_get_time();
|
||||
uint64_t now = start;
|
||||
int count = 0;
|
||||
const int delays[] = {50, 5000, 10000000};
|
||||
const int delays_count = sizeof(delays)/sizeof(delays[0]);
|
||||
while (now - start < test_time_sec * 1000000) {
|
||||
now = esp_timer_impl_get_time();
|
||||
esp_timer_impl_set_alarm(now + delays[count % delays_count]);
|
||||
++count;
|
||||
}
|
||||
xSemaphoreGive(done);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
SemaphoreHandle_t done = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
|
||||
setup_overflow();
|
||||
xTaskCreatePinnedToCore(&set_alarm_task, "set_alarm_0", 4096, done, UNITY_FREERTOS_PRIORITY, NULL, 0);
|
||||
#if portNUM_PROCESSORS == 2
|
||||
xTaskCreatePinnedToCore(&set_alarm_task, "set_alarm_1", 4096, done, UNITY_FREERTOS_PRIORITY, NULL, 1);
|
||||
#endif
|
||||
|
||||
TEST_ASSERT(xSemaphoreTake(done, test_time_sec * 2 * 1000 / portTICK_PERIOD_MS));
|
||||
#if portNUM_PROCESSORS == 2
|
||||
TEST_ASSERT(xSemaphoreTake(done, test_time_sec * 2 * 1000 / portTICK_PERIOD_MS));
|
||||
#endif
|
||||
teardown_overflow();
|
||||
vSemaphoreDelete(done);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_timer produces correct delay", "[esp_timer]")
|
||||
{
|
||||
@@ -89,6 +143,7 @@ TEST_CASE("esp_timer produces correct delay", "[esp_timer]")
|
||||
const size_t delays_count = sizeof(delays_ms)/sizeof(delays_ms[0]);
|
||||
|
||||
ref_clock_init();
|
||||
setup_overflow();
|
||||
for (size_t i = 0; i < delays_count; ++i) {
|
||||
t_end = 0;
|
||||
int64_t t_start = ref_clock_get();
|
||||
@@ -102,6 +157,7 @@ TEST_CASE("esp_timer produces correct delay", "[esp_timer]")
|
||||
|
||||
TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, delays_ms[i], ms_diff);
|
||||
}
|
||||
teardown_overflow();
|
||||
ref_clock_deinit();
|
||||
|
||||
TEST_ESP_OK( esp_timer_dump(stdout) );
|
||||
@@ -149,6 +205,7 @@ TEST_CASE("periodic esp_timer produces correct delays", "[esp_timer]")
|
||||
};
|
||||
TEST_ESP_OK(esp_timer_create(&create_args, &timer1));
|
||||
ref_clock_init();
|
||||
setup_overflow();
|
||||
args.timer = timer1;
|
||||
args.t_start = ref_clock_get();
|
||||
args.done = xSemaphoreCreateBinary();
|
||||
@@ -160,6 +217,7 @@ TEST_CASE("periodic esp_timer produces correct delays", "[esp_timer]")
|
||||
for (size_t i = 0; i < NUM_INTERVALS; ++i) {
|
||||
TEST_ASSERT_INT32_WITHIN(portTICK_PERIOD_MS, (i + 1) * delay_ms, args.intervals[i]);
|
||||
}
|
||||
teardown_overflow();
|
||||
ref_clock_deinit();
|
||||
TEST_ESP_OK( esp_timer_dump(stdout) );
|
||||
|
||||
@@ -316,6 +374,7 @@ TEST_CASE("esp_timer for very short intervals", "[esp_timer]")
|
||||
esp_timer_handle_t timer1, timer2;
|
||||
ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer1) );
|
||||
ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer2) );
|
||||
setup_overflow();
|
||||
const int timeout_ms = 10;
|
||||
for (int timeout_delta_us = -150; timeout_delta_us < 150; timeout_delta_us++) {
|
||||
printf("delta=%d", timeout_delta_us);
|
||||
@@ -328,6 +387,7 @@ TEST_CASE("esp_timer for very short intervals", "[esp_timer]")
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_timer_stop(timer2));
|
||||
}
|
||||
|
||||
teardown_overflow();
|
||||
vSemaphoreDelete(semaphore);
|
||||
}
|
||||
|
||||
@@ -344,40 +404,75 @@ TEST_CASE("esp_timer_get_time call takes less than 1us", "[esp_timer]")
|
||||
TEST_PERFORMANCE_LESS_THAN(ESP_TIMER_GET_TIME_PER_CALL, "%dns", ns_per_call);
|
||||
}
|
||||
|
||||
/* This test runs for about 10 minutes and is disabled in CI.
|
||||
* Such run time is needed to have FRC2 timer overflow a few times.
|
||||
*/
|
||||
TEST_CASE("esp_timer_get_time returns monotonic values", "[esp_timer][ignore]")
|
||||
TEST_CASE("esp_timer_get_time returns monotonic values", "[esp_timer]")
|
||||
{
|
||||
void timer_test_task(void* arg) {
|
||||
int64_t delta = esp_timer_get_time() - ref_clock_get();
|
||||
typedef struct {
|
||||
SemaphoreHandle_t done;
|
||||
bool pass;
|
||||
int test_cnt;
|
||||
int error_cnt;
|
||||
int64_t total_sq_error;
|
||||
int64_t max_error;
|
||||
} test_state_t;
|
||||
|
||||
const int iter_count = 1000000000;
|
||||
for (int i = 0; i < iter_count; ++i) {
|
||||
int64_t now = esp_timer_get_time();
|
||||
int64_t ref_now = ref_clock_get();
|
||||
int64_t diff = now - (ref_now + delta);
|
||||
void timer_test_task(void* arg) {
|
||||
test_state_t* state = (test_state_t*) arg;
|
||||
state->pass = true;
|
||||
int64_t start_time = ref_clock_get();
|
||||
int64_t delta = esp_timer_get_time() - start_time;
|
||||
|
||||
int64_t now = start_time;
|
||||
int error_repeat_cnt = 0;
|
||||
while (now - start_time < 10000000) { /* 10 seconds */
|
||||
int64_t hs_now = esp_timer_get_time();
|
||||
now = ref_clock_get();
|
||||
int64_t diff = hs_now - (now + delta);
|
||||
/* Allow some difference due to rtos tick interrupting task between
|
||||
* getting 'now' and 'ref_now'.
|
||||
*/
|
||||
TEST_ASSERT_INT32_WITHIN(100, 0, (int) diff);
|
||||
if (abs(diff) > 100) {
|
||||
error_repeat_cnt++;
|
||||
state->error_cnt++;
|
||||
} else {
|
||||
error_repeat_cnt = 0;
|
||||
}
|
||||
if (error_repeat_cnt > 2) {
|
||||
printf("diff=%lld\n", diff);
|
||||
state->pass = false;
|
||||
}
|
||||
state->max_error = MAX(state->max_error, abs(diff));
|
||||
state->test_cnt++;
|
||||
state->total_sq_error += diff * diff;
|
||||
}
|
||||
|
||||
xSemaphoreGive((SemaphoreHandle_t) arg);
|
||||
xSemaphoreGive(state->done);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
ref_clock_init();
|
||||
SemaphoreHandle_t done_1 = xSemaphoreCreateBinary();
|
||||
SemaphoreHandle_t done_2 = xSemaphoreCreateBinary();
|
||||
setup_overflow();
|
||||
|
||||
xTaskCreatePinnedToCore(&timer_test_task, "t1", 4096, (void*) done_1, 6, NULL, 0);
|
||||
xTaskCreatePinnedToCore(&timer_test_task, "t2", 4096, (void*) done_2, 6, NULL, 1);
|
||||
test_state_t states[portNUM_PROCESSORS] = {0};
|
||||
SemaphoreHandle_t done = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
|
||||
for (int i = 0; i < portNUM_PROCESSORS; ++i) {
|
||||
states[i].done = done;
|
||||
xTaskCreatePinnedToCore(&timer_test_task, "test", 4096, &states[i], 6, NULL, i);
|
||||
}
|
||||
|
||||
TEST_ASSERT_TRUE( xSemaphoreTake(done_1, portMAX_DELAY) );
|
||||
TEST_ASSERT_TRUE( xSemaphoreTake(done_2, portMAX_DELAY) );
|
||||
vSemaphoreDelete(done_1);
|
||||
vSemaphoreDelete(done_2);
|
||||
for (int i = 0; i < portNUM_PROCESSORS; ++i) {
|
||||
TEST_ASSERT_TRUE( xSemaphoreTake(done, portMAX_DELAY) );
|
||||
printf("CPU%d: %s test_cnt=%d error_cnt=%d std_error=%d |max_error|=%d\n",
|
||||
i, states[i].pass ? "PASS" : "FAIL",
|
||||
states[i].test_cnt, states[i].error_cnt,
|
||||
(int) sqrt(states[i].total_sq_error / states[i].test_cnt), (int) states[i].max_error);
|
||||
}
|
||||
|
||||
vSemaphoreDelete(done);
|
||||
teardown_overflow();
|
||||
ref_clock_deinit();
|
||||
|
||||
for (int i = 0; i < portNUM_PROCESSORS; ++i) {
|
||||
TEST_ASSERT(states[i].pass);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Can dump esp_timer stats", "[esp_timer]")
|
||||
|
||||
@@ -2458,8 +2458,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
//ToDo: figure out locking
|
||||
// taskENTER_CRITICAL(&pxQueue->mux);
|
||||
taskENTER_CRITICAL(&(((Queue_t * )xQueueOrSemaphore)->mux));
|
||||
{
|
||||
if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL )
|
||||
{
|
||||
@@ -2478,7 +2477,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
}
|
||||
// taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
taskEXIT_CRITICAL(&(((Queue_t * )xQueueOrSemaphore)->mux));
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
@@ -2507,12 +2506,12 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// taskENTER_CRITICAL(&pxQueue->mux);
|
||||
taskENTER_CRITICAL(&(pxQueueOrSemaphore->mux));
|
||||
{
|
||||
/* The queue is no longer contained in the set. */
|
||||
pxQueueOrSemaphore->pxQueueSetContainer = NULL;
|
||||
}
|
||||
// taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
taskEXIT_CRITICAL(&(pxQueueOrSemaphore->mux));
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
|
||||
@@ -2555,9 +2554,15 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
/* This function must be called form a critical section. */
|
||||
/*
|
||||
* This function is called with a Queue's / Semaphore's spinlock already
|
||||
* acquired. Acquiring the Queue set's spinlock is still necessary.
|
||||
*/
|
||||
|
||||
configASSERT( pxQueueSetContainer );
|
||||
|
||||
//Acquire the Queue set's spinlock
|
||||
portENTER_CRITICAL(&(pxQueueSetContainer->mux));
|
||||
configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength );
|
||||
|
||||
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
||||
@@ -2588,6 +2593,9 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
//Release the Queue set's spinlock
|
||||
portEXIT_CRITICAL(&(pxQueueSetContainer->mux));
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
|
||||
137
components/freertos/test/test_queuesets.c
Normal file
137
components/freertos/test/test_queuesets.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
|
||||
/*
|
||||
* Basic queue set tests. Multiple queues are added to a queue set then each
|
||||
* queue is filled in a sequential order. The members returned from the queue
|
||||
* set must adhered to the order in which the queues were filled.
|
||||
*/
|
||||
#define NO_OF_QUEUES 5
|
||||
#define QUEUE_LEN 4
|
||||
#define ITEM_SIZE sizeof(uint32_t)
|
||||
|
||||
static QueueHandle_t handles[NO_OF_QUEUES];
|
||||
static QueueSetHandle_t set_handle;
|
||||
|
||||
TEST_CASE("Test Queue sets", "[freertos]")
|
||||
{
|
||||
//Create queue set, queues, and add queues to queue set
|
||||
set_handle = xQueueCreateSet(NO_OF_QUEUES * QUEUE_LEN);
|
||||
for (int i = 0; i < NO_OF_QUEUES; i++) {
|
||||
handles[i] = xQueueCreate(QUEUE_LEN, ITEM_SIZE);
|
||||
TEST_ASSERT_MESSAGE(handles[i] != NULL, "Failed to create queue");
|
||||
TEST_ASSERT_MESSAGE(xQueueAddToSet(handles[i], set_handle) == pdPASS, "Failed to add to queue set");
|
||||
}
|
||||
|
||||
//Fill queue set via filling each queue
|
||||
for (int i = 0; i < NO_OF_QUEUES; i++) {
|
||||
for (int j = 0; j < QUEUE_LEN; j++) {
|
||||
uint32_t item_num = (i * QUEUE_LEN) + j;
|
||||
TEST_ASSERT_MESSAGE(xQueueSendToBack(handles[i], &item_num, portMAX_DELAY) == pdTRUE, "Failed to send to queue");
|
||||
}
|
||||
}
|
||||
|
||||
//Check queue set is notified in correct order
|
||||
for (int i = 0; i < NO_OF_QUEUES; i++) {
|
||||
for (int j = 0; j < QUEUE_LEN; j++) {
|
||||
QueueSetMemberHandle_t member = xQueueSelectFromSet(set_handle, portMAX_DELAY);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(handles[i], member, "Incorrect queue set member returned");
|
||||
uint32_t item;
|
||||
xQueueReceive((QueueHandle_t)member, &item, 0);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(((i * QUEUE_LEN) + j), item, "Incorrect item value");
|
||||
}
|
||||
}
|
||||
|
||||
//Remove queues from queue set and delete queues
|
||||
for (int i = 0; i < NO_OF_QUEUES; i++) {
|
||||
TEST_ASSERT_MESSAGE(xQueueRemoveFromSet(handles[i], set_handle), "Failed to remove from queue set");
|
||||
vQueueDelete(handles[i]);
|
||||
}
|
||||
vQueueDelete(set_handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue set thread safety test. Test the SMP thread safety by adding two queues
|
||||
* to a queue set and have a task on each core send to the queues simultaneously.
|
||||
* Check returned queue set members are valid.
|
||||
*/
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
static volatile bool sync_flags[portNUM_PROCESSORS];
|
||||
static SemaphoreHandle_t sync_sem;
|
||||
|
||||
static void send_task(void *arg)
|
||||
{
|
||||
QueueHandle_t queue = (QueueHandle_t)arg;
|
||||
|
||||
//Wait until task on the other core starts running
|
||||
xSemaphoreTake(sync_sem, portMAX_DELAY);
|
||||
sync_flags[xPortGetCoreID()] = true;
|
||||
while (!sync_flags[!xPortGetCoreID()]) {
|
||||
;
|
||||
}
|
||||
|
||||
//Fill queue
|
||||
for (int i = 0; i < QUEUE_LEN; i++) {
|
||||
uint32_t item = i;
|
||||
xQueueSendToBack(queue, &item, portMAX_DELAY);
|
||||
}
|
||||
|
||||
xSemaphoreGive(sync_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Test Queue sets thread safety", "[freertos]")
|
||||
{
|
||||
//Create queue set, queues, and a send task on each core
|
||||
sync_sem = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
|
||||
QueueHandle_t queue_handles[portNUM_PROCESSORS];
|
||||
QueueSetHandle_t queueset_handle = xQueueCreateSet(portNUM_PROCESSORS * QUEUE_LEN);
|
||||
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
sync_flags[i] = false;
|
||||
queue_handles[i] = xQueueCreate(QUEUE_LEN, ITEM_SIZE);
|
||||
TEST_ASSERT_MESSAGE(xQueueAddToSet(queue_handles[i], queueset_handle) == pdPASS, "Failed to add to queue set");
|
||||
xTaskCreatePinnedToCore(send_task, "send", 2048, (void *)queue_handles[i], 10, NULL, i);
|
||||
}
|
||||
|
||||
//Start both send tasks
|
||||
portDISABLE_INTERRUPTS();
|
||||
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
xSemaphoreGive(sync_sem);
|
||||
}
|
||||
portENABLE_INTERRUPTS();
|
||||
vTaskDelay(2);
|
||||
|
||||
//Check returned queue set members are valid
|
||||
uint32_t expect_0 = 0;
|
||||
uint32_t expect_1 = 0;
|
||||
for (int i = 0; i < (portNUM_PROCESSORS * QUEUE_LEN); i++) {
|
||||
QueueSetMemberHandle_t member = xQueueSelectFromSet(queueset_handle, portMAX_DELAY);
|
||||
uint32_t item;
|
||||
if (member == queue_handles[0]) {
|
||||
xQueueReceive((QueueHandle_t)member, &item, 0);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(expect_0, item, "Incorrect item value");
|
||||
expect_0++;
|
||||
} else if (member == queue_handles[1]) {
|
||||
xQueueReceive((QueueHandle_t)member, &item, 0);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(expect_1, item, "Incorrect item value");
|
||||
expect_1++;
|
||||
} else {
|
||||
TEST_ASSERT_MESSAGE(0, "Incorrect queue set member returned");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
xSemaphoreTake(sync_sem, portMAX_DELAY);
|
||||
}
|
||||
for (int i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
xQueueRemoveFromSet(queueset_handle, handles[i]);
|
||||
vQueueDelete(queue_handles[i]);
|
||||
}
|
||||
vQueueDelete(queueset_handle);
|
||||
}
|
||||
#endif
|
||||
@@ -798,7 +798,7 @@ test cases:
|
||||
- ['R PC_COM C +NIC_START:OK']
|
||||
- - "SSC SSC1 bleadv -D -z stop"
|
||||
- ["R SSC1 C +BLEADV"]
|
||||
- - LOOP 2 2 "['0x20-0x40','0xA0-0xB0']" "['NPDU','PDU']"
|
||||
- - LOOP 2 2 "['0x20-0x40','0xA0-0xB0']" "['PDU','PDU']"
|
||||
- [""]
|
||||
- - "SSC SSC1 bleadv -D -z start -t 2 -i {%s}"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
@@ -842,7 +842,7 @@ test cases:
|
||||
- ['R PC_COM C +NIC_START:OK']
|
||||
- - "SSC SSC1 bleadv -D -z stop"
|
||||
- ["R SSC1 C +BLEADV"]
|
||||
- - LOOP 2 2 "['0x20-0x40','0xA0-0xB0']" "['NPDU','PDU']"
|
||||
- - LOOP 2 2 "['0x20-0x40','0xA0-0xB0']" "['PDU','PDU']"
|
||||
- [""]
|
||||
- - "SSC SSC1 bleadv -D -z start -t 3 -i {%s}"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
@@ -890,7 +890,7 @@ test cases:
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
- - "SSC SSC2 bleadv -D -z stop"
|
||||
- ["R SSC2 C +BLEADV:OK"]
|
||||
- - "SSC SSC2 blescan -L -c 0 -s 0"
|
||||
- - "SSC SSC2 blescan -L -c 0 -s 0 -d 1"
|
||||
- ["R SSC2 C +BLESCAN:SetScanParam,OK"]
|
||||
- - "SSC SSC2 blescan -D -z start -t 3 -e 2"
|
||||
- - 'P SSC2 RE "\+BTSCANEXT:%%s,man,0x1011121314151617181910111213141516171819"%%(<dut1_bt_mac>)'
|
||||
@@ -944,7 +944,7 @@ test cases:
|
||||
- ["R SSC2 C +BLEADV:OK"]
|
||||
- - LOOP 4 2 "[0,1,2,3]"
|
||||
- ['']
|
||||
- - "SSC SSC2 blescan -L -c 0 -s 1 -o {%d}"
|
||||
- - "SSC SSC2 blescan -L -c 0 -s 1 -o {%d} -d 1"
|
||||
- ["R SSC2 C +BLESCAN:SetScanParam,OK"]
|
||||
- - "SSC SSC2 blescan -D -z start -t 1"
|
||||
- ['R SSC2 P <dut1_bt_mac> C Complete']
|
||||
@@ -1075,7 +1075,7 @@ test cases:
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
- - "SSC SSC1 bleadv -D -z start"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
- - "SSC SSC2 blescan -L -c 0"
|
||||
- - "SSC SSC2 blescan -L -c 0 -d 1"
|
||||
- ["R SSC2 C +BLESCAN:SetScanParam,OK"]
|
||||
- - "SSC SSC2 blescan -D -z start -t 1"
|
||||
- ["R SSC2 P <dut1_bt_mac> C Complete"]
|
||||
@@ -1538,6 +1538,8 @@ test cases:
|
||||
- ""
|
||||
- - "SSC SSC1 bleadv -D -z stop"
|
||||
- ["R SSC1 C +BLEADV"]
|
||||
- - "SSC SSC2 blescan -L -c 0 -d 1"
|
||||
- ['R SSC2 C +BLESCAN']
|
||||
- - "SSC SSC1 bleadv -R -t 1 -r 0x020AEB06FF1112131415051220004000021901020106"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
- - "SSC SSC1 bleadv -D -z start"
|
||||
@@ -1584,6 +1586,8 @@ test cases:
|
||||
- ["R SSC1 C +BLEADV"]
|
||||
- - "SSC SSC2 bleadv -D -z stop"
|
||||
- ["R SSC2 C +BLEADV:OK"]
|
||||
- - "SSC SSC2 blescan -L -c 0 -d 1"
|
||||
- ['R SSC2 C +BLESCAN']
|
||||
- - LOOP 4 3 "['0302ABCD','0303ABCD','0504ABCDABCD','0505ABCDABCD',]" "['insrv16,0xABCD','srv16,0xABCD','insrv32,0xABCDABCD','srv32,0xABCDABCD']"
|
||||
- - "SSC SSC1 bleadv -R -t 1 -r 0x{%s}"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
@@ -1633,6 +1637,8 @@ test cases:
|
||||
- ["R SSC1 C +BLEADV"]
|
||||
- - "SSC SSC2 bleadv -D -z stop"
|
||||
- ["R SSC2 C +BLEADV:OK"]
|
||||
- - "SSC SSC2 blescan -L -c 0 -d 1"
|
||||
- ['R SSC2 C +BLESCAN']
|
||||
- - LOOP 3 3 "['0416ABCDEF','0620ABCDABCDEF','1221ABCDABCDABCDABCDABCDABCDABCDABCDEF',]" "['srvdata,0xABCDEF','srvdata32,0xABCDABCDEF','srvdata128,0xABCDABCDABCDABCDABCDABCDABCDABCDEF']"
|
||||
- - "SSC SSC1 bleadv -R -t 1 -r 0x{%s}"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
@@ -1671,6 +1677,8 @@ test cases:
|
||||
- ""
|
||||
- - "SSC SSC1 bleadv -D -z stop"
|
||||
- ["R SSC1 C +BLEADV"]
|
||||
- - "SSC SSC2 blescan -L -c 0 -d 1"
|
||||
- ['R SSC2 C +BLESCAN']
|
||||
- - "SSC SSC1 bleadv -R -t 1 -r 0x15FF1011121314151617181910111213141516171819"
|
||||
- ["R SSC1 C +BLEADV:OK"]
|
||||
- - "SSC SSC1 bleadv -R -t 2 -r 0x020AEB051220004000021901020106"
|
||||
|
||||
@@ -83,7 +83,7 @@ config LWIP_STATS
|
||||
|
||||
config LWIP_ETHARP_TRUST_IP_MAC
|
||||
bool "Enable LWIP ARP trust"
|
||||
default y
|
||||
default n
|
||||
help
|
||||
Enabling this option allows ARP table to be updated.
|
||||
|
||||
@@ -96,6 +96,17 @@ config LWIP_ETHARP_TRUST_IP_MAC
|
||||
The peer *is* in the ARP table if it requested our address before.
|
||||
Also notice that this slows down input processing of every IP packet!
|
||||
|
||||
There are two known issues in real application if this feature is enabled:
|
||||
- The LAN peer may have bug to update the ARP table after the ARP entry is aged out.
|
||||
If the ARP entry on the LAN peer is aged out but failed to be updated, all IP packets
|
||||
sent from LWIP to the LAN peer will be dropped by LAN peer.
|
||||
- The LAN peer may not be trustful, the LAN peer may send IP packets to LWIP with
|
||||
two different MACs, but the same IP address. If this happens, the LWIP has problem
|
||||
to receive IP packets from LAN peer.
|
||||
|
||||
So the recommendation is to disable this option.
|
||||
Here the LAN peer means the other side to which the ESP station or soft-AP is connected.
|
||||
|
||||
config TCPIP_RECVMBOX_SIZE
|
||||
int "TCPIP task receive mail box size"
|
||||
default 32
|
||||
|
||||
@@ -407,9 +407,9 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
/* Let the stack know that we have accepted the connection. */
|
||||
API_MSG_VAR_ALLOC_DONTFAIL(msg);
|
||||
API_MSG_VAR_REF(msg).msg.conn = conn;
|
||||
/* don't care for the return value of lwip_netconn_do_recv */
|
||||
TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv);
|
||||
API_MSG_VAR_REF(msg).msg.conn = newconn;
|
||||
/* don't care for the return value of lwip_netconn_do_accepted */
|
||||
TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_accepted);
|
||||
API_MSG_VAR_FREE(msg);
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
|
||||
|
||||
@@ -536,6 +536,9 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||
to the application thread */
|
||||
newconn->last_err = err;
|
||||
|
||||
/* handle backlog counter */
|
||||
tcp_backlog_delayed(newpcb);
|
||||
|
||||
if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
|
||||
ESP_STATS_DROP_INC(esp.acceptmbox_post_fail);
|
||||
/* When returning != ERR_OK, the pcb is aborted in tcp_process(),
|
||||
@@ -1503,24 +1506,38 @@ lwip_netconn_do_recv(void *m)
|
||||
msg->err = ERR_OK;
|
||||
if (msg->conn->pcb.tcp != NULL) {
|
||||
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
if (msg->conn->pcb.tcp->state == LISTEN) {
|
||||
tcp_accepted(msg->conn->pcb.tcp);
|
||||
} else
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
{
|
||||
u32_t remaining = msg->msg.r.len;
|
||||
do {
|
||||
u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining;
|
||||
tcp_recved(msg->conn->pcb.tcp, recved);
|
||||
remaining -= recved;
|
||||
} while (remaining != 0);
|
||||
}
|
||||
u32_t remaining = msg->msg.r.len;
|
||||
do {
|
||||
u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining;
|
||||
tcp_recved(msg->conn->pcb.tcp, recved);
|
||||
remaining -= recved;
|
||||
} while (remaining != 0);
|
||||
}
|
||||
}
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
/** Indicate that a TCP pcb has been accepted
|
||||
* Called from netconn_accept
|
||||
*
|
||||
* @param m the api_msg pointing to the connection
|
||||
*/
|
||||
void
|
||||
lwip_netconn_do_accepted(void *m)
|
||||
{
|
||||
struct api_msg_msg *msg = (struct api_msg_msg *)m;
|
||||
|
||||
msg->err = ERR_OK;
|
||||
if (msg->conn->pcb.tcp != NULL) {
|
||||
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
|
||||
tcp_backlog_accepted(msg->conn->pcb.tcp);
|
||||
}
|
||||
}
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
|
||||
/**
|
||||
* See if more data needs to be written from a previous call to netconn_write.
|
||||
* Called initially from lwip_netconn_do_write. If the first call can't send all data
|
||||
|
||||
@@ -133,16 +133,14 @@ bool ip4_netif_exist(const ip4_addr_t *src, const ip4_addr_t *dest)
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Source based IPv4 routing hook function. This function works only
|
||||
* when destination IP is broadcast IP.
|
||||
* Source based IPv4 routing hook function.
|
||||
*/
|
||||
struct netif *
|
||||
ip4_route_src_hook(const ip4_addr_t *dest, const ip4_addr_t *src)
|
||||
{
|
||||
struct netif *netif = NULL;
|
||||
|
||||
/* destination IP is broadcast IP? */
|
||||
if ((src != NULL) && (dest->addr == IPADDR_BROADCAST)) {
|
||||
if ((src != NULL) && !ip4_addr_isany(src)) {
|
||||
/* iterate through netifs */
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
/* is the netif up, does it have a link and a valid address? */
|
||||
|
||||
@@ -149,6 +149,22 @@ tcp_tmr(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
|
||||
/** Called when a listen pcb is closed. Iterates one pcb list and removes the
|
||||
* closed listener pcb from pcb->listener if matching.
|
||||
*/
|
||||
static void
|
||||
tcp_remove_listener(struct tcp_pcb *list, struct tcp_pcb_listen *lpcb)
|
||||
{
|
||||
struct tcp_pcb *pcb;
|
||||
for (pcb = list; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->listener == lpcb) {
|
||||
pcb->listener = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
tcp_set_fin_wait_1(struct tcp_pcb *pcb)
|
||||
{
|
||||
@@ -158,6 +174,70 @@ tcp_set_fin_wait_1(struct tcp_pcb *pcb)
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Called when a listen pcb is closed. Iterates all pcb lists and removes the
|
||||
* closed listener pcb from pcb->listener if matching.
|
||||
*/
|
||||
static void
|
||||
tcp_listen_closed(struct tcp_pcb *pcb)
|
||||
{
|
||||
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
|
||||
size_t i;
|
||||
LWIP_ASSERT("pcb != NULL", pcb != NULL);
|
||||
LWIP_ASSERT("pcb->state == LISTEN", pcb->state == LISTEN);
|
||||
for (i = 1; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) {
|
||||
tcp_remove_listener(*tcp_pcb_lists[i], (struct tcp_pcb_listen *)pcb);
|
||||
}
|
||||
#endif
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
}
|
||||
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
/** @ingroup tcp_raw
|
||||
* Delay accepting a connection in respect to the listen backlog:
|
||||
* the number of outstanding connections is increased until
|
||||
* tcp_backlog_accepted() is called.
|
||||
*
|
||||
* ATTENTION: the caller is responsible for calling tcp_backlog_accepted()
|
||||
* or else the backlog feature will get out of sync!
|
||||
*
|
||||
* @param pcb the connection pcb which is not fully accepted yet
|
||||
*/
|
||||
void
|
||||
tcp_backlog_delayed(struct tcp_pcb *pcb)
|
||||
{
|
||||
LWIP_ASSERT("pcb != NULL", pcb != NULL);
|
||||
if ((pcb->flags & TF_BACKLOGPEND) == 0) {
|
||||
if (pcb->listener != NULL) {
|
||||
pcb->listener->accepts_pending++;
|
||||
LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
|
||||
pcb->flags |= TF_BACKLOGPEND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @ingroup tcp_raw
|
||||
* A delayed-accept a connection is accepted (or closed/aborted): decreases
|
||||
* the number of outstanding connections after calling tcp_backlog_delayed().
|
||||
*
|
||||
* ATTENTION: the caller is responsible for calling tcp_backlog_accepted()
|
||||
* or else the backlog feature will get out of sync!
|
||||
*
|
||||
* @param pcb the connection pcb which is now fully accepted (or closed/aborted)
|
||||
*/
|
||||
void
|
||||
tcp_backlog_accepted(struct tcp_pcb *pcb)
|
||||
{
|
||||
LWIP_ASSERT("pcb != NULL", pcb != NULL);
|
||||
if ((pcb->flags & TF_BACKLOGPEND) != 0) {
|
||||
if (pcb->listener != NULL) {
|
||||
LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
|
||||
pcb->listener->accepts_pending--;
|
||||
pcb->flags &= ~TF_BACKLOGPEND;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
|
||||
/**
|
||||
* Closes the TX side of a connection held by the PCB.
|
||||
* For tcp_close(), a RST is sent if the application didn't receive all data
|
||||
@@ -227,6 +307,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
||||
break;
|
||||
case LISTEN:
|
||||
err = ERR_OK;
|
||||
tcp_listen_closed(pcb);
|
||||
tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB_LISTEN, pcb);
|
||||
pcb = NULL;
|
||||
@@ -241,6 +322,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
||||
case SYN_RCVD:
|
||||
err = tcp_send_fin(pcb);
|
||||
if (err == ERR_OK) {
|
||||
tcp_backlog_accepted(pcb);
|
||||
MIB2_STATS_INC(mib2.tcpattemptfails);
|
||||
tcp_set_fin_wait_1(pcb);
|
||||
}
|
||||
@@ -408,6 +490,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
||||
pcb->ooseq = NULL;
|
||||
}
|
||||
#endif /* TCP_QUEUE_OOSEQ */
|
||||
tcp_backlog_accepted(pcb);
|
||||
if (send_rst) {
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
|
||||
tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
|
||||
@@ -1747,39 +1830,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
|
||||
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
if (pcb->state == SYN_RCVD) {
|
||||
/* Need to find the corresponding listen_pcb and decrease its accepts_pending */
|
||||
struct tcp_pcb_listen *lpcb;
|
||||
|
||||
/*
|
||||
* The official LWIP will assert the system if tcp_listen_pcbs.listen_pcbs is NULL, it's a bug.
|
||||
*
|
||||
* Considering following scenario:
|
||||
* 1. On TCP server side, one of TCP pcb is in SYNC_RECV state and is waiting for TCP ACK from TCP client.
|
||||
* 2. The TCP server is closed by application, which causes the tcp_listen_pcbs.listen_pcbs to become NULL.
|
||||
* 3. When SYNC_RECV state timeout (20s by default), tcp_pcb_purge() is called in tcp_slowtmr(), it asserts
|
||||
* the system.
|
||||
* This is a normal scenario, should NOT assert the system. So just remove it.
|
||||
*
|
||||
*/
|
||||
if (tcp_listen_pcbs.listen_pcbs) {
|
||||
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||
if ((lpcb->local_port == pcb->local_port) &&
|
||||
(IP_IS_V6_VAL(pcb->local_ip) == IP_IS_V6_VAL(lpcb->local_ip)) &&
|
||||
(ip_addr_isany(&lpcb->local_ip) ||
|
||||
ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
|
||||
/* port and address of the listen pcb match the timed-out pcb */
|
||||
LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
|
||||
lpcb->accepts_pending > 0);
|
||||
lpcb->accepts_pending--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
|
||||
tcp_backlog_accepted(pcb);
|
||||
|
||||
if (pcb->refused_data != NULL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
|
||||
|
||||
@@ -568,6 +568,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
}
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
pcb->accepts_pending++;
|
||||
npcb->flags |= TF_BACKLOGPEND;
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
/* Set up the new PCB. */
|
||||
ip_addr_copy(npcb->local_ip, *ip_current_dest_addr());
|
||||
@@ -582,6 +583,10 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
#if LWIP_CALLBACK_API
|
||||
npcb->accept = pcb->accept;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
|
||||
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
|
||||
npcb->listener = pcb;
|
||||
#endif
|
||||
/* inherit socket options */
|
||||
npcb->so_options = pcb->so_options & SOF_INHERITED;
|
||||
/* Register the new PCB so that we can begin receiving segments
|
||||
@@ -785,11 +790,19 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
|
||||
pcb->state = ESTABLISHED;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
|
||||
#if LWIP_CALLBACK_API
|
||||
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
|
||||
#endif
|
||||
/* Call the accept function. */
|
||||
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
|
||||
|
||||
if (pcb->listener == NULL) {
|
||||
err = ERR_VAL;
|
||||
} else {
|
||||
#endif
|
||||
tcp_backlog_accepted(pcb);
|
||||
/* Call the accept function. */
|
||||
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
|
||||
}
|
||||
if (err != ERR_OK) {
|
||||
/* If the accept function returns with an error, we abort
|
||||
* the connection. */
|
||||
|
||||
@@ -232,6 +232,9 @@ void lwip_netconn_do_disconnect (void *m);
|
||||
void lwip_netconn_do_listen (void *m);
|
||||
void lwip_netconn_do_send (void *m);
|
||||
void lwip_netconn_do_recv (void *m);
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
void lwip_netconn_do_accepted (void *m);
|
||||
#endif
|
||||
void lwip_netconn_do_write (void *m);
|
||||
void lwip_netconn_do_getaddr (void *m);
|
||||
void lwip_netconn_do_close (void *m);
|
||||
|
||||
@@ -138,7 +138,7 @@ typedef u16_t tcpflags_t;
|
||||
#define TCPWND16(x) (x)
|
||||
#define TCP_WND_MAX(pcb) TCP_WND(pcb)
|
||||
typedef u16_t tcpwnd_size_t;
|
||||
typedef u8_t tcpflags_t;
|
||||
typedef u16_t tcpflags_t;
|
||||
#endif
|
||||
|
||||
enum tcp_state {
|
||||
@@ -203,6 +203,9 @@ struct tcp_pcb {
|
||||
#define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
|
||||
#if LWIP_WND_SCALE
|
||||
#define TF_WND_SCALE 0x0100U /* Window Scale option enabled */
|
||||
#endif
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
#define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */
|
||||
#endif
|
||||
|
||||
/* the rest of the fields are in host byte order
|
||||
@@ -311,6 +314,10 @@ struct tcp_pcb {
|
||||
u8_t rcv_scale;
|
||||
#endif
|
||||
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
struct tcp_pcb_listen *listener;
|
||||
#endif
|
||||
|
||||
#if ESP_STATS_TCP
|
||||
#define ESP_STATS_TCP_ARRAY_SIZE 20
|
||||
u16_t retry_cnt[TCP_MAXRTX];
|
||||
@@ -383,16 +390,17 @@ void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err);
|
||||
#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0)
|
||||
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
#define tcp_accepted(pcb) do { \
|
||||
LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \
|
||||
(((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0)
|
||||
#define tcp_backlog_set(pcb, new_backlog) do { \
|
||||
LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \
|
||||
((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0)
|
||||
void tcp_backlog_delayed(struct tcp_pcb* pcb);
|
||||
void tcp_backlog_accepted(struct tcp_pcb* pcb);
|
||||
#else /* TCP_LISTEN_BACKLOG */
|
||||
#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \
|
||||
(pcb)->state == LISTEN)
|
||||
#define tcp_backlog_set(pcb, new_backlog)
|
||||
#define tcp_backlog_delayed(pcb)
|
||||
#define tcp_backlog_accepted(pcb)
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
#define tcp_accepted(pcb) do { LWIP_UNUSED_ARG(pcb); } while(0) /* compatibility define, not needed any more */
|
||||
|
||||
void tcp_recved (struct tcp_pcb *pcb, u16_t len);
|
||||
err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
|
||||
|
||||
@@ -47,7 +47,8 @@ static esp_ble_scan_params_t ble_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
|
||||
};
|
||||
|
||||
static void esp_eddystone_show_inform(const esp_eddystone_result_t* res)
|
||||
|
||||
@@ -43,7 +43,8 @@ static esp_ble_scan_params_t ble_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
|
||||
};
|
||||
|
||||
#elif (IBEACON_MODE == IBEACON_SENDER)
|
||||
|
||||
@@ -93,7 +93,8 @@ static esp_ble_scan_params_t ble_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
|
||||
};
|
||||
|
||||
static const char device_name[] = "ESP_SPP_SERVER";
|
||||
|
||||
@@ -77,7 +77,8 @@ static esp_ble_scan_params_t ble_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
|
||||
};
|
||||
|
||||
struct gattc_profile_inst {
|
||||
|
||||
@@ -64,7 +64,8 @@ static esp_ble_scan_params_t ble_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -100,7 +100,8 @@ static esp_ble_scan_params_t ble_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
.scan_interval = 0x50,
|
||||
.scan_window = 0x30
|
||||
.scan_window = 0x30,
|
||||
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
|
||||
};
|
||||
|
||||
struct gattc_profile_inst {
|
||||
|
||||
@@ -17,6 +17,8 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
import functools
|
||||
import random
|
||||
import tempfile
|
||||
|
||||
import DUT
|
||||
|
||||
@@ -40,6 +42,8 @@ class IDFDUT(DUT.SerialDUT):
|
||||
""" IDF DUT, extends serial with ESPTool methods """
|
||||
|
||||
CHIP_TYPE_PATTERN = re.compile(r"Detecting chip type[.:\s]+(.+)")
|
||||
# if need to erase NVS partition in start app
|
||||
ERASE_NVS = True
|
||||
|
||||
def __init__(self, name, port, log_file, app, **kwargs):
|
||||
self.download_config, self.partition_table = app.process_app_info()
|
||||
@@ -68,24 +72,39 @@ class IDFDUT(DUT.SerialDUT):
|
||||
return cls.get_chip(app, port) is not None
|
||||
|
||||
@_tool_method
|
||||
def start_app(self):
|
||||
def start_app(self, erase_nvs=ERASE_NVS):
|
||||
"""
|
||||
download and start app.
|
||||
|
||||
:param: erase_nvs: whether erase NVS partition during flash
|
||||
:return: None
|
||||
"""
|
||||
if erase_nvs:
|
||||
address = self.partition_table["nvs"]["offset"]
|
||||
size = self.partition_table["nvs"]["size"]
|
||||
nvs_file = tempfile.NamedTemporaryFile()
|
||||
nvs_file.write(chr(0xFF) * size)
|
||||
nvs_file.flush()
|
||||
download_config = self.download_config + [address, nvs_file.name]
|
||||
else:
|
||||
download_config = self.download_config
|
||||
|
||||
retry_baud_rates = ["921600", "115200"]
|
||||
error = IDFToolError()
|
||||
for baud_rate in retry_baud_rates:
|
||||
try:
|
||||
subprocess.check_output(["python", self.app.esptool,
|
||||
"--port", self.port, "--baud", baud_rate]
|
||||
+ self.download_config)
|
||||
break
|
||||
except subprocess.CalledProcessError as error:
|
||||
continue
|
||||
else:
|
||||
raise error
|
||||
try:
|
||||
for baud_rate in retry_baud_rates:
|
||||
try:
|
||||
subprocess.check_output(["python", self.app.esptool,
|
||||
"--port", self.port, "--baud", baud_rate]
|
||||
+ download_config)
|
||||
break
|
||||
except subprocess.CalledProcessError as error:
|
||||
continue
|
||||
else:
|
||||
raise error
|
||||
finally:
|
||||
if erase_nvs:
|
||||
nvs_file.close()
|
||||
|
||||
@_tool_method
|
||||
def reset(self):
|
||||
@@ -96,6 +115,17 @@ class IDFDUT(DUT.SerialDUT):
|
||||
"""
|
||||
subprocess.check_output(["python", self.app.esptool, "--port", self.port, "run"])
|
||||
|
||||
@_tool_method
|
||||
def erase_partition(self, partition):
|
||||
"""
|
||||
:param partition: partition name to erase
|
||||
:return: None
|
||||
"""
|
||||
address = self.partition_table[partition]["offset"]
|
||||
size = self.partition_table[partition]["size"]
|
||||
with open(".erase_partition.tmp", "wb") as f:
|
||||
f.write(chr(0xFF) * size)
|
||||
|
||||
@_tool_method
|
||||
def dump_flush(self, output_file, **kwargs):
|
||||
"""
|
||||
|
||||
@@ -20,9 +20,8 @@ from IDF.IDFApp import IDFApp, Example, UT
|
||||
from IDF.IDFDUT import IDFDUT
|
||||
|
||||
|
||||
def idf_example_test(app=Example, dut=IDFDUT, chip="ESP32",
|
||||
module="examples", execution_time=1,
|
||||
**kwargs):
|
||||
def idf_example_test(app=Example, dut=IDFDUT, chip="ESP32", module="examples", execution_time=1,
|
||||
level="example", erase_nvs=True, **kwargs):
|
||||
"""
|
||||
decorator for testing idf examples (with default values for some keyword args).
|
||||
|
||||
@@ -31,12 +30,19 @@ def idf_example_test(app=Example, dut=IDFDUT, chip="ESP32",
|
||||
:param chip: chip supported, string or tuple
|
||||
:param module: module, string
|
||||
:param execution_time: execution time in minutes, int
|
||||
:param level: test level, could be used to filter test cases, string
|
||||
:param erase_nvs: if need to erase_nvs in DUT.start_app()
|
||||
:param kwargs: other keyword args
|
||||
:return: test method
|
||||
"""
|
||||
# not use partial function as define as function support auto generating document
|
||||
try:
|
||||
# try to config the default behavior of erase nvs
|
||||
dut.ERASE_NVS = erase_nvs
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return TinyFW.test_method(app=app, dut=dut, chip=chip, module=module,
|
||||
execution_time=execution_time, **kwargs)
|
||||
execution_time=execution_time, level=level, **kwargs)
|
||||
|
||||
|
||||
def log_performance(item, value):
|
||||
|
||||
Reference in New Issue
Block a user