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

applications: serial_lte_modem: Fix asserts when pressing power pin #21081

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

trantanen
Copy link
Contributor

Asserts were enabled with PR #20040.
This has caused an assert to occur when pressing power pin, because GPIO callback (power_pin_callback_wakeup()) called slm_at_host_power_on(), which called k_sleep(), which has an assert that it's not called from interrupt context. Added most of the wake up operation into a worker.

Also added a command to modem_slm library for toggling power pin. In addition, adding main command for operations done in SLM shell device. Toggling power pin is done as follows:
"slmsh powerpin"

I have some follow-up PRs for SLM shell so I'll also update its documentation then regarding the new command. I'd like to get these changes in whenever they are technically OK so that test engineers can proceed testing the power pin.

@github-actions github-actions bot added the changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. label Mar 21, 2025
@trantanen trantanen requested a review from a team March 21, 2025 07:56
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Mar 21, 2025

CI Information

To view the history of this post, clich the 'edited' button above
Build number: 4

Inputs:

Sources:

more details

Github labels

Enabled Name Description
ci-disabled Disable the ci execution
ci-all-test Run all of ci, no test spec filtering will be done
ci-force-downstream Force execution of downstream even if twister fails
ci-run-twister Force run twister
ci-run-zephyr-twister Force run zephyr twister
List of changed files detected by CI (0)

Outputs:

Toolchain

Version:
Build docker image:

Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped; ⚠️ Quarantine

  • ❌ Toolchain
  • ❌ Build twister
  • ❌ Integration tests

Note: This message is automatically posted and updated by the CI

@trantanen trantanen force-pushed the slm_powerpin_assert branch from c3bf395 to 47c081e Compare March 21, 2025 07:59
* so that it doesn't fire right away (which it does if enabled here).
*/
k_work_schedule(&work, K_MSEC(1));
configure_power_pin_interrupt(power_pin_callback_poweroff, GPIO_INT_EDGE_RISING);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tomi-font Do you remember what happened if GPIO was configured here? The comment says it would have fired immediately but I haven't experienced issues with this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would this have been because we were level triggered at some point? Cannot recall exactly.

SHELL_CMD_REGISTER(slm, NULL, "Send AT commands to SLM device", modem_slm_shell);

SHELL_STATIC_SUBCMD_SET_CREATE(
sub_slmsh,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've made slmsh as the main command for shell commands that are executed in the SLM shell device. Better naming for "SLM shell device" or for the command name are welcome.

Copy link

You can find the documentation preview for this PR here.

@trantanen trantanen force-pushed the slm_powerpin_assert branch from 47c081e to 466eb13 Compare March 21, 2025 10:36
* so that it doesn't fire right away (which it does if enabled here).
*/
k_work_schedule(&work, K_MSEC(1));
configure_power_pin_interrupt(power_pin_callback_poweroff, GPIO_INT_EDGE_RISING);
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this have been because we were level triggered at some point? Cannot recall exactly.

@@ -276,12 +273,21 @@ static void power_pin_callback_wakeup(const struct device *dev,
return;
}

atomic_set(&callback_running, false);
Copy link
Contributor

@MarkusLassila MarkusLassila Mar 21, 2025

Choose a reason for hiding this comment

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

This needs to be in power_pin_callback_wakeup. Level triggered GPIO can cause multiple calls to power_pin_callback_wakeup. I am uncertain whether removing the callback as the very first thing would prevent this.

Also, in older version, the callback is only removed when we have brought the UART up. Now if the power_pin_callback_wakeup_work_fn somehow fails, the only way to bring the UART up is to reset the SLM from the external MCU.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both of these topics are something I've been thinking a lot when doing the change.

This needs to be in power_pin_callback_wakeup. Level triggered GPIO can cause multiple calls to power_pin_callback_wakeup. I am uncertain whether removing the callback as the very first thing would prevent this.

I haven't seen problems in form of multiple calls to power_pin_callback_wakeup() function when pressing power pin. I could move the following block from power_pin_callback_wakeup_work_fn() to power_pin_callback_wakeup() if needed:

	/* Prevent level triggered interrupt running this multiple times. */
	if (!atomic_cas(&callback_running, false, true)) {
		return;
	}

But I would say that then atomic_set(&callback_running, false); should still be here as it is.

However, if we determine that gpio_remove_callback function call handles this properly then the whole callback_running could be removed.

Also, in older version, the callback is only removed when we have brought the UART up. Now if the power_pin_callback_wakeup_work_fn somehow fails, the only way to bring the UART up is to reset the SLM from the external MCU.

I had mistakenly thought that since we set configure_power_pin_interrupt(power_pin_callback_enable_poweroff, GPIO_INT_EDGE_RISING); in power_pin_callback_wakeup(), this would be handled into some extent but that will then power off the SLM device instead of return to "normal mode" from idle. I'm adding setting of these GPIOs and callbacks into power_pin_callback_wakeup_work_fn() and also into the error branch.

Asserts were enabled with PR nrfconnect#20040.
This has caused an assert to occur when pressing power pin,
because GPIO callback (power_pin_callback_wakeup)
called slm_at_host_power_on, which called k_sleep(),
which has an assert that it's not called from interrupt context.
Added most of the wake up operation into a worker.

Jira: LRCS-70

Signed-off-by: Tommi Rantanen <tommi.rantanen@nordicsemi.no>
Add command for toggling power pin.
Also adding main command for operations done in SLM shell device.
Toggling is done as follows:
"slmsh powerpin"

Jira: LRCS-84

Signed-off-by: Tommi Rantanen <tommi.rantanen@nordicsemi.no>
@trantanen trantanen force-pushed the slm_powerpin_assert branch from 466eb13 to e1fb005 Compare March 21, 2025 14:10
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants