Skip to content

Conversation

@ndrs-pst
Copy link
Contributor

@ndrs-pst ndrs-pst commented Jun 21, 2024

This PR aims to eliminate the dependency on ctx_shell in the Bluetooth host/shell/*, making the code more maintainable.

  • Introduced bt_shell_private.c and bt_shell_private.h to provide common functions for the Bluetooth shell.
  • Limit the usage of ctx_shell to cases where printing requires it and sh is not available.
    (Interim commit before switch to bt_shell_*)
  • Refactor shell print to eliminate ctx_shell usage in the Bluetooth host/shell/*.

Fixes #41796

@zephyrbot zephyrbot added area: Bluetooth Host Bluetooth Host (excluding BR/EDR) area: Bluetooth labels Jun 21, 2024
@ndrs-pst ndrs-pst force-pushed the pr_bt_shell_refactor branch 2 times, most recently from 1f6268c to 204e867 Compare June 21, 2024 09:22
Copy link
Contributor

@Thalley Thalley left a comment

Choose a reason for hiding this comment

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

I don't think this is the right direction (but please do convince me if you believe so).

Some of the changes are welcome, but the idea of a bt_shell is IMO not.

In your commit message you mention that you want to remove the code footprint, but you also mention an increase cost of this new bt_shell. Aren't those two sentences conflicting?

The BT shell definitely needs improvement. I created a issue #70945 related to this, that requests the removed of the ctx_shell. The removal of the ctx_shell would directly conflict with the majority of this PR, as all the bt_shell functions you've defined will simply call the shell functions directly (as they would need the shell pointer again).

Could you provide some data on the codesize that you've increase/decreased?

@ndrs-pst
Copy link
Contributor Author

@Thalley Thank you for your feedback. It's good to hear that you're addressing ctx_shell. 😃

Aren't those two sentences conflicting?

At first glance, this might seem controversial.
Currently, many shell print require passing parameters like sh and color repeatedly.
By centralizing these interactions within specific bt_shell functions, we streamline the code.

Could you provide some data on the codesize that you've increase/decreased?

By picking up periodic_adv_conn sample with nrf52840dk boards and adding CONFIG_BT_SHELL=y
the footprint of shell\* which get from rom_report shown that

MODULE FLASH SIZE (BEFORE) FLASH SIZE (AFTER) INCREASE/DECREASE
bluetooth\shell\* 15,795 B 14,963 B -832 B
bt.c 13,251 B 12,275 B -976 B
bt_shell_private.c 0 B 144 B +144 B

Here is the footprint from each wrapper
bt_shell_private

@ndrs-pst
Copy link
Contributor Author

To stretch further, I think the functions that should be improved are
shell_fprintf_impl(sh, color, fmt, ##__VA_ARGS__) itself to have a wrapper for the color parameter.

void __printf_like(2, 3) shell_fprintf_error_impl(const struct shell *sh, const char *fmt, ...);
void __printf_like(2, 3) shell_fprintf_info_impl(const struct shell *sh, const char *fmt, ...);
void __printf_like(2, 3) shell_fprintf_print_impl(const struct shell *sh, const char *fmt, ...);
void __printf_like(2, 3) shell_fprintf_warn_impl(const struct shell *sh, const char *fmt, ...);

Since in reality the same message printed out inside the shell is always fixed to a specific color, and if we prioritize the code size, this should make sense.

Otherwise, every time, for example in Cortex-M, r1 needs to be allocated to pass the color value (while r0 is for sh), which causes the caller code to save the previously used r1.

@Thalley
Copy link
Contributor

Thalley commented Jun 28, 2024

Just tried your PR with the BT shell test application for the nrf5340dk_nrf5340_cpuapp board and got the following results:

With PR

Memory region         Used Size  Region Size  %age Used
           FLASH:      317356 B         1 MB     30.27%
             RAM:       52992 B       448 KB     11.55%
        IDT_LIST:          0 GB        32 KB      0.00%

Without PR

Memory region         Used Size  Region Size  %age Used
           FLASH:      318668 B         1 MB     30.39%
             RAM:       52992 B       448 KB     11.55%
        IDT_LIST:          0 GB        32 KB      0.00%

So while I do not agree with the direction of this PR, as we really need to get rid of ctx_shell, I can't disagree with the 1312 Bytes saved.

I'm not at a point where I'll approve, but I'm also not going to reject this change. I'd like to get input from the other BT collaborators on this.

@Thalley Thalley self-requested a review June 28, 2024 09:18
@Thalley Thalley dismissed their stale review June 28, 2024 09:18

Not sure yet

@ndrs-pst
Copy link
Contributor Author

@Thalley, thank you for the additional information. It seems we should start by getting rid of ctx_shell and then find a way to reduce the footprint.

@ndrs-pst ndrs-pst marked this pull request as draft June 28, 2024 09:32
@ndrs-pst
Copy link
Contributor Author

To stretch further, I think the functions that should be improved are shell_fprintf_impl(sh, color, fmt, ##__VA_ARGS__) itself to have a wrapper for the color parameter.

void __printf_like(2, 3) shell_fprintf_error_impl(const struct shell *sh, const char *fmt, ...);
void __printf_like(2, 3) shell_fprintf_info_impl(const struct shell *sh, const char *fmt, ...);
void __printf_like(2, 3) shell_fprintf_print_impl(const struct shell *sh, const char *fmt, ...);
void __printf_like(2, 3) shell_fprintf_warn_impl(const struct shell *sh, const char *fmt, ...);

Since in reality the same message printed out inside the shell is always fixed to a specific color, and if we prioritize the code size, this should make sense.

Otherwise, every time, for example in Cortex-M, r1 needs to be allocated to pass the color value (while r0 is for sh), which causes the caller code to save the previously used r1.

@Thalley Just a reminder that this stretch was merged in this PR: #75340. 👀

@github-actions
Copy link

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Sep 27, 2024
@ndrs-pst ndrs-pst force-pushed the pr_bt_shell_refactor branch from 204e867 to 45075db Compare October 4, 2024 11:29
@Thalley Thalley removed the Stale label Oct 4, 2024
@ndrs-pst ndrs-pst force-pushed the pr_bt_shell_refactor branch from 45075db to d3dffb7 Compare October 14, 2024 19:38
@ndrs-pst
Copy link
Contributor Author

@Thalley I just added another commit that introduces CONFIG_BT_SHELL_BACKEND for Bluetooth shell output when the shell context is unavailable (e.g., in callbacks).

While exploring ways to eliminate ctx_shell, could we initialize it during startup and hide it from other shell commands?
Since ctx_shell is currently used in multiple places like audio/shell, mesh/shell, and services/ias/shell.

@ndrs-pst ndrs-pst force-pushed the pr_bt_shell_refactor branch from 5243ac9 to 90f439f Compare November 15, 2024 13:52
@ndrs-pst
Copy link
Contributor Author

Changes made as requested—hope this looks good!

Thalley
Thalley previously approved these changes Nov 15, 2024
@Thalley
Copy link
Contributor

Thalley commented Nov 15, 2024

Excellent job and great that you updated it so fast :)

Copy link
Member

Choose a reason for hiding this comment

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

Is there anything really Bluetooth specific in this c-file? Wouldn't other modules benefit from having a "wall" API? Seems to me like this should just be a generic API instead of a Bluetooth specific one.

Copy link
Contributor Author

@ndrs-pst ndrs-pst Nov 16, 2024

Choose a reason for hiding this comment

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

It's true that this C-file isn't Bluetooth-specific, but since it's designed to address a Bluetooth-shell problem, keeping it focused on Bluetooth is fine for now. If similar needs arise elsewhere, it can be refactored into a generic API later.

🤞 Once this is merged, I'll open another PR for audio/shell, mesh/shell, and classic/shell too.

Copy link
Member

Choose a reason for hiding this comment

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

@jakub-uC @carlescufi any comments on this? How easily could this generic API be accepted as part of the shell subsystem?

Copy link
Member

Choose a reason for hiding this comment

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

@jakub-uC @carlescufi I'm still waiting for some response to the above question.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since the ctx_shell is only used in BT context, I think we can move forward with this PR. We can later port these to a non-BT place if there's any use for it

alwa-nordic
alwa-nordic previously approved these changes Nov 16, 2024
@Thalley
Copy link
Contributor

Thalley commented Dec 4, 2024

@ndrs-pst I think this PR actually solves #41796 - Should we add fixes https://github.com/zephyrproject-rtos/zephyr/issues/41796 in the PR description here?

Copy link
Member

@jhedberg jhedberg left a comment

Choose a reason for hiding this comment

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

Some style comments. I'm still a bit concerned with the total silence from the shell maintainers.

Comment on lines 1791 to 1793
Copy link
Member

Choose a reason for hiding this comment

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

Can't this be just one line?

Comment on lines 129 to 130
Copy link
Member

Choose a reason for hiding this comment

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

Merge to one line?

Comment on lines 398 to 400
Copy link
Member

Choose a reason for hiding this comment

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

Seems like at least the string literal should be mergeable to the first line

Comment on lines 420 to 422
Copy link
Member

Choose a reason for hiding this comment

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

Same here

Comment on lines 859 to 860
Copy link
Member

Choose a reason for hiding this comment

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

One line perhaps? I'll stop pointing more of this out, but in general, please pay attention to when you're shortening a line that was previously split if there's the possibility to merge the next line into it. I realize this is some extra work since you probably did an automated search-and-replace, however if we don't do it then the code will gradually start looking quite odd.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, the way that it's formatted looks like clang-format, but where the line length is set to 80 instead of 100. Chances are that the author is using a misconfigured auto-formatter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I can recall, I used the in-tree .clang-format with some manual adjustments to align it with the previous one.
For the next push, I'll change it according to the clang-format suggestion.

@ndrs-pst
Copy link
Contributor Author

ndrs-pst commented Dec 4, 2024

@ndrs-pst I think this PR actually solves #41796 - Should we add fixes https://github.com/zephyrproject-rtos/zephyr/issues/41796 in the PR description here?

Got it.

Introduced `bt_shell_private.c` and `bt_shell_private.h` to provide
common functions for the Bluetooth `shell_wall_print`.
These functions are equivalent to `shell_fprintf`, `shell_info`,
`shell_print`, `shell_warn`, `shell_error` and `shell_hexdump`
but without requiring the `sh` parameter.

The cost of the newly added `bt_shell_fprintf_info` ... `_error` functions
will be negligible when there are many individual calls that need to pass
both the `sh` and `color` parameters each time.

Signed-off-by: Pisit Sawangvonganan <[email protected]>
Limit the usage of `ctx_shell` to cases where printing requires it
and `sh` is not available.

Signed-off-by: Pisit Sawangvonganan <[email protected]>
This change aims to eliminate the dependency on `ctx_shell` in
the Bluetooth `host/shell/*`, making the code more maintainable.
Replaced `shell_*` functions that depended on `ctx_shell` with
the appropriate `bt_shell_*` functions.

The shell-less functions `bt_do_scan_filter_clear_name`, `bt_do_scan_off`,
and `bt_do_connect_le` were added so they can be called without `sh`.

Signed-off-by: Pisit Sawangvonganan <[email protected]>
@ndrs-pst ndrs-pst dismissed stale reviews from alwa-nordic and Thalley via 15ed4ec December 4, 2024 17:47
@ndrs-pst ndrs-pst force-pushed the pr_bt_shell_refactor branch from 90f439f to 15ed4ec Compare December 4, 2024 17:47
@Thalley Thalley requested a review from jhedberg December 5, 2024 13:45
Copy link
Member

@jhedberg jhedberg left a comment

Choose a reason for hiding this comment

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

Approving, but there's potential cleanup still to be done in follow-up PRs (see my inline comments). Please also engage actively with the shell maintainers to make this a generic API eventually. Thanks.

Comment on lines +827 to +838
bt_shell_print("LE conn param req: int (0x%04x, 0x%04x) lat %d"
" to %d", param->interval_min, param->interval_max,
param->latency, param->timeout);

return true;
}

static void le_param_updated(struct bt_conn *conn, uint16_t interval,
uint16_t latency, uint16_t timeout)
{
shell_print(ctx_shell, "LE conn param updated: int 0x%04x lat %d "
"to %d", interval, latency, timeout);
bt_shell_print("LE conn param updated: int 0x%04x lat %d "
"to %d", interval, latency, timeout);
Copy link
Member

Choose a reason for hiding this comment

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

I don't mean to keep bikeshedding here, and in most cases line splitting details are really not that critical, but splitting format strings is something that should be avoided whenever possible. The reason is that splitting them makes it hard/impossible to grep the code for the location where something was outputted to the console, since what's in the console will not match any single line in the source code. I see the original code had the split already, but I'm pretty sure the string can now be merged into a single line in both of these cases.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. If the author has setup clang-format in their IDE with only formatting changed lines using the .clang-format from Zephyr, these would have been formatted like you want.

Comment on lines -903 to +894
shell_print(ctx_shell, "Security failed: %s level %u "
"reason: %s (%d)",
addr, level, security_err_str(err), err);
bt_shell_print("Security failed: %s level %u "
"reason: %s (%d)",
addr, level, security_err_str(err), err);
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

Comment on lines +908 to +909
bt_shell_print("Remote LMP version %s (0x%02x) subversion 0x%04x "
"manufacturer 0x%04x", bt_hci_get_ver_str(remote_info->version),
Copy link
Member

Choose a reason for hiding this comment

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

And here.

Comment on lines +931 to +932
bt_shell_print("LE data len updated: TX (len: %d time: %d)"
" RX (len: %d time: %d)", info->tx_max_len,
Copy link
Member

Choose a reason for hiding this comment

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

And here.

@ndrs-pst
Copy link
Contributor Author

ndrs-pst commented Dec 5, 2024

Thank you for the approval and feedback!
I'll address the potential cleanup you mentioned in a follow-up PR.
Cheers 🎉

@kartben kartben merged commit aa1a38e into zephyrproject-rtos:main Dec 5, 2024
26 checks passed
@ndrs-pst ndrs-pst deleted the pr_bt_shell_refactor branch December 6, 2024 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Bluetooth Host Bluetooth Host (excluding BR/EDR) area: Bluetooth ISO Bluetooth LE Isochronous Channels area: Bluetooth

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shell_print crashes the board on bt bonds and bt connections

6 participants