irq_offload: API to run a function in IRQ context
Software interrupts or system calls aren't really appropriate for zephyr, but we have an ongoing need in our test code to run a function with arguments synchronously in interrupt context. This patch introduces irq_offload() which allows us to do this without separate initialization or having to manage fake IRQs in the interrupt controller. ARM assembly code contributed by Benjamin Walsh <benjamin.walsh@windriver.com> ARC is not yet implemented but will be in a subsequent patch. irq_test_common.h has been removed and all test cases updated to use the new API. Change-Id: I9af99ed31b62bc7eb340e32cf65e3d11354d1ec7 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
02a6baee12
commit
bba9510319
44 changed files with 313 additions and 350 deletions
|
@ -11,5 +11,5 @@ obj-y = atomic.o exc_exit.o irq_init.o \
|
|||
fatal.o sys_fatal_error_handler.o
|
||||
|
||||
obj-$(CONFIG_MICROKERNEL) += task_abort.o
|
||||
|
||||
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
||||
obj-$(CONFIG_CPU_CORTEX_M) += cortex_m/
|
||||
|
|
|
@ -133,6 +133,14 @@ endmenu
|
|||
menu "ARM Cortex-M3/M4 options"
|
||||
depends on CPU_CORTEX_M3_M4
|
||||
|
||||
config IRQ_OFFLOAD
|
||||
bool "Enable IRQ offload"
|
||||
default n
|
||||
help
|
||||
Enable irq_offload() API which allows functions to be synchronously
|
||||
run in interrupt context. Adds some overhead to context switching.
|
||||
Mainly useful for test cases.
|
||||
|
||||
config SW_ISR_TABLE
|
||||
bool
|
||||
prompt "Enable software interrupt handler table"
|
||||
|
|
44
arch/arm/core/irq_offload.c
Normal file
44
arch/arm/core/irq_offload.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Intel corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Software interrupts utility code - ARM implementation
|
||||
*/
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
static irq_offload_routine_t offload_routine;
|
||||
static void *offload_param;
|
||||
|
||||
/* Called by __svc */
|
||||
void _irq_do_offload(void)
|
||||
{
|
||||
offload_routine(offload_param);
|
||||
}
|
||||
|
||||
void irq_offload(irq_offload_routine_t routine, void *parameter)
|
||||
{
|
||||
int key;
|
||||
|
||||
key = irq_lock();
|
||||
offload_routine = routine;
|
||||
offload_param = parameter;
|
||||
|
||||
__asm__ volatile ("svc #1");
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
|
@ -152,6 +152,33 @@ SECTION_FUNC(TEXT, __svc)
|
|||
|
||||
_GDB_STUB_EXC_ENTRY
|
||||
|
||||
#if CONFIG_IRQ_OFFLOAD
|
||||
tst lr, #0x4 /* did we come from thread mode ? */
|
||||
ite eq /* if zero (equal), came from handler mode */
|
||||
mrseq r0, MSP /* handler mode, stack frame is on MSP */
|
||||
mrsne r0, PSP /* thread mode, stack frame is on PSP */
|
||||
|
||||
ldr r0, [r0, #24] /* grab address of PC from stack frame */
|
||||
/* SVC is a two-byte instruction, point to it and read encoding */
|
||||
ldr r0, [r0, #-2]
|
||||
|
||||
/*
|
||||
* grab service call number: if zero, it's a context switch; if not,
|
||||
* it's an irq offload
|
||||
*/
|
||||
ands r0, #0xff
|
||||
beq _context_switch
|
||||
|
||||
push {lr}
|
||||
blx _irq_do_offload /* call C routine which executes the offload */
|
||||
pop {lr}
|
||||
|
||||
/* exception return is done in _IntExit(), including _GDB_STUB_EXC_EXIT */
|
||||
b _IntExit
|
||||
|
||||
BRANCH_LABEL(_context_switch);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unlock interrupts:
|
||||
* - in a SVC call, so protected against context switches
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue