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

lib: nrf_modem: init once on dfu apply #105

Merged
merged 3 commits into from
Sep 19, 2023

Conversation

eivindj-nordic
Copy link
Collaborator

@eivindj-nordic eivindj-nordic commented May 30, 2023

It is no longer necessary to call nrf_modem_init twice when applying modem firmware updates.

@eivindj-nordic eivindj-nordic self-assigned this May 30, 2023
@eivindj-nordic eivindj-nordic changed the title [WiP] lib: nrf_modem: init once on dfu apply lib: nrf_modem: init once on dfu apply Jun 12, 2023
Comment on lines 35 to 36
mosh_error("FOTA: Expected DFU result from modem library, "
"but no DFU was triggered");
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is now the expected behavior, so make it visible that firmware update was successful. This output is also expected by our tests.

Suggested change
mosh_error("FOTA: Expected DFU result from modem library, "
"but no DFU was triggered");
mosh_print("FOTA: Modem firmware update successful!");

handle_nrf_modem_lib_init_ret(modem_lib_init_ret);

nrf_modem_at_cmd(buf, sizeof(buf), "%s", "AT%SHORTSWVER");
if (strstr(buf, "1.3.4") || strstr(buf, "1.3.5")) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note, this has been removed already by nrfconnect#12086.
This branch/repo is not quite up to date with NCS's main.

@@ -379,20 +369,20 @@ int main(void)
LOG_WRN("Failed to init slm settings");
}

const int ret = nrf_modem_lib_init();

int ret = nrf_modem_lib_init();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do I understand correctly that nrf_modem_on_dfu_res() will get called right before nrf_modem_lib_init() returns?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, or rather, right before nrf_modem_init() returns to nrf_modem_lib_init(), so the NRF_MODEM_LIB_ON_INIT hooks are called after.

Comment on lines 60 to 65
/**
* @brief Handles @ref nrf_modem_lib_init() return values
* relating to modem firmware update.
*
* @return Whether the modem must be re-initialized.
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/**
* @brief Handles @ref nrf_modem_lib_init() return values
* relating to modem firmware update.
*
* @return Whether the modem must be re-initialized.
*/

Comment on lines 66 to 67
void handle_nrf_modem_lib_init_ret(int modem_lib_init_ret);

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
void handle_nrf_modem_lib_init_ret(int modem_lib_init_ret);

This function does not exist anymore.

@@ -250,17 +250,17 @@ static int handle_at_modemreset(enum at_cmd_type type)
++step;

ret = nrf_modem_lib_init();

Copy link
Collaborator

Choose a reason for hiding this comment

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

It could be good to add a small comment saying that nrf_modem_on_dfu_res() will get indirectly called to help follow the logic of the fota_* variables (which was already messy).

.callback = _callback, \
.context = _context, \
};

Copy link
Collaborator

Choose a reason for hiding this comment

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

nrf_modem_lib_init()'s description probably has to be updated (at least regarding the return values)?

Comment on lines 253 to 258
LOG_INF("nRF Modem firmware update succeeded");
if (fota_stage == FOTA_STAGE_ACTIVATE) {
fota_stage = FOTA_STAGE_COMPLETE;
fota_status = FOTA_STATUS_OK;
fota_info = 0;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
LOG_INF("nRF Modem firmware update succeeded");
if (fota_stage == FOTA_STAGE_ACTIVATE) {
fota_stage = FOTA_STAGE_COMPLETE;
fota_status = FOTA_STATUS_OK;
fota_info = 0;
}
LOG_INF("nRF Modem firmware update succeeded");
fota_stage = FOTA_STAGE_COMPLETE;
fota_status = FOTA_STATUS_OK;
fota_info = 0;

Not that it should matter, but just to keep the logic as-is...

/* TODO: This should indicate to the host MCU that the modem is not initialized and
* whether it can be retried or if it is required to reprogram the modem firmware.
* Also, when the modem lib is not initialized, this will fail at start_execute().
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

There could be a log conditionally output (if we're here due to some reason other than the LOW_VOLTAGE error) to say something similar to line 269?
Otherwise, if LOW_VOLTAGE happened, then I think there is nothing to do as nrf_modem_on_dfu_res() should already have updated the fota_* variables appropriately. In that case the SLM should work normally, with the modem running its original firmware.

Copy link
Collaborator

@tomi-font tomi-font left a comment

Choose a reason for hiding this comment

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

Good to me from the SLM's perspective.

@eivindj-nordic eivindj-nordic force-pushed the dfu_init_once branch 3 times, most recently from 67cecd2 to 01a9fa7 Compare September 11, 2023 07:35
{
int ret = nrf_modem_lib_init();

/* Handle return values*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/* Handle return values*/
/* Handle return values */

@@ -4,8 +4,16 @@
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/* Use high drive mode on SPI pins that handle communication with nRF7002
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does this change belong to this commit?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Uhm, this should be removed. Thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated.

int ret = nrf_modem_lib_init();

/* Handle return values */
switch (ret) {
Copy link
Owner

Choose a reason for hiding this comment

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

this can be a simple if statement now

* considered irrecoverable and a reboot is needed.
*/
/* Unknown DFU result code */
LOG_ERR("nRF modem DFU failed, error: %d", dfu_res);
Copy link
Owner

Choose a reason for hiding this comment

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

Since these errors are defined in hexadecimal, we could print them as hexadecimal so it's easier to see what errors we get (applies everywhere else where we print these)

@@ -109,6 +112,15 @@ static void log_fw_version_uuid(void)
}
}

static void nrf_modem_lib_dfu_handler(uint32_t dfu_res)
{
LOG_DBG("Modem library dfu res %d", dfu_res);
Copy link
Owner

Choose a reason for hiding this comment

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

nit: Modem firmware update result 0x%x

LOG_INF("Modem firmware update successful!");
LOG_INF("Modem will run the new firmware after reboot");
k_thread_suspend(k_current_get());
LOG_DBG("nRF Modem firmware updated");
Copy link
Owner

Choose a reason for hiding this comment

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

nit: why nRF here?

Copy link
Owner

Choose a reason for hiding this comment

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

Applies to the rest of the PR as well

case NRF_MODEM_DFU_RESULT_AUTH_ERROR:
case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR:
LOG_ERR("Modem FOTA error: %d", modem_lib_init_result);
} else if (modem_lib_init_result == -EIO || modem_lib_init_result == -EAGAIN) {
Copy link
Owner

Choose a reason for hiding this comment

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

We are changing the behavior here.

Earlier, failing to update the modem firmware (for whatever reason) would let this function return _VALIDATE_FAIL.
Now, failing to update the modem firmware will let this function return _VALIDATE_FAIL only if the error is one of the two fatal errors, or low power. And actually in all those cases, we are unable to report that to the cloud in any way, since the modem can't be initialized.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If the modem init fails because of a FOTA error, we either return EAGAIN (retriable, e.g. voltage low error) or EIO (non retriable). If the error is something else, the modem has responded with an initialization error on the second init. So the update may have succeeded but the modem is not initialized.

Copy link
Owner

Choose a reason for hiding this comment

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

what I am trying to say is that earlier NRF_MODEM_DFU_RESULT_UUID_ERROR resulted in NRF_CLOUD_FOTA_VALIDATE_FAIL, since the update failed.

Now we NRF_MODEM_DFU_RESULT_UUID_ERROR lets nrf_modem_lib_init return 0, and this function returns NRF_CLOUD_FOTA_VALIDATE_PASS, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, I see, yes, you're right!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Guess we'll need a hook here as well then.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated.

@@ -641,7 +641,7 @@ ZTEST(lwm2m_client_utils_firmware, test_firmware_update)
printf("State %d\r\n", state);
zassert_equal(state, STATE_DOWNLOADED, "wrong result value");

lwm2m_firmware_emulate_modem_lib_init(NRF_MODEM_DFU_RESULT_AUTH_ERROR);
lwm2m_firmware_emulate_modem_lib_init(-NRF_EAGAIN);
Copy link
Owner

Choose a reason for hiding this comment

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

why -EAGAIN instead of -EIO?

Copy link
Collaborator

@MarkusLassila MarkusLassila left a comment

Choose a reason for hiding this comment

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

SLM looks good.

tomi-font and others added 2 commits September 18, 2023 10:03
Working around the modem firmware bug
is now taken care of by the modem library.

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
It is no longer necessary to call nrf_modem_init twice when applying
modem firmware updates.

Signed-off-by: Eivind Jølsgard <eivind.jolsgard@nordicsemi.no>
@eivindj-nordic eivindj-nordic force-pushed the dfu_init_once branch 2 times, most recently from 405fcdf to 1117c8d Compare September 18, 2023 10:55
Add modem init return values.

Signed-off-by: Eivind Jølsgard <eivind.jolsgard@nordicsemi.no>
@lemrey lemrey merged commit 76be615 into lemrey:libmodem Sep 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants