Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add esp_custom_part_ota component (IEC-195) #328

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

hmalpani
Copy link
Contributor

@hmalpani hmalpani commented May 16, 2024

Add new component to support OTA updates for non-app type partitions in ESP-IDF

Checklist

  • Component contains License
  • Component contains README.md
  • Component contains idf_component.yml file with url field defined
  • Add Example
  • Add Component Unit tests
  • Component was added to upload job
  • Component was added to build job
  • Optional: Component contains unit tests
  • CI passing

Change description

Please describe your change here

@hmalpani hmalpani marked this pull request as draft May 16, 2024 11:33
@hmalpani hmalpani force-pushed the feat/non_app_ota_update branch 2 times, most recently from a14c6c1 to 0bac912 Compare May 23, 2024 07:05
@hmalpani hmalpani changed the title feat: Add esp_non_app_ota component feat: Add esp_custom_part_ota component May 23, 2024
@hmalpani hmalpani force-pushed the feat/non_app_ota_update branch 2 times, most recently from 3551754 to a337719 Compare May 24, 2024 08:57
esp_custom_part_ota/include/esp_custom_part_ota.h Outdated Show resolved Hide resolved
esp_custom_part_ota/include/esp_custom_part_ota.h Outdated Show resolved Hide resolved
esp_custom_part_ota/include/esp_custom_part_ota.h Outdated Show resolved Hide resolved
esp_custom_part_ota/src/esp_custom_part_ota.c Outdated Show resolved Hide resolved
esp_custom_part_ota/src/esp_custom_part_ota.c Outdated Show resolved Hide resolved
ESP_LOGI(TAG, "No backup present in the backup partition. Nothing to restore");
return ESP_OK;
}
if (handle->backup_len > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could there be a scenario where this length is partial and not for full image? Do we need any image integrity checks (e.g., SHA sum) in the NVS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the user can set the length of the data to be backed-up. I don't think we need any image integrity checks. We store the size of data in NVS. Also in case of any error, the APIs will return relevant error code.

return ESP_ERR_NO_MEM;
}

esp_err_t ret = esp_partition_erase_range(ctx->backup_partition, 0, ctx->backup_len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we allow this API to be executed twice for 2 different partitions? If not, how can we detect if there exist a backup for any previous partition? Do we need some API to invalidate the previous backup here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right. I didn't think of this case. I think we can store some information in NVS regarding this and iterate over the data to check if some other backup is stored in the partition.

static const char *TAG = "esp_custom_part_ota";

#define BACKUP_STORAGE_NAMESPACE "esp_custom_ota"
#define BACKUP_STORAGE_DATA_LEN "backup_len"
Copy link
Member

@mahavirj mahavirj May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it help if we make this variable partition specific:

snprintf(str, size, "%s_backup_len", part_name)

This component can be used for performing OTA upgrades for custom partitions in ESP-IDF
@@ -0,0 +1,43 @@
# ESP Non-App OTA Updates

This component provides an API interface to update the Non-App type partitions using ESP_IDF.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This component provides an API interface to update the Non-App type partitions using ESP_IDF.
This component provides an API interface to update the Non-App type partitions using ESP-IDF.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


`esp_custom_part_ota` component supports OTA update using two schemes:

### Scheme 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to provide a name for these schemes rather than just calling them Scheme 1 and Scheme 2

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given name as custom_part_ota_backup and custom_part_ota

Here the non-app partition which we are trying to update is spiffs. When the user wants to update the spiffs partition, the workflow will be as follows:

* Consider that ota_0 is the current running partition.
* Copy the data from the spiffs partition to the backup partition.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should first explain what the backup partition is.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added this line (backup partition will be always ota passive partition), backup word.

Backup partition can be specified using `backup_partition` field in `esp_custom_part_ota_cfg_t` structure. If no backup partition is specified, the passive app partition will be set as the backup partition by default.

### Scheme 2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better if we provide some clear reasoning for when to choose scheme 1 and when to use scheme 2.
One might be as follows

  1. There is limited flash available on the chip and no backup partition can be assigned for the OTA process. In that case scheme 2 might be helpful
  2. This is unsafe and can result in loss of data if the OTA is interrupted.

esp_http_client_cleanup(client);
}

static void custom_part_ota_example_task(void *pvParameter)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is question more related to the structure of the component itself.
Considering this is the core logic of the component which performs the actual OTA process. Should this be located in the src directory rather than the shown as an example?
I would prefer if simple APIs are provided to the user just to perform the OTA process.

esp_http_client_cleanup(client);
task_fatal_error();
}
esp_http_client_fetch_headers(client);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take backup of the partition here after ensuring the ability to perform OTA has been confirmed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also add the check here that the data length given to us by the server fits in the partition to be updated.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added checks which ensures whether the firmware length is greater than partition length

ret = nvs_set_u32(backup_info_handle, BACKUP_STORAGE_DATA_LEN, 0);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to store backup information: %s", esp_err_to_name(ret));
return ret;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if we should give an option to explicitly clear the backup information in the NVS

ESP_LOGE(TAG, "Failed to store backup information: %s", esp_err_to_name(ret));
return ret;
}
ret = nvs_set_u32(backup_info_handle, BACKUP_STORAGE_DATA_LEN, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also store the name of the backup partition?

@hrushikesh430 hrushikesh430 mentioned this pull request Aug 23, 2024
6 tasks
return ESP_ERR_INVALID_ARG;
}
esp_custom_part_ota_t *ctx = (esp_custom_part_ota_t *)handle;
free(ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should update the NVS entry at this point

@github-actions github-actions bot changed the title feat: Add esp_custom_part_ota component feat: Add esp_custom_part_ota component (IEC-195) Oct 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants