diff --git a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json index 091fa46ae6..86e1c91c8c 100644 --- a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json +++ b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/mbed_lib.json @@ -12,11 +12,14 @@ "critical-section-usable-from-interrupt": { "help": "Make critical section API usable from interrupt context. Else a mutex is used as locking primitive. Consult arm_hal_interrupt.c for possible side effects on interrupt latency.", "value": false - } - , + }, "event-loop-dispatch-from-application": { "help": "Application is responsible of message dispatch loop. Else launch a separate thread for event-loop.", "value": false + }, + "event-loop-use-mbed-events": { + "help": "Use Mbed OS global event queue for Nanostack event loop, rather than our own thread.", + "value": false } } } diff --git a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c index 5883fe623e..7b2332c21a 100644 --- a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c +++ b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c @@ -2,7 +2,7 @@ * Copyright (c) 2016 ARM Limited, All Rights Reserved */ -#include +#include "mbed_assert.h" #include "cmsis.h" #include "cmsis_os2.h" #include "mbed_rtos_storage.h" @@ -10,10 +10,12 @@ #include "eventOS_scheduler.h" +#include "ns_event_loop_mutex.h" #include "ns_event_loop.h" #define TRACE_GROUP "evlp" +#if !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_USE_MBED_EVENTS #if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_DISPATCH_FROM_APPLICATION @@ -50,40 +52,6 @@ static const osThreadAttr_t event_thread_attr = { static osThreadId_t event_thread_id; #endif -static mbed_rtos_storage_mutex_t event_mutex; -static const osMutexAttr_t event_mutex_attr = { - .name = "nanostack_event_mutex", - .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust, - .cb_mem = &event_mutex, - .cb_size = sizeof event_mutex, -}; -static osMutexId_t event_mutex_id; -static osThreadId_t event_mutex_owner_id = NULL; -static uint32_t owner_count = 0; - -void eventOS_scheduler_mutex_wait(void) -{ - osMutexAcquire(event_mutex_id, osWaitForever); - if (0 == owner_count) { - event_mutex_owner_id = osThreadGetId(); - } - owner_count++; -} - -void eventOS_scheduler_mutex_release(void) -{ - owner_count--; - if (0 == owner_count) { - event_mutex_owner_id = NULL; - } - osMutexRelease(event_mutex_id); -} - -uint8_t eventOS_scheduler_mutex_is_owner(void) -{ - return osThreadGetId() == event_mutex_owner_id ? 1 : 0; -} - void eventOS_scheduler_signal(void) { // XXX why does signal set lock if called with irqs disabled? @@ -124,8 +92,7 @@ static void event_loop_thread(void *arg) // if it is not ran in a separate thread. void ns_event_loop_init(void) { - event_mutex_id = osMutexNew(&event_mutex_attr); - MBED_ASSERT(event_mutex_id != NULL); + ns_event_loop_mutex_init(); // If a separate event loop thread is not used, the signaling // happens via event flags instead of thread flags. This allows one to @@ -148,3 +115,5 @@ void ns_event_loop_thread_start(void) { } #endif + +#endif // !MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_USE_MBED_EVENTS diff --git a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mbed.cpp b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mbed.cpp new file mode 100644 index 0000000000..6953cb660d --- /dev/null +++ b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mbed.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed_assert.h" +#include "platform/arm_hal_interrupt.h" +#include "cmsis.h" +#include "cmsis_os2.h" +#include "mbed_rtos_storage.h" +#include "ns_trace.h" + +#include "eventOS_scheduler.h" + +#include "mbed_error.h" +#include "mbed_shared_queues.h" +#include "events/Event.h" +#include "ns_event_loop_mutex.h" +#include "ns_event_loop.h" + +#define TRACE_GROUP "evlp" + +#if MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_USE_MBED_EVENTS + +using events::EventQueue; +using events::Event; + +static Event *event; +static volatile int event_pending; +static volatile bool started; + +void eventOS_scheduler_signal(void) +{ + platform_enter_critical(); + if (started && event_pending == 0) { + event_pending = event->post(); + MBED_ASSERT(event_pending != 0); + } + platform_exit_critical(); +} + +void eventOS_scheduler_idle(void) +{ + error("Shouldn't be called"); +} + +static void do_dispatch_with_mutex_held() +{ + platform_enter_critical(); + event_pending = 0; + platform_exit_critical(); + + /* Process only 1 Nanostack event at a time, to try to be nice to + * others on the global queue. + */ + eventOS_scheduler_mutex_wait(); + bool dispatched = eventOS_scheduler_dispatch_event(); + eventOS_scheduler_mutex_release(); + + /* Go round again if (potentially) more */ + if (dispatched) { + eventOS_scheduler_signal(); + } +} + +void ns_event_loop_init(void) +{ + ns_event_loop_mutex_init(); +} + +void ns_event_loop_thread_create(void) +{ + EventQueue *equeue = mbed::mbed_event_queue(); + MBED_ASSERT(equeue != NULL); + + event = new Event(equeue, do_dispatch_with_mutex_held); + MBED_ASSERT(event != NULL); +} + +void ns_event_loop_thread_start(void) +{ + started = true; + eventOS_scheduler_signal(); +} + +#endif // MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_USE_MBED_EVENTS diff --git a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mutex.c b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mutex.c new file mode 100644 index 0000000000..f4d91236fa --- /dev/null +++ b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mutex.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed_assert.h" +#include "cmsis.h" +#include "cmsis_os2.h" +#include "mbed_rtos_storage.h" +#include "ns_trace.h" + +#include "eventOS_scheduler.h" + +#include "ns_event_loop_mutex.h" + +#define TRACE_GROUP "evlm" + +static mbed_rtos_storage_mutex_t event_mutex; +static const osMutexAttr_t event_mutex_attr = { + .name = "nanostack_event_mutex", + .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust, + .cb_mem = &event_mutex, + .cb_size = sizeof event_mutex, +}; +static osMutexId_t event_mutex_id; +static osThreadId_t event_mutex_owner_id = NULL; +static uint32_t owner_count = 0; + +void eventOS_scheduler_mutex_wait(void) +{ + osMutexAcquire(event_mutex_id, osWaitForever); + if (0 == owner_count) { + event_mutex_owner_id = osThreadGetId(); + } + owner_count++; +} + +void eventOS_scheduler_mutex_release(void) +{ + owner_count--; + if (0 == owner_count) { + event_mutex_owner_id = NULL; + } + osMutexRelease(event_mutex_id); +} + +uint8_t eventOS_scheduler_mutex_is_owner(void) +{ + return osThreadGetId() == event_mutex_owner_id ? 1 : 0; +} + +void ns_event_loop_mutex_init(void) +{ + event_mutex_id = osMutexNew(&event_mutex_attr); + MBED_ASSERT(event_mutex_id != NULL); +} + diff --git a/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mutex.h b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mutex.h new file mode 100644 index 0000000000..ce3ac9beb6 --- /dev/null +++ b/features/nanostack/nanostack-hal-mbed-cmsis-rtos/ns_event_loop_mutex.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \internal Initialise the scheduler mutex + * + * Initialises the mutex used by the implementation of + * eventOS_scheduler_mutex_wait(). Must be called before scheduler is used. + */ +void ns_event_loop_mutex_init(void); + +#ifdef __cplusplus +} +#endif +