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

cpu/esp32: add Bluetooth LE and NimBLE host support #18439

Merged
merged 16 commits into from
Aug 24, 2022

Conversation

gschorcht
Copy link
Contributor

@gschorcht gschorcht commented Aug 11, 2022

Contribution description

This PR provides Bluetooth LE and NimBLE host support for ESP32. In detail it includes the following changes:

  • patches for the compilation of ESP-IDF Bluetooth LE controller code
  • changes and extensions of the FreeRTOS adaptation layer required by the ESP-IDF Bluetooth LE controller code
  • additional module esp_idf_ble with the ESP-IDF Bluetooth LE controller code
  • new linker script used when Bluetooth LE support is enabled due to different memory layout
  • additional pseudomodule esp_ble to enable Bluetooth LE support
  • additional module nimble_transport_hci_h4 in package nimble
  • conditional compilation of nRF5x code in package nimble
  • additional pseudomodule esp_ble_nimble to enable NimBLE host support
  • test application for Bluetooth and WiFi coexistence

The following examples/tests already work:

BLE support already works for ESP32-C3 as well.

Testing procedure

Use any ESP32 board to test examples/nimble_scanner:

BOARD=esp32-wroom-32 make -j8 -C examples/nimble_scanner flash term

Issues/PRs references

@github-actions github-actions bot added Area: BLE Area: Bluetooth Low Energy support Area: cpu Area: CPU/MCU ports Area: doc Area: Documentation Area: Kconfig Area: Kconfig integration Area: pkg Area: External package ports Area: sys Area: System Platform: ESP Platform: This PR/issue effects ESP-based platforms labels Aug 11, 2022
@gschorcht gschorcht added State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Aug 11, 2022
@gschorcht gschorcht force-pushed the cpu/esp32/enable_ble_nimble branch from fc9dbfd to 2cae517 Compare August 11, 2022 10:25
@gschorcht
Copy link
Contributor Author

@benpicco Now that we are using ESP-IDF directly, even Bluetooth LE support seems to be possible 😉

@benpicco benpicco requested a review from haukepetersen August 11, 2022 10:29
@gschorcht gschorcht force-pushed the cpu/esp32/enable_ble_nimble branch from 2cae517 to e648c15 Compare August 11, 2022 10:47
@gschorcht
Copy link
Contributor Author

gschorcht commented Aug 11, 2022

Since the label State: WIP is set and there is no review active, I feel free to squash an force push a number of fixes.

@gschorcht gschorcht force-pushed the cpu/esp32/enable_ble_nimble branch from e648c15 to cf271dd Compare August 11, 2022 16:13
@benpicco benpicco requested a review from maribu August 11, 2022 16:40
Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

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

Code looks good to me. I'm looking forward to test this :)

cpu/esp32/Kconfig Show resolved Hide resolved
cpu/esp32/esp-ble-nimble/doc.txt Outdated Show resolved Hide resolved
cpu/esp32/esp-ble-nimble/esp_ble_nimble.c Outdated Show resolved Hide resolved
cpu/esp32/esp-ble-nimble/esp_ble_nimble.c Outdated Show resolved Hide resolved
cpu/esp32/include/esp_ble_nimble/syscfg/syscfg.h Outdated Show resolved Hide resolved
@gschorcht gschorcht added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Aug 12, 2022
@gschorcht gschorcht force-pushed the cpu/esp32/enable_ble_nimble branch 3 times, most recently from 03d67d3 to 003cd45 Compare August 12, 2022 06:05
@github-actions github-actions bot added the Area: build system Area: Build system label Aug 12, 2022
@gschorcht
Copy link
Contributor Author

gschorcht commented Aug 12, 2022

I think with ef7fbf7 I found a more elegant way to avoid compiling files that depend on nRF5x MCUs than patching the NimBLE sources with 5244724.

@gschorcht
Copy link
Contributor Author

gschorcht commented Aug 12, 2022

The coexistence of BLE and WiFi in station mode seems to work with this PR. I have created an application that combines examples/gnrc_networking and examples/nimble_scanner. It is possible to execute command scan while connecting to the WiFi AP and it is possible to ping the ESP32 node with ping6 -i0.1 -s 1280 and execute the scan command simultaneously.

Should I add this application for testing to this PR?

With the current implementation, coexistence is controlled by the hardware. However, for heavy traffic environments, it is recommended to control the coexistence by the software according the the documentation of Kconfig option ESP32_WIFI_SW_COEXIST_ENABLE

            If enabled, WiFi & Bluetooth coexistence is controlled by software rather than hardware.
            Recommended for heavy traffic scenarios. Both coexistence configuration options are
            automatically managed, no user intervention is required.
            If only Bluetooth is used, it is recommended to disable this option to reduce binary file
            size.

I haven't tried it yet.

The coexistence of BLE and WiFi in SoftAP mode isn't supported. Therefore, the coexistence of BLE and ESP-NOW is also not supported.

@gschorcht
Copy link
Contributor Author

However, for heavy traffic environments, it is recommended to control the coexistence by the software according the the documentation of Kconfig option ESP32_WIFI_SW_COEXIST_ENABLE

