11/*
2- * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
@@ -29,6 +29,29 @@ _Static_assert(DEFAULT_OTA_BUF_SIZE > (sizeof(esp_image_header_t) + sizeof(esp_i
2929/* Setting event group */
3030#define MSC_CONNECT (1 << 0) // MSC device connect
3131
32+ /**
33+ * @brief To prevent the VFS from being unregistered during file read and write operations.
34+ *
35+ * @param semaphore Semaphore to take.
36+ * @return esp_err_t
37+ * - ESP_OK on success or if the semaphore is NULL.
38+ * - ESP_FAIL if taking the semaphore fails.
39+ */
40+ #define SEMAPHORE_TAKE (semaphore ) \
41+ ((semaphore == NULL) ? ESP_OK : \
42+ ((xSemaphoreTake(semaphore, pdMS_TO_TICKS(10)) == pdTRUE) ? ESP_OK : ESP_FAIL))
43+
44+ /**
45+ * @brief To prevent the VFS from being unregistered during file read and write operations.
46+ *
47+ * @param semaphore Semaphore to give.
48+ * @return esp_err_t
49+ * - ESP_OK on success or if the semaphore is NULL.
50+ */
51+ #define SEMAPHORE_GIVE (semaphore ) \
52+ ((semaphore == NULL) ? ESP_OK : \
53+ (xSemaphoreGive(semaphore), ESP_OK))
54+
3255typedef struct {
3356 EventGroupHandle_t mscEventGroup ;
3457 bool bulk_flash_erase ;
@@ -107,6 +130,7 @@ esp_msc_ota_status_t esp_msc_ota_get_status(esp_msc_ota_handle_t handle)
107130
108131static esp_err_t _read_header (esp_msc_ota_t * msc_ota )
109132{
133+ esp_err_t err = ESP_OK ;
110134 EventBits_t bits = xEventGroupWaitBits (msc_ota -> mscEventGroup , MSC_CONNECT , pdFALSE , pdFALSE , 0 );
111135 MSC_OTA_CHECK (bits & MSC_CONNECT , "msc can't be disconnect" , ESP_ERR_INVALID_STATE );
112136 /*
@@ -115,6 +139,8 @@ static esp_err_t _read_header(esp_msc_ota_t *msc_ota)
115139 int data_read_size = IMAGE_HEADER_SIZE ;
116140 int data_read = 0 ;
117141
142+ err = SEMAPHORE_TAKE (msc_read_semaphore );
143+ MSC_OTA_CHECK (err == ESP_OK , "take msc_read_semaphore failed" , ESP_FAIL );
118144 FILE * file = fopen (msc_ota -> ota_bin_path , "rb" );
119145 MSC_OTA_CHECK (file != NULL , "Failed to open file for reading" , ESP_ERR_NOT_FOUND );
120146
@@ -125,27 +151,28 @@ static esp_err_t _read_header(esp_msc_ota_t *msc_ota)
125151 data_read_size = data_read_size > fileLength ? fileLength : data_read_size ;
126152 ESP_LOGI (TAG , "Reading file %s, size: %d, total size: %" PRIu32 "" , msc_ota -> ota_bin_path , data_read_size , fileLength );
127153
128- BaseType_t ret = xSemaphoreTake (msc_read_semaphore , pdMS_TO_TICKS (10 ));
129- MSC_OTA_CHECK (ret == pdTRUE , "take msc_read_semaphore failed" , ESP_FAIL );
130154 data_read = fread (msc_ota -> ota_upgrade_buf , 1 , data_read_size , file );
131- xSemaphoreGive (msc_read_semaphore );
132155
133156 if (data_read == data_read_size ) {
134157 msc_ota -> binary_file_read_len = data_read ;
135- fclose ( file ) ;
136- return ESP_OK ;
158+ err = ESP_OK ;
159+ goto file_close ;
137160 } else if (data_read > 0 && data_read < data_read_size ) {
138161 msc_ota -> binary_file_read_len = data_read ;
139- fclose ( file ) ;
140- return ESP_OK ;
162+ err = ESP_OK ;
163+ goto file_close ;
141164 } else if (ferror (file )) {
165+ err = ESP_FAIL ;
142166 ESP_LOGI (TAG , "Error reading from file" );
143167 } else if (feof (file )) {
144- ESP_LOGI (TAG , "End of file reached.\n" );
168+ err = ESP_FAIL ;
169+ ESP_LOGI (TAG , "End of file reached." );
145170 }
146171
172+ file_close :
147173 fclose (file );
148- return ESP_FAIL ;
174+ SEMAPHORE_GIVE (msc_read_semaphore );
175+ return err ;
149176}
150177
151178static esp_err_t _ota_verify_chip_id (const void * arg )
@@ -198,9 +225,14 @@ esp_err_t esp_msc_ota_begin(esp_msc_ota_config_t *config, esp_msc_ota_handle_t *
198225
199226 esp_event_handler_register (ESP_MSC_HOST_EVENT , ESP_EVENT_ANY_ID , & _esp_msc_host_handler , msc_ota );
200227
201- ESP_LOGI (TAG , "Waiting for MSC device to connect..." );
202- EventBits_t bits = xEventGroupWaitBits (msc_ota -> mscEventGroup , MSC_CONNECT , pdFALSE , pdFALSE , config -> wait_msc_connect );
203- MSC_OTA_CHECK_GOTO (bits & MSC_CONNECT , "TIMEOUT: MSC device not connected" , msc_cleanup );
228+ if (!config -> skip_msc_connect_wait ) {
229+ ESP_LOGI (TAG , "Waiting for MSC device to connect..." );
230+ EventBits_t bits = xEventGroupWaitBits (msc_ota -> mscEventGroup , MSC_CONNECT , pdFALSE , pdFALSE , config -> wait_msc_connect );
231+ MSC_OTA_CHECK_GOTO (bits & MSC_CONNECT , "TIMEOUT: MSC device not connected" , msc_cleanup );
232+ } else {
233+ xEventGroupSetBits (msc_ota -> mscEventGroup , MSC_CONNECT );
234+ ESP_LOGI (TAG , "skip_msc_connect_wait is true, set MSC_CONNECT event directly" );
235+ }
204236
205237 msc_ota -> update_partition = NULL ;
206238 ESP_LOGI (TAG , "Starting OTA..." );
@@ -272,20 +304,23 @@ esp_err_t esp_msc_ota_perform(esp_msc_ota_handle_t handle)
272304 MSC_OTA_CHECK (bits & MSC_CONNECT , "msc can't be disconnect" , ESP_ERR_INVALID_STATE );
273305 if (msc_ota -> file == NULL ) {
274306
307+ err = SEMAPHORE_TAKE (msc_read_semaphore );
308+ MSC_OTA_CHECK (err == ESP_OK , "take msc_read_semaphore failed" , ESP_FAIL );
275309 FILE * file = fopen (msc_ota -> ota_bin_path , "rb" );
276310 MSC_OTA_CHECK (file != NULL , "Failed to open file for reading" , ESP_ERR_NOT_FOUND );
277311 fseek (file , msc_ota -> binary_file_read_len , SEEK_CUR );
312+ SEMAPHORE_GIVE (msc_read_semaphore );
278313 msc_ota -> file = file ;
279314 }
280315 uint32_t * fileLength = & msc_ota -> binary_file_read_len ;
281316 uint32_t * totalLength = & msc_ota -> binary_file_len ;
282317 if (* fileLength < * totalLength ) {
283318 size_t readLength = * fileLength > msc_ota -> ota_upgrade_buf_size ? msc_ota -> ota_upgrade_buf_size : * fileLength ;
284319
285- BaseType_t ret = xSemaphoreTake (msc_read_semaphore , pdMS_TO_TICKS ( 10 ) );
286- MSC_OTA_CHECK (ret == pdTRUE , "take msc_read_semaphore failed" , ESP_FAIL );
320+ err = SEMAPHORE_TAKE (msc_read_semaphore );
321+ MSC_OTA_CHECK (err == ESP_OK , "take msc_read_semaphore failed" , ESP_FAIL );
287322 data_read = fread (msc_ota -> ota_upgrade_buf , 1 , readLength , msc_ota -> file );
288- xSemaphoreGive (msc_read_semaphore );
323+ SEMAPHORE_GIVE (msc_read_semaphore );
289324
290325 MSC_OTA_CHECK (data_read > 0 , "Failed to read file" , ESP_ERR_INVALID_SIZE );
291326 err = esp_ota_write (msc_ota -> update_handle , (const void * )msc_ota -> ota_upgrade_buf , data_read );
@@ -299,7 +334,10 @@ esp_err_t esp_msc_ota_perform(esp_msc_ota_handle_t handle)
299334 }
300335 if (* fileLength >= * totalLength ) {
301336 msc_ota -> status = ESP_MSC_OTA_SUCCESS ;
337+ err = SEMAPHORE_TAKE (msc_read_semaphore );
338+ MSC_OTA_CHECK (err == ESP_OK , "take msc_read_semaphore failed" , ESP_FAIL );
302339 fclose (msc_ota -> file );
340+ SEMAPHORE_GIVE (msc_read_semaphore );
303341 return ESP_OK ;
304342 }
305343 return ESP_OK ;
@@ -338,6 +376,7 @@ esp_err_t esp_msc_ota_end(esp_msc_ota_handle_t handle)
338376 }
339377 }
340378 esp_event_handler_unregister (ESP_MSC_HOST_EVENT , ESP_EVENT_ANY_ID , & _esp_msc_host_handler );
379+ vEventGroupDelete (msc_ota -> mscEventGroup );
341380 free (msc_ota );
342381 esp_msc_ota_dispatch_event (ESP_MSC_OTA_FINISH , NULL , 0 );
343382 return err ;
@@ -353,7 +392,10 @@ esp_err_t esp_msc_ota_abort(esp_msc_ota_handle_t handle)
353392 case ESP_MSC_OTA_SUCCESS :
354393 case ESP_MSC_OTA_IN_PROGRESS :
355394 if (msc_ota -> file ) {
395+ err = SEMAPHORE_TAKE (msc_read_semaphore );
396+ MSC_OTA_CHECK (err == ESP_OK , "take msc_read_semaphore failed" , ESP_FAIL );
356397 fclose (msc_ota -> file );
398+ SEMAPHORE_GIVE (msc_read_semaphore );
357399 }
358400 err = esp_ota_abort (msc_ota -> update_handle );
359401 [[fallthrough ]];
0 commit comments