Skip to content

Commit 499ebfe

Browse files
SohKamYung-Espressifmantriyogesh
authored andcommitted
bugfix(sta_connect): Fix applying new sta config
- apply new incoming sta config immediately if not connected - suppress disconnect event from old config - tested with these conditions: - not using NVRAM to save station config - using NVRAM to save station config - test results: new sta config is applied and connected without prior disconnection (unless already connected) - bugfix: IRAM limitation for UART applies only to ESP32 - workaround: bug in `esp_wifi_get_protocol()` causing memory corruption - updated CI pipeline to build mqtt/tcp example from Registry Component
1 parent dc8c876 commit 499ebfe

File tree

6 files changed

+131
-24
lines changed

6 files changed

+131
-24
lines changed

.gitlab/ci/regression_pipeline_jobs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,18 @@ regression_build_idf_v5.5_iperf:
7070
regression_build_idf_master_mqtt_tcp:
7171
variables:
7272
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
73+
IDF_REGISTRY_COMPONENT: "espressif/mqtt"
74+
IDF_REGISTRY_COMPONENT_EXAMPLE: "tcp"
7375
tags:
7476
- build
7577
rules:
7678
- !reference [.staging_branch_rules, rules]
77-
extends: .build_template
79+
extends: .build_template_mqtt_tcp_component
7880
image: espressif/idf:latest
7981
parallel:
8082
matrix:
8183
- IDF_TARGET: ["esp32p4", "esp32h2"]
8284
IDF_SLAVE_TARGET: ["esp32", "esp32c2", "esp32c3", "esp32s3" ]
83-
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
8485

8586
regression_build_idf_master_iperf:
8687
tags:

.gitlab/ci/sanity_pipeline_jobs.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,20 @@ premerge_check:
1515
###
1616

1717
### protocols/mqtt/tcp example
18+
### for master, mqtt/tcp example is now in Component Registry
1819
sanity_build_idf_master_mqtt_tcp:
1920
variables:
2021
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
22+
IDF_REGISTRY_COMPONENT: "espressif/mqtt"
23+
IDF_REGISTRY_COMPONENT_EXAMPLE: "tcp"
2124
rules:
2225
- !reference [.default_rules, rules]
23-
extends: .build_template
26+
extends: .build_template_mqtt_tcp_component
2427
image: espressif/idf:latest
2528
parallel:
2629
matrix:
2730
- IDF_TARGET: ["esp32p4"]
2831
IDF_SLAVE_TARGET: ["esp32c6", "esp32c5"]
29-
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
3032

3133
### wifi/iperf example
3234
sanity_build_idf_v5.5_iperf:

.gitlab/ci/templates.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,70 @@
7777
idf-build-apps build -p . -vv --target ${IDF_TARGET}
7878
fi
7979
80+
# build mqtt/tcp example from espressif/mqtt Registry Component
81+
.build_template_mqtt_tcp_component:
82+
stage: build
83+
tags:
84+
- build
85+
artifacts:
86+
paths:
87+
- "artifacts_*/"
88+
when: always
89+
expire_in: 4 days
90+
script:
91+
- export IDF_PYTHON_CHECK_CONSTRAINTS=yes
92+
- ${IDF_PATH}/install.sh --enable-ci
93+
- source ${IDF_PATH}/export.sh
94+
# Need to rename the cloned "esp_hosted_mcu" directory since the injected component name is "esp_hosted"
95+
- cd .. && rm -rf esp_hosted && mv esp_hosted_mcu esp_hosted && cd esp_hosted
96+
- export OVERRIDE_PATH=`pwd`
97+
# get the example from Component Registry
98+
- echo "Checking out example ${IDF_REGISTRY_COMPONENT}:${IDF_REGISTRY_COMPONENT_EXAMPLE}"
99+
- cd ..
100+
- idf.py create-project-from-example "${IDF_REGISTRY_COMPONENT}:${IDF_REGISTRY_COMPONENT_EXAMPLE}"
101+
- cd "${IDF_REGISTRY_COMPONENT_EXAMPLE}"
102+
# Override esp_hosted component in example's deps with the one from the current repository
103+
- mkdir components
104+
- ln -sf ${OVERRIDE_PATH} components/esp_hosted
105+
# Add slave target configuration if specified
106+
- |
107+
if [ ! -z "${IDF_SLAVE_TARGET}" ]; then
108+
echo "CONFIG_SLAVE_IDF_TARGET_${IDF_SLAVE_TARGET^^}=y" >> sdkconfig.defaults
109+
echo "Added slave target CONFIG_SLAVE_IDF_TARGET_${IDF_SLAVE_TARGET^^}=y to sdkconfig.defaults"
110+
fi
111+
# EXAMPLE_CI_FILE: use sdkconfig CI file in example directory
112+
- |
113+
if [ ! -z "${SDKCONFIG_CI_FILE}" ]; then
114+
cp ${OVERRIDE_PATH}/${SDKCONFIG_CI_FILE} ./sdkconfig.ci.custom
115+
echo "Using custom sdkconfig: ${SDKCONFIG_CI_FILE}"
116+
SDKCONFIG_PATTERN="sdkconfig.ci.custom"
117+
elif [ ! -z "${EXAMPLE_CI_FILE}" ]; then
118+
echo "Using CI sdkconfig file in example: ${EXAMPLE_CI_FILE}"
119+
SDKCONFIG_PATTERN="./${EXAMPLE_CI_FILE}"
120+
else
121+
SDKCONFIG_PATTERN="sdkconfig.ci*"
122+
fi
123+
- echo "SDKCONFIG_PATTERN is ${SDKCONFIG_PATTERN}"
124+
# Build with IDF pedantic flags and IDF build apps script
125+
- export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function"
126+
- export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes"
127+
- export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}"
128+
# use --config-file to override default IDF config file
129+
# use --enable-preview-targets to build for all targets
130+
# use --override-sdkconfig-items to override (possibly incorrect) build target that may be in provided config file
131+
- idf-build-apps find -p . --enable-preview-targets --config-file "${OVERRIDE_PATH}/.idf_build_apps.toml" --config ${SDKCONFIG_PATTERN} --override-sdkconfig-items=CONFIG_IDF_TARGET=${IDF_TARGET} -vv --target ${IDF_TARGET}
132+
- idf-build-apps build -p . --enable-preview-targets --config-file "${OVERRIDE_PATH}/.idf_build_apps.toml" --config ${SDKCONFIG_PATTERN} --override-sdkconfig-items=CONFIG_IDF_TARGET=${IDF_TARGET} -vv --target ${IDF_TARGET}
133+
# Copy config files back to project directory for artifacts
134+
- mkdir -p ${OVERRIDE_PATH}/artifacts_${IDF_TARGET}_${IDF_SLAVE_TARGET}
135+
- cp sdkconfig* ${OVERRIDE_PATH}/artifacts_${IDF_TARGET}_${IDF_SLAVE_TARGET}/ 2>/dev/null || echo "No sdkconfig files found"
136+
- cp main/idf_component.yml ${OVERRIDE_PATH}/artifacts_${IDF_TARGET}_${IDF_SLAVE_TARGET}/ 2>/dev/null || echo "No component file found"
137+
# Clean up the component symlink
138+
- unlink components/esp_hosted
139+
- echo "Cleaned up esp_hosted component symlink"
140+
# Rename back, since post scripts expect the original name
141+
- cd ${OVERRIDE_PATH} && cd .. && mv esp_hosted esp_hosted_mcu
142+
143+
80144
.build_template:
81145
stage: build
82146
tags:

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## 2.7.0
4+
5+
### Bug Fixes
6+
Restructured the ESP-Hosted-MCU commits
7+
8+
## 2.6.6
9+
10+
### Bug Fixes
11+
12+
- Fixed sta connection to remove extra disconnected event if incoming station config is different from current station config
13+
- IRAM size limitation when using UART transport only applies to ESP32, not to all SOCs.
14+
- workaround a bug in `esp_wifi_get_protocol()` that can cause memory corruption. See this [ESP-IDF Issue](https://github.com/espressif/esp-idf/issues/17502).
15+
- updated CI pipelines to build mqtt/tcp example from Registry Component on master branch
16+
317
## 2.6.5
418

519
### Features
@@ -8,7 +22,9 @@
822

923
## 2.6.4
1024

11-
- Fix the esp_wifi_deinit() call from host
25+
### Bug Fixes
26+
27+
- Fix the `esp_wifi_deinit()` call from host
1228

1329
## 2.6.3
1430

slave/main/slave_control.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
static wifi_config_t new_wifi_config = {0};
6060
static bool new_config_recvd = false;
61+
static bool suppress_disconnect = false; // true when we want to suppress the disconnect event
6162
static wifi_event_sta_connected_t lkg_sta_connected_event = {0};
6263

6364
enum {
@@ -656,10 +657,10 @@ static void event_handler_wifi(void* arg, esp_event_base_t event_base,
656657
int ret = esp_wifi_set_config(WIFI_IF_STA, &new_wifi_config);
657658
if (ret) {
658659
ESP_LOGE(TAG, "Error[0x%x] while setting the wifi config", ret);
659-
} else {
660-
new_config_recvd = 0;
661660
}
662661
esp_wifi_disconnect();
662+
// suppress the disconnect event since we force disconnect here
663+
suppress_disconnect = true;
663664
return;
664665
}
665666
station_connecting = false;
@@ -669,22 +670,31 @@ static void event_handler_wifi(void* arg, esp_event_base_t event_base,
669670
esp_wifi_internal_reg_rxcb(WIFI_IF_STA, (wifi_rxcb_t) wlan_sta_rx_callback);
670671
station_connected = true;
671672
} else if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
672-
station_connected = false;
673+
ESP_LOGI(TAG, "Sta mode disconnect");
673674
if (new_config_recvd) {
674675
ESP_LOGI(TAG, "New wifi config still unapplied, applying it");
675676
/* Still not applied new config, so apply it */
676677
int ret = esp_wifi_set_config(WIFI_IF_STA, &new_wifi_config);
677678
if (ret) {
678679
ESP_LOGE(TAG, "Error[0x%x] while setting the wifi config", ret);
679680
} else {
680-
new_config_recvd = 0;
681+
new_config_recvd = false;
681682
}
683+
station_connecting = true;
684+
esp_wifi_connect();
682685
}
686+
station_connected = false;
683687
esp_wifi_internal_reg_rxcb(WIFI_IF_STA, NULL);
684-
ESP_LOGI(TAG, "Sta mode disconnect");
685688
station_connecting = false;
686-
send_event_data_to_host(RPC_ID__Event_StaDisconnected,
687-
event_data, sizeof(wifi_event_sta_disconnected_t));
689+
if (!suppress_disconnect) {
690+
send_event_data_to_host(RPC_ID__Event_StaDisconnected,
691+
event_data, sizeof(wifi_event_sta_disconnected_t));
692+
wifi_event_sta_disconnected_t *ptr = (wifi_event_sta_disconnected_t *)event_data;
693+
ESP_LOGI(TAG, "disconnect due to reason: %d", ptr->reason);
694+
} else {
695+
ESP_LOGI(TAG, "suppressing disconnect event due to new config");
696+
suppress_disconnect = false;
697+
}
688698
#if CONFIG_SOC_WIFI_HE_SUPPORT
689699
} else if (event_id == WIFI_EVENT_ITWT_SETUP) {
690700
ESP_LOGI(TAG, "Itwt Setup");
@@ -1238,7 +1248,7 @@ static esp_err_t req_wifi_connect(Rpc *req, Rpc *resp, void *priv_data)
12381248

12391249
if (new_config_recvd || !station_connected) {
12401250
ESP_LOGI(TAG, "************ connect ****************");
1241-
//station_connecting = true;
1251+
station_connecting = true;
12421252
ret = esp_wifi_connect();
12431253
if (ret != ESP_OK) {
12441254
ESP_LOGE(TAG, "Failed to connect to WiFi: %d", ret);
@@ -1286,7 +1296,7 @@ static bool wifi_is_provisioned(wifi_config_t *wifi_cfg)
12861296
ESP_LOGI(TAG, "Wifi provisioned");
12871297
return true;
12881298
}
1289-
ESP_LOGI(TAG, "Wifi not provisioned, Fallback to example config");
1299+
ESP_LOGI(TAG, "Wifi not provisioned");
12901300

12911301
return false;
12921302
}
@@ -1342,16 +1352,26 @@ esp_err_t esp_hosted_set_sta_config(wifi_interface_t iface, wifi_config_t *cfg)
13421352
ESP_LOGW(TAG, "not provisioned and failed to set wifi config");
13431353
} else {
13441354
ESP_LOGI(TAG, "Provisioned new Wi-Fi config");
1345-
new_config_recvd = true;
1346-
station_connecting = false;
1355+
new_config_recvd = false;
1356+
return ESP_OK;
13471357
}
13481358
}
13491359