Seems to work too, and it makes a significant difference. When I ping the ESP32 node with ping6 -i0.01 -s 1280, without ESP32_WIFI_SW_COEXIST_ENABLE the ping is slowed down much more during the execution of the scan command than with ESP32_WIFI_SW_COEXIST_ENABLE. With this option the scan command has almost no impact on the RTT.

@github-actions github-actions bot added the Platform: ARM Platform: This PR/issue effects ARM-based platforms label Aug 12, 2022
@gschorcht
Copy link
Contributor Author

Hm, nimble_*_ext modules can be enabled without having the feature of extended advertising. That is, there is no feature ble_nimble_ext required for nimble_*_ext modules.

ESP32 and ESP32-S2 are only Bluetooth LE 4.2 devices that work with the NimBLE host stack but have no extended advertising.

Should we introduce feature ble_nimble_ext and the according dependencies?

@github-actions github-actions bot added the Platform: ARM Platform: This PR/issue effects ARM-based platforms label Aug 23, 2022
@benpicco
Copy link
Contributor

Please squash again

@gschorcht gschorcht force-pushed the cpu/esp32/enable_ble_nimble branch from d67dbbc to 8ba0d3f Compare August 23, 2022 16:10
If the package is used for a controller that supports the HCI UART H4 transport layer protocol, the functions implemented in `nimble/transport/common/hci_h4` are very useful to deal with H4 formatted packages. If required, they can be enabled by module `nimble_transport_hci_h4`.
The package uses the nRFx SDK package `nrfx`. In addition, the `mynewt-nimble` repository contains some files (`porting/nimble/src/hal_timer.c` and `porting/npl/riot/src/nrf5x_isr.c`) that are compilable only for nRF MCUs. To allow the compilation for other platforms, the use of the `nrfx` package and the compilation of these files are now dependent on the use of any nRF5x MCU.
When using Bluetooth LE, the former UART interrupt number 5 is occupied by the ESP32 Bluetooth Controller. Therefore, another interrupt number has to be used for UART.
To reduce the required RAM in default configuration, the BLE interface is used as netdev_default instead of ESP-NOW. Further network interfaces can be enabled with the modules `esp_now`, `esp_wifi` or `esp_eth`.
`nimble_rpl` was not compilable without `nimble_controller` because the header includes were inside the conditional for `MODULE_NIMBLE_CONTROLLER`.
The definition of gettimeofday in pkg/ccn-lite leads to multiple definitions on platforms where gettimeofday is compiled in in newlib. Therefore, the gettimeofday function in pkg/ccn-lite is declared as weak symbol.
When FreeRTOS semaphores, as required by ESP-IDF, are used together with `gnrc_netif`, RIOT may crash if `STATUS_RECEIVE_BLOCKED` is used as a blocking mechanism in the FreeRTOS adaptation layer. The reason for this is that `gnrc_netif` uses thread flags since PR RIOT-OS#16748. If the `gnrc_netif` thread is blocked because of a FreeRTOS semaphore, and is thus in `STATUS_RECEIVE_BLOCKED` state, the `_msg_send` function will cause a crash because it then assumes that `target->wait_data` contains a pointer to a message of type `msg_t`, but by using thread flags it contains the flag mask. This situation can happen if the ESP hardware is used while another thread is sending something timer controlled to the `gnrc_netif` thread.

To solve this problem `STATUS_MUTEX_LOCKED` is used instead of `STATUS_RECEIVE_BLOCKED` and `STATUS_SEND_BLOCKED`
@gschorcht gschorcht force-pushed the cpu/esp32/enable_ble_nimble branch from 8ba0d3f to 4b0d920 Compare August 24, 2022 07:05
Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

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

Code looks good, I don't know enough about the BLE examples to judge, but I trust your testing.

Will this also be easy to enable for ESP32-S2, ESP32-S3 and ESP32-C3?

@benpicco
Copy link
Contributor

Does this still depend on #18454?

@maribu
Copy link
Member

maribu commented Aug 24, 2022

Does this still depend on #18454?

No, it is using the mutex blocked status instead. There are no assumptions towards the blocked for mutex status as of now.

I was planning on reusing that for tracing the owner of a mutex, but one really wants that to be readily available in the mutex, rather than having to search through all running threads.

I guess this shows that we should add the dedicated thread states and move to them when merged. But for now, this should work :)

@benpicco benpicco merged commit 2abc850 into RIOT-OS:master Aug 24, 2022
@gschorcht
Copy link
Contributor Author

Code looks good, I don't know enough about the BLE examples to judge, but I trust your testing.

Will this also be easy to enable for ESP32-S2, ESP32-S3 and ESP32-C3?

I already have it ready for ESP32-C3, I was just waiting for this PR to be merged 😉

@gschorcht
Copy link
Contributor Author

Thanks for reviewing and merging.

@gschorcht gschorcht deleted the cpu/esp32/enable_ble_nimble branch August 24, 2022 16:04
@gschorcht
Copy link
Contributor Author

I already have it ready for ESP32-C3, I was just waiting for this PR to be merged

See PR #18510

@benpicco benpicco added this to the Release 2022.10 milestone Aug 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: BLE Area: Bluetooth Low Energy support Area: build system Area: Build system Area: cpu Area: CPU/MCU ports Area: doc Area: Documentation Area: Kconfig Area: Kconfig integration Area: pkg Area: External package ports Area: sys Area: System Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Platform: ESP Platform: This PR/issue effects ESP-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants