-
Notifications
You must be signed in to change notification settings - Fork 7.7k
BLE: BLECharacteristic::setValue()
cleanup and optimization
#11751
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
Conversation
👋 Hello Kolcha, we appreciate your contribution to this project! 📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project. Click to see more instructions ...
Review and merge process you can expect ...
|
05c13c0
to
3fa7ff5
Compare
There is no need to pass primitive types by reference, especially by non-const reference as it was in BLECharacteristic. Pass primitive types by value instead, as it should be, and used everywhere else except this one odd class. This allows allows to pass function result as `setValue()` argument without creating temporary variable.
It may be worth to test and verify it using other MCU SoCs, such as ESP32-S3 and ESP32-C3. Based on BLE specification, it shall be little-endian, therefore if you try sending an int value, you will see that the hex values are arranged in little-endian format. The "human readable" value 0xAABBCCDD will for instance be transmitted and received as 0xDDCCBBAA. The change takes into consideration the MCU endianless when compiling the code.
|
Test Results 76 files 76 suites 13m 9s ⏱️ Results for commit f801bdd. ♻️ This comment has been updated with latest results. |
Memory usage test (comparing PR against master branch)The table below shows the summary of memory usage change (decrease - increase) in bytes and percentage for each target.
Click to expand the detailed deltas report [usage change in BYTES]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using C++ reinterpret_cast<uint8_t*>
instead.
Another suggestion of change here (using reinterpret_cast<uint8_t*>):
|
ESP32 is little-endian architecture, so the code that filled temporary arrays created from integers basically did nothing. Pass primitives as 'buffers' to generic `setValue()` instead. Also use sizeof() instead of hardcoded sizes as the argument.
There is no technical need to pass non-const data there. Also it is a common practice to pass const data to the functions with write semantics, as they not supposed to modify the data. This allows to pass the data from read-only sources without removing the constness what is not always safe.
Pass String by const reference to many `setValue()` functions to avoid copying it. Even there are not so much data inside these strings, it just looks too odd to copy them every time. Also this change decreases binary size (~200 bytes in my case).
Co-authored-by: Copilot <[email protected]>
@Kolcha - Thanks for the contribution. I have tested it using u16 and u32 characteristics and it is working correctly with ESP32. ESP32-S3, ESP32-C3 and ESP32-C6. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Tested with ESP32, ESP32-S3, ESP32-C3 and ESP32-C6 using u16/u32 characteristics.
@lucasssvaz - PTAL. All seems fine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR optimizes the BLE library's setValue()
methods by improving parameter passing and eliminating unnecessary temporary variables. The changes focus on making the API more efficient and user-friendly without altering behavior.
- Pass primitive types by value instead of non-const reference to allow direct function return usage
- Replace manual byte array construction with direct memory access using
reinterpret_cast
- Change string and data parameters to const references/pointers to avoid unnecessary copies
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
libraries/BLE/src/BLEValue.h | Updates method signatures to use const references for String and const pointers for data |
libraries/BLE/src/BLEValue.cpp | Implements const reference parameters for addPart and setValue methods |
libraries/BLE/src/BLEDescriptor.h | Changes setValue signatures to use const parameters |
libraries/BLE/src/BLEDescriptor.cpp | Implements const parameters and uses reinterpret_cast for type conversion |
libraries/BLE/src/BLECharacteristic.h | Updates setValue overloads to pass primitives by value and use const references |
libraries/BLE/src/BLECharacteristic.cpp | Replaces manual byte manipulation with reinterpret_cast and direct memory access |
libraries/BLE/src/BLE2901.h | Changes setDescription to use const String reference |
libraries/BLE/src/BLE2901.cpp | Implements const String reference parameter |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes
Checklist
This entire section above can be deleted if all items are checked.
Description of Change
The change is just a code cleanup following common practices, no behavior change introduced.
BLECharacteristic::setValue()
by value instead of by non-const reference.There is no technical need to passing values by non-const reference there, non-const reference makes usage inconvenient (function return can't be passed directly as argument, temporary variable required), passing by value eliminates this inconvenience.
setValue()
implementations for primitive types.There is no technical need to create all those temporary variables, the address of the argument can be used directly. Such "integer to array" conversion is not required, because it basically does nothing, as ESP32 is little-endian architecture.
There is no technical need to pass non-const data there. This allows to pass the data from read-only sources without removing the constness what is not always safe.
Pass String by const reference to many
setValue()
functions to avoid copying it.Test Scenarios
I have tested my Pull Request on Arduino-esp32 core v3.3.0 with ESP32 Board with this scenario:
uint16_t
and 4 arefloat
Related links
nothing related found