13501360
if (!is_wifi_config_equal(cfg, &current_config)) {
1351-
new_config_recvd = true;
1352-
station_connecting = false;
1353-
ESP_LOGI(TAG, "Setting new WiFi config SSID: %s", cfg->sta.ssid);
1354-
memcpy(&new_wifi_config, cfg, sizeof(wifi_config_t));
1361+
if (station_connecting) {
1362+
ESP_LOGI(TAG, "Caching new WiFi config SSID: %s", cfg->sta.ssid);
1363+
memcpy(&new_wifi_config, cfg, sizeof(wifi_config_t));
1364+
new_config_recvd = true;
1365+
} else {
1366+
if (esp_wifi_set_config(WIFI_IF_STA, cfg) != ESP_OK) {
1367+
ESP_LOGW(TAG, "already provisioned but failed to set wifi config: copying to cache instead");
1368+
memcpy(&new_wifi_config, cfg, sizeof(wifi_config_t));
1369+
new_config_recvd = true;
1370+
} else {
1371+
ESP_LOGI(TAG, "Setting new WiFi config SSID: %s", cfg->sta.ssid);
1372+
new_config_recvd = false;
1373+
}
1374+
}
13551375
} else {
13561376
ESP_LOGI(TAG, "WiFi config unchanged, keeping current connection");
13571377
new_config_recvd = false;
@@ -1804,8 +1824,12 @@ static esp_err_t req_wifi_get_protocol(Rpc *req, Rpc *resp, void *priv_data)
18041824
RpcReqWifiGetProtocol, req_wifi_get_protocol,
18051825
rpc__resp__wifi_get_protocol__init);
18061826

