Add OsEventObserver

Add the OsEventObserver mechanism. A client interested in receiving
notifications on certain OS events can register to receive notifications
with osRegisterForOsEvents. This is useful for clients like the secure
memory allocator, which observes thread switching events in order to swap
in and out different memory allocator objects.
pull/1753/head
Jaeden Amero 2016-05-24 09:36:02 +01:00 committed by Milosch Meriac
parent 55f464da27
commit 4cdc4a7b45
4 changed files with 132 additions and 0 deletions

View File

@ -65,6 +65,7 @@
#include "rt_MemBox.h"
#include "rt_Memory.h"
#include "rt_HAL_CM.h"
#include "rt_OsEventObserver.h"
#include "cmsis_os.h"
@ -504,6 +505,10 @@ osStatus svcKernelStart (void) {
if (os_running) { return osOK; }
if (osEventObs && osEventObs->pre_start) {
osEventObs->pre_start();
}
rt_tsk_prio(0U, os_tsk.run->prio_base); // Restore priority
if (os_tsk.run->task_id == 0xFFU) { // Idle Thread
__set_PSP(os_tsk.run->tsk_stack + (8U*4U)); // Setup PSP
@ -683,6 +688,12 @@ osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument) {
*((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit;
if (osEventObs && osEventObs->thread_create) {
ptcb->context = osEventObs->thread_create(ptcb->task_id, context);
} else {
ptcb->context = context;
}
return ptcb;
}
@ -712,6 +723,10 @@ osStatus svcThreadTerminate (osThreadId thread_id) {
stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack
#endif
if (osEventObs && osEventObs->thread_destroy) {
osEventObs->thread_destroy(ptcb->context);
}
res = rt_tsk_delete(ptcb->task_id); // Delete task
if (res == OS_R_NOK) {

View File

@ -0,0 +1,55 @@
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
* Name: rt_OsEventObserver.c
* Purpose: OS Event Callbacks for CMSIS RTOS
* Rev.: VX.XX
*----------------------------------------------------------------------------
*
* Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*---------------------------------------------------------------------------*/
#include "rt_OsEventObserver.h"
/*
* _____ _____ ____ __ _____
* | ___|_ _\ \/ / \/ | ____|
* | |_ | | \ /| |\/| | _|
* | _| | | / \| | | | |___
* |_| |___/_/\_\_| |_|_____|
*
* FIXME:
* The osEventObs variable must be in protected memory. If not every box
* and box 0 can modify osEventObs to point to any handler to run code
* privileged. This issue is tracked at
* <https://github.com/ARMmbed/uvisor/issues/235>.
*/
const OsEventObserver *osEventObs;
void osRegisterForOsEvents(const OsEventObserver *observer)
{
osEventObs = observer;
}

View File

@ -0,0 +1,58 @@
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
* Name: os_events.h
* Purpose: OS Event Callbacks for CMSIS RTOS
* Rev.: VX.XX
*----------------------------------------------------------------------------
*
* Copyright (c) 1999-2009 KEIL, 2009-2016 ARM Germany GmbH
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*---------------------------------------------------------------------------*/
#ifndef _RT_OS_EVENT_OBSERVER_H
#define _RT_OS_EVENT_OBSERVER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t version;
void (*pre_start)(void);
void *(*thread_create)(int thread_id, void *context);
void (*thread_destroy)(void *context);
void (*thread_switch)(void *context);
} OsEventObserver;
extern const OsEventObserver *osEventObs;
void osRegisterForOsEvents(const OsEventObserver *observer);
#ifdef __cplusplus
};
#endif
#endif

View File

@ -40,6 +40,7 @@
#include "rt_MemBox.h"
#include "rt_Robin.h"
#include "rt_HAL_CM.h"
#include "rt_OsEventObserver.h"
/*----------------------------------------------------------------------------
* Global Variables
@ -101,6 +102,9 @@ void rt_switch_req (P_TCB p_new) {
/* Switch to next task (identified by "p_new"). */
os_tsk.new_tsk = p_new;
p_new->state = RUNNING;
if (osEventObs && osEventObs->thread_switch) {
osEventObs->thread_switch(p_new->context);
}
DBG_TASK_SWITCH(p_new->task_id);
}