On Fri, Oct 16, 2026 at 2:44 PM chao an <[email protected]> wrote:

> Hi raiden00pl,
>
> Regarding your point about the NimBLE port using the POSIX API — yes, it
> uses POSIX, but there are real issues with the current implementation that
> go beyond just kernel/protected mode support.
> 1. ble_npl_hw_enter_critical is not a real critical section
>
> Look at the NuttX port's implementation:
>
> https://github.com/apache/mynewt-nimble/blob/master/porting/npl/nuttx/src/os_atomic.c
>
> static pthread_mutex_t s_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
>
> uint32_t ble_npl_hw_enter_critical(void)
> {
>     pthread_mutex_lock(&s_mutex);
>     return 0;
> }
>
> This is a mutex, not a critical section. It does not disable interrupts or
> preemption — an ISR can still fire and corrupt data that the "critical
> section" was supposed to protect. On top of that, using a mutex opens the
> door to ABBA deadlocks when combined with any other lock held inside the
> critical region:
>
>    - Thread A: enter_critical → lock(s_mutex) → try lock(mutex M) ← blocked
>    by B
>    - Thread B: lock(M) → enter_critical → lock(s_mutex) ← blocked by A
>
> Compare this with the FreeRTOS port, which correctly uses
> vPortEnterCritical() / vPortExitCritical() (i.e., actually disabling
> scheduling/preemption). The current NuttX port simply does not meet the
> semantic contract that the NimBLE stack expects from
> ble_npl_hw_enter_critical.
> 2. Time subsystem uses clock_gettime instead of kernel tick APIs
>
>
> https://github.com/apache/mynewt-nimble/blob/master/porting/npl/nuttx/src/os_time.c
>
> ble_npl_time_get() is backed by clock_gettime(CLOCK_MONOTONIC, ...), which
> involves a syscall and floating-point arithmetic on every call. In a BLE
> stack where timestamps and timing are on the hot path, this adds measurable
> overhead compared to accessing the kernel tick counter directly.
> 3. Others are already using the kernel approach — and for good reason
>
> A concrete example: Xiaomi's Bluetooth stack (zblue) for openvela/NuttX
> uses kernel APIs directly, bypassing POSIX for the performance-critical
> paths:
> https://github.com/sprhawk/zblue-port-openvela/tree/yaotepai/port/kernel
>
> This isn't an academic exercise — it's a production choice. They recognized
> that a BLE stack needs tight integration with the OS timer subsystem,
> direct access to critical section primitives, and efficient event delivery,
> none of which POSIX provides well in this context.
> My question
>
> If other organizations are already using a more performant, architecturally
> correct kernel-level integration for their BLE stacks on NuttX, why should
> we be told that we must use the slower, less correct POSIX path? NuttX's
> POSIX compliance is valuable, but it shouldn't come at the cost of shipping
> a BLE stack with a broken critical section primitive. There should be room
> for both approaches, and the decision should be driven by technical merit,
> not by treating POSIX as the only acceptable answer.
>
>
I don't object to moving the key bluetooth stack to kernel space like how
the current bluetooth stack is done,
what I object to is that the current state of
https://github.com/apache/nuttx/pull/20686 is far to move entirely
into kernel space.
If I low my quality bar, I have requested my teammate to upstream our
implementation:
https://github.com/sprhawk/zblue-port-openvela/tree/yaotepai/port/kernel
since much work needs to be done before it can achieve the quality upstream.
BTW, many zephyr class BT features are developed by my team and upstream to
Zeprhy community.
If considering the quality, our version is much better since:

   1. Product on smart speaker last year
   2. Pass Bluetooth SIG BT/BLE 6.2 certification at 2026.06
   3. Product on wear device by end of this year

Reply via email to