1807-
uint8_t protocol_bitmap = 0;
1808-
RPC_RET_FAIL_IF(esp_wifi_get_protocol(req_payload->ifx, &protocol_bitmap));
1827+
/** due to a bug in some ESP-IDF releases, esp_wifi_get_protocol() treats
1828+
* the incoming pointer as a uint16_t *, corrupting the next byte
1829+
* see https://github.com/espressif/esp-idf/issues/17502
1830+
*/
1831+
uint32_t protocol_bitmap = 0; // for safety
1832+
RPC_RET_FAIL_IF(esp_wifi_get_protocol(req_payload->ifx, (uint8_t *)&protocol_bitmap));
18091833

18101834
resp_payload->protocol_bitmap = protocol_bitmap;
18111835
return ESP_OK;

slave/main/uart_slave_api.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@
4141

4242
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0))
4343
/**
44-
* For ESP-IDF v5.5, Building with UART Transport can fail due to
44+
* For ESP-IDF v5.5, Building ESP32 with UART Transport can fail due to
4545
* lack of IRAM space.
4646
* To reduce IRAM usage, `CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y`
4747
* should be enabled
4848
*/
49-
#if !CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH
49+
#if CONFIG_IDF_TARGET_ESP32 && !CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH
5050
#error Building for UART transport can fail due to lack of IRAM space
5151
#error To free up IRAM, enable Component config --> ESP Ringbuf ---> Place non-ISR ringbuf functions into flash
5252
#error or uncomment CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y in sdkconfig.defaults.esp32 and regenerate sdkconfig

0 commit comments

Comments
 (0)