mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Add option to make Nanostack use global event queue
							parent
							
								
									f12afde757
								
							
						
					
					
						commit
						8ad3e47a7e
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 * Copyright (c) 2016 ARM Limited, All Rights Reserved
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <mbed_assert.h>
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<void()> *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<void()>(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
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue