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
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
/**
|
||||
*
|
||||
* @brief Find out if running in an ISR context
|
||||
*
|
||||
*
|
||||
* The current executing vector is found in the IPSR register. We consider the
|
||||
* IRQs (exception 16 and up), and the PendSV and SYSTICK exceptions, to be
|
||||
* interrupts. Taking a fault within an exception is also considered in
|
||||
* IRQs (exception 16 and up), and the SVC, PendSV, and SYSTICK exceptions,
|
||||
* to be interrupts. Taking a fault within an exception is also considered in
|
||||
* interrupt context.
|
||||
*
|
||||
* @return 1 if in ISR, 0 if not.
|
||||
|
@ -48,8 +48,11 @@ static ALWAYS_INLINE int _IsInIsr(void)
|
|||
{
|
||||
uint32_t vector = _IpsrGet();
|
||||
|
||||
/* IRQs + PendSV + SYSTICK are interrupts */
|
||||
return (vector > 13) || (vector && _ScbIsNestedExc());
|
||||
/*
|
||||
* IRQs + PendSV (14) + SVC (11) + SYSTICK (15) are interrupts.
|
||||
* Vectors 12 and 13 are reserved, we'll never be in there
|
||||
*/
|
||||
return (vector > 10) || (vector && _ScbIsNestedExc());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -118,6 +118,14 @@ config PIC_DISABLE
|
|||
help
|
||||
This option disables all interrupts on the PIC
|
||||
|
||||
config IRQ_OFFLOAD
|
||||
bool "Enable IRQ offload"
|
||||
default n
|
||||
help
|
||||
Enable irq_offload() API which allows functions to be synchronously
|
||||
run in interrupt context. Uses one entry in the IDT. Mainly useful
|
||||
for test cases.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Processor Capabilities"
|
||||
|
|
|
@ -19,6 +19,7 @@ obj-y += gdt.o fatal.o cpuhalt.o \
|
|||
crt0.o driver_static_irq_stubs.o \
|
||||
atomic.o cache_s.o cache.o
|
||||
|
||||
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
||||
obj-$(CONFIG_FP_SHARING) += float.o
|
||||
obj-$(CONFIG_MICROKERNEL) += strtask.o
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ entering and exiting a C interrupt handler.
|
|||
GTEXT(_SpuriousIntNoErrCodeHandler)
|
||||
GTEXT(_SpuriousIntHandler)
|
||||
GTEXT(_DynIntStubsBegin)
|
||||
GTEXT(_irq_sw_handler)
|
||||
|
||||
/* externs */
|
||||
|
||||
|
@ -512,3 +513,11 @@ stub_num = 0
|
|||
1: jmp _DynIntStubCommon
|
||||
.endr
|
||||
#endif /* ALL_DYN_IRQ_STUBS */
|
||||
|
||||
#if CONFIG_IRQ_OFFLOAD
|
||||
SECTION_FUNC(TEXT, _irq_sw_handler)
|
||||
call _IntEnt
|
||||
call _irq_do_offload
|
||||
jmp _IntExit
|
||||
|
||||
#endif
|
||||
|
|
54
arch/x86/core/irq_offload.c
Normal file
54
arch/x86/core/irq_offload.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 IRQ offload - x86 implementation
|
||||
*/
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
#define SW_IRQ_VECTOR (CONFIG_IDT_NUM_VECTORS - 1)
|
||||
|
||||
extern void (*_irq_sw_handler)(void);
|
||||
NANO_CPU_INT_REGISTER(_irq_sw_handler, NANO_SOFT_IRQ, SW_IRQ_VECTOR / 16,
|
||||
SW_IRQ_VECTOR, 0);
|
||||
|
||||
static irq_offload_routine_t offload_routine;
|
||||
static void *offload_param;
|
||||
|
||||
/* Called by asm stub */
|
||||
void _irq_do_offload(void)
|
||||
{
|
||||
offload_routine(offload_param);
|
||||
}
|
||||
|
||||
void irq_offload(irq_offload_routine_t routine, void *parameter)
|
||||
{
|
||||
int key;
|
||||
|
||||
/*
|
||||
* Lock interrupts here to prevent any concurrency issues with
|
||||
* the two globals
|
||||
*/
|
||||
key = irq_lock();
|
||||
offload_routine = routine;
|
||||
offload_param = parameter;
|
||||
|
||||
__asm__ volatile("int %[vector]" : : [vector] "i" (SW_IRQ_VECTOR));
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
39
include/irq_offload.h
Normal file
39
include/irq_offload.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 IRQ Offload interface
|
||||
*/
|
||||
#ifndef _IRQ_OFFLOAD_H_
|
||||
#define _IRQ_OFFLOAD_H_
|
||||
|
||||
typedef void (*irq_offload_routine_t)(void *parameter);
|
||||
|
||||
/**
|
||||
* @brief Run a function in interrupt context
|
||||
*
|
||||
* This function synchronously runs the provided function in interrupt
|
||||
* context, passing in the supplied parameter. Useful for test code
|
||||
* which needs to show that kernel objects work correctly in interrupt
|
||||
* context.
|
||||
*
|
||||
* @param routine The function to run
|
||||
* @param parameter Argument to pass to the function when it is run as an
|
||||
* interrupt
|
||||
*/
|
||||
void irq_offload(irq_offload_routine_t routine, void *parameter);
|
||||
|
||||
#endif /* _SW_IRQ_H_ */
|
|
@ -1,139 +0,0 @@
|
|||
/* irq-test-common.h - IRQ utilities for tests */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Wind River Systems, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
Interrupt stuff, abstracted across CPU architectures.
|
||||
*/
|
||||
|
||||
#ifndef _IRQ_TEST_COMMON__H_
|
||||
#define _IRQ_TEST_COMMON__H_
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#define IRQ_PRIORITY 3
|
||||
#elif defined(CONFIG_ARM)
|
||||
#if defined(CONFIG_CPU_CORTEX_M)
|
||||
#define IRQ_PRIORITY _EXC_PRIO(3)
|
||||
#endif /* CONFIG_CPU_CORTEX_M */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NUM_SW_IRQS must be defined before this file is included, and it
|
||||
* currently only supports 1 or 2 as valid values.
|
||||
*/
|
||||
#if !defined(NUM_SW_IRQS)
|
||||
#error NUM_SW_IRQS must be defined before including irq-test-common.h
|
||||
#elif NUM_SW_IRQS < 1 || NUM_SW_IRQS > 2
|
||||
#error NUM_SW_IRQS only supports 1 or 2 IRQs
|
||||
#endif
|
||||
|
||||
typedef void (*vvfn)(void); /* void-void function pointer */
|
||||
typedef void (*vvpfn)(void *); /* void-void_pointer function pointer */
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
/*
|
||||
* Opcode for generating a software interrupt. The ISR associated with each
|
||||
* of these software interrupts will call either nano_isr_lifo_put() or
|
||||
* nano_isr_lifo_get(). The imm8 data in the opcode sequence will need to be
|
||||
* filled in after calling irq_connect().
|
||||
*/
|
||||
#include <drivers/loapic.h>
|
||||
static uint8_t sw_irq_vectors[NUM_SW_IRQS];
|
||||
|
||||
static inline void sw_isr_trigger_0(void)
|
||||
{
|
||||
loapic_int_vec_trigger(sw_irq_vectors[0]);
|
||||
}
|
||||
|
||||
#if NUM_SW_IRQS >= 2
|
||||
static inline void sw_isr_trigger_1(void)
|
||||
{
|
||||
loapic_int_vec_trigger(sw_irq_vectors[1]);
|
||||
}
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
|
||||
#elif defined(CONFIG_ARM)
|
||||
#if defined(CONFIG_CPU_CORTEX_M)
|
||||
#include <nanokernel.h>
|
||||
static inline void sw_isr_trigger_0(void)
|
||||
{
|
||||
_NvicSwInterruptTrigger(0);
|
||||
}
|
||||
|
||||
#if NUM_SW_IRQS >= 2
|
||||
static inline void sw_isr_trigger_1(void)
|
||||
{
|
||||
_NvicSwInterruptTrigger(1);
|
||||
}
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
#endif /* CONFIG_CPU_CORTEX_M */
|
||||
#endif
|
||||
|
||||
struct isrInitInfo {
|
||||
vvpfn isr[2];
|
||||
void *arg[2];
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Init interrupts
|
||||
*
|
||||
*/
|
||||
|
||||
static int initIRQ(struct isrInitInfo *i)
|
||||
{
|
||||
#if defined(CONFIG_X86)
|
||||
int vector; /* vector to which interrupt is connected */
|
||||
|
||||
if (i->isr[0]) {
|
||||
vector = irq_connect(NANO_SOFT_IRQ, IRQ_PRIORITY, i->isr[0],
|
||||
i->arg[0], 0);
|
||||
if (-1 == vector) {
|
||||
return -1;
|
||||
}
|
||||
sw_irq_vectors[0] = vector;
|
||||
}
|
||||
|
||||
#if NUM_SW_IRQS >= 2
|
||||
if (i->isr[1]) {
|
||||
vector = irq_connect(NANO_SOFT_IRQ, IRQ_PRIORITY, i->isr[1],
|
||||
i->arg[1], 0);
|
||||
if (-1 == vector) {
|
||||
return -1;
|
||||
}
|
||||
sw_irq_vectors[1] = vector;
|
||||
}
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
#elif defined(CONFIG_ARM)
|
||||
#if defined(CONFIG_CPU_CORTEX_M)
|
||||
if (i->isr[0]) {
|
||||
(void) irq_connect(0, IRQ_PRIORITY, i->isr[0], i->arg[0], 0);
|
||||
irq_enable(0);
|
||||
}
|
||||
if (i->isr[1]) {
|
||||
(void) irq_connect(1, IRQ_PRIORITY, i->isr[1], i->arg[1], 0);
|
||||
irq_enable(1);
|
||||
}
|
||||
#endif /* CONFIG_CPU_CORTEX_M */
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _IRQ_TEST_COMMON__H_ */
|
|
@ -1 +1 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -28,11 +28,8 @@ This modules tests the following event APIs:
|
|||
#include <zephyr.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <toolchain.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 1 software IRQs */
|
||||
#define NUM_SW_IRQS 1
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
typedef struct {
|
||||
|
@ -42,8 +39,6 @@ typedef struct {
|
|||
static int evidence = 0;
|
||||
|
||||
static ISR_INFO isrInfo;
|
||||
|
||||
static void (*_trigger_isrEventSignal)(void) = (vvfn)sw_isr_trigger_0;
|
||||
static int handlerRetVal = 0;
|
||||
|
||||
extern void testFiberInit(void);
|
||||
|
@ -65,6 +60,12 @@ void isr_event_signal_handler(void *data)
|
|||
isr_event_send(pInfo->event);
|
||||
}
|
||||
|
||||
static void _trigger_isrEventSignal(void)
|
||||
{
|
||||
irq_offload(isr_event_signal_handler, &isrInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Release the test fiber
|
||||
|
@ -86,12 +87,6 @@ void releaseTestFiber(void)
|
|||
|
||||
void microObjectsInit(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{isr_event_signal_handler, NULL},
|
||||
{&isrInfo, NULL},
|
||||
};
|
||||
|
||||
(void) initIRQ(&i);
|
||||
testFiberInit();
|
||||
|
||||
TC_PRINT("Microkernel objects initialized\n");
|
||||
|
|
|
@ -1 +1 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -29,12 +29,9 @@ then announces the result of the test.
|
|||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <irq_offload.h>
|
||||
#include <tc_util.h>
|
||||
|
||||
/* test uses 1 software IRQs */
|
||||
#define NUM_SW_IRQS 1
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
extern void testFiberInit(void);
|
||||
|
@ -82,7 +79,24 @@ ksem_t semList[] = {
|
|||
ENDLIST
|
||||
};
|
||||
|
||||
static vvfn _trigger_isrSemaSignal = (vvfn) sw_isr_trigger_0;
|
||||
/**
|
||||
*
|
||||
* @brief ISR that gives specified semaphore
|
||||
*
|
||||
* @param isrData pointer to semaphore to be given
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static void testIsrHandler(void *isrData)
|
||||
{
|
||||
isr_sem_give(*(ksem_t *)isrData);
|
||||
}
|
||||
|
||||
static void _trigger_isrSemaSignal(void)
|
||||
{
|
||||
irq_offload(testIsrHandler, &testIsrInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -152,19 +166,6 @@ void LowPriTaskEntry(void)
|
|||
task_sem_give(resultSems[LowPriTask()]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief ISR that gives specified semaphore
|
||||
*
|
||||
* @param isrData pointer to semaphore to be given
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static void testIsrHandler(void *isrData)
|
||||
{
|
||||
isr_sem_give(*(ksem_t *)isrData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -193,26 +194,6 @@ void releaseTestFiber(void)
|
|||
nano_task_sem_give(&fiberSem);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize interrupt-related code
|
||||
*
|
||||
* Binds an ISR to the interrupt vector used to give semaphores from interrupt
|
||||
* level.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static void testInterruptsInit(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{ testIsrHandler, NULL},
|
||||
{ &testIsrInfo, NULL},
|
||||
};
|
||||
|
||||
(void) initIRQ(&i);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Entry point for MonitorTask
|
||||
|
@ -228,7 +209,6 @@ void MonitorTaskEntry(void)
|
|||
ksem_t result;
|
||||
int tasksDone;
|
||||
|
||||
testInterruptsInit();
|
||||
testFiberInit();
|
||||
|
||||
PRINT_DATA("Starting semaphore tests\n");
|
||||
|
|
|
@ -1 +1 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
CONFIG_NUM_TASK_PRIORITIES=32
|
||||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_NUM_IRQS=1
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -4,4 +4,4 @@ CONFIG_NUM_TASK_PRIORITIES=32
|
|||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -27,11 +27,8 @@ This module tests the following task APIs:
|
|||
#include <tc_util.h>
|
||||
#include <zephyr.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 1 software IRQs */
|
||||
#define NUM_SW_IRQS 1
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
#define RT_PRIO 10 /* RegressionTask prio - must match prj.mdef */
|
||||
|
@ -47,8 +44,6 @@ typedef struct {
|
|||
int data;
|
||||
} ISR_INFO;
|
||||
|
||||
static vvfn _trigger_isrTaskCommand = (vvfn)sw_isr_trigger_0;
|
||||
|
||||
static ISR_INFO isrInfo;
|
||||
|
||||
static int tcRC = TC_PASS; /* test case return code */
|
||||
|
@ -101,7 +96,7 @@ void isr_task_command_handler(void *data)
|
|||
int isrAPIsTest(int taskId, int taskPrio)
|
||||
{
|
||||
isrInfo.cmd = CMD_TASKID;
|
||||
_trigger_isrTaskCommand();
|
||||
irq_offload(isr_task_command_handler, &isrInfo);
|
||||
if (isrInfo.data != taskId) {
|
||||
TC_ERROR("isr_task_id_get() returned %d, not %d\n",
|
||||
isrInfo.data, taskId);
|
||||
|
@ -109,7 +104,7 @@ int isrAPIsTest(int taskId, int taskPrio)
|
|||
}
|
||||
|
||||
isrInfo.cmd = CMD_PRIORITY;
|
||||
_trigger_isrTaskCommand();
|
||||
irq_offload(isr_task_command_handler, &isrInfo);
|
||||
if (isrInfo.data != taskPrio) {
|
||||
TC_ERROR("isr_task_priority_get() returned %d, not %d\n",
|
||||
isrInfo.data, taskPrio);
|
||||
|
@ -147,25 +142,6 @@ int taskMacrosTest(int taskId, int taskPrio)
|
|||
return TC_PASS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize objects used in this microkernel test suite
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
void microObjectsInit(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{ isr_task_command_handler, NULL },
|
||||
{ &isrInfo, NULL },
|
||||
};
|
||||
|
||||
(void) initIRQ(&i);
|
||||
|
||||
TC_PRINT("Microkernel objects initialized\n");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Helper task portion to test setting the priority
|
||||
|
@ -499,7 +475,6 @@ void RegressionTask(void)
|
|||
|
||||
PRINT_LINE;
|
||||
|
||||
microObjectsInit();
|
||||
task_start(HT_TASKID);
|
||||
|
||||
TC_PRINT("Testing isr_task_id_get() and isr_task_priority_get()\n");
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
CONFIG_NUM_TASK_PRIORITIES=32
|
||||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -4,4 +4,4 @@ CONFIG_NUM_TASK_PRIORITIES=32
|
|||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_ZERO_LATENCY_IRQS=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_NUM_DYNAMIC_EXC_NOERR_STUBS=1
|
||||
|
|
|
@ -29,11 +29,8 @@ This module tests the following CPU and thread related routines:
|
|||
#include <tc_util.h>
|
||||
#include <nano_private.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 1 software IRQs */
|
||||
#define NUM_SW_IRQS 1
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
/*
|
||||
|
@ -99,8 +96,6 @@ static int fiberEvidence = 0;
|
|||
|
||||
static ISR_INFO isrInfo;
|
||||
|
||||
static void (*_trigger_isrHandler)(void) = (vvfn)sw_isr_trigger_0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Handler to perform various actions from within an ISR context
|
||||
|
@ -129,6 +124,11 @@ void isr_handler(void *data)
|
|||
break;
|
||||
}
|
||||
}
|
||||
static void _trigger_isrHandler(void)
|
||||
{
|
||||
irq_offload(isr_handler, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Cortex-M3/M4 does not implement connecting non-IRQ exception handlers */
|
||||
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
|
||||
|
@ -173,12 +173,7 @@ int initNanoObjects(void)
|
|||
nanoCpuExcConnect(IV_DIVIDE_ERROR, exc_divide_error_handler);
|
||||
#endif
|
||||
|
||||
struct isrInitInfo i = {
|
||||
{isr_handler, NULL},
|
||||
{&isrInfo, NULL},
|
||||
};
|
||||
|
||||
return initIRQ(&i) < 0 ? TC_FAIL : TC_PASS;
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_ASSERT_LEVEL=2
|
||||
|
|
|
@ -5,4 +5,4 @@ CONFIG_TEST_RANDOM_GENERATOR=y
|
|||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_ASSERT_LEVEL=2
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -55,11 +55,8 @@ Scenario #4:
|
|||
#include <tc_util.h>
|
||||
#include <misc/__assert.h>
|
||||
#include <misc/util.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 2 software IRQs */
|
||||
#define NUM_SW_IRQS 2
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
#ifndef FIBER_STACKSIZE
|
||||
|
@ -120,9 +117,6 @@ int retCode = TC_PASS;
|
|||
|
||||
static ISR_FIFO_INFO isrFifoInfo = {&nanoFifoObj, NULL};
|
||||
|
||||
static void (*_trigger_nano_isr_fifo_put)(void) = (vvfn)sw_isr_trigger_0;
|
||||
static void (*_trigger_nano_isr_fifo_get)(void) = (vvfn)sw_isr_trigger_1;
|
||||
|
||||
void fiber1(void);
|
||||
void fiber2(void);
|
||||
void fiber3(void);
|
||||
|
@ -151,6 +145,12 @@ void isr_fifo_put(void *parameter)
|
|||
nano_isr_fifo_put(pInfo->fifo_ptr, pInfo->data);
|
||||
}
|
||||
|
||||
static void _trigger_nano_isr_fifo_put(void)
|
||||
{
|
||||
irq_offload(isr_fifo_put, &isrFifoInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get an item from a FIFO
|
||||
|
@ -170,6 +170,10 @@ void isr_fifo_get(void *parameter)
|
|||
pInfo->data = nano_isr_fifo_get(pInfo->fifo_ptr);
|
||||
}
|
||||
|
||||
static void _trigger_nano_isr_fifo_get(void)
|
||||
{
|
||||
irq_offload(isr_fifo_get, &isrFifoInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -557,13 +561,6 @@ void testTaskFifoGetW(void)
|
|||
|
||||
void initNanoObjects(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{isr_fifo_put, isr_fifo_get},
|
||||
{&isrFifoInfo, &isrFifoInfo},
|
||||
};
|
||||
|
||||
(void)initIRQ(&i);
|
||||
|
||||
nano_fifo_init(&nanoFifoObj);
|
||||
nano_fifo_init(&nanoFifoObj2);
|
||||
|
||||
|
|
|
@ -3,3 +3,6 @@ CONFIG_CONSOLE=y
|
|||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_IPI_CONSOLE_RECEIVER=y
|
||||
CONFIG_IPI_CONSOLE_SENDER=y
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_DEBUG=y
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_IPI_CONSOLE_RECEIVER=y
|
||||
CONFIG_IPI_CONSOLE_SENDER=y
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
||||
|
|
|
@ -22,13 +22,10 @@
|
|||
#include <device.h>
|
||||
#include <init.h>
|
||||
#include <misc/printk.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
#define NUM_SW_IRQS 2
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include "ipi_dummy.h"
|
||||
|
||||
static void (*trigger_dummy_isr)(void) = (vvfn)sw_isr_trigger_0;
|
||||
|
||||
/* Implemented as a software interrupt so that callbacks are executed
|
||||
* in the expected context */
|
||||
|
@ -78,7 +75,7 @@ static int ipi_dummy_send(struct device *d, int wait, uint32_t id,
|
|||
driver_data->regs.id = id;
|
||||
driver_data->regs.busy = 1;
|
||||
|
||||
trigger_dummy_isr();
|
||||
irq_offload(ipi_dummy_isr, d);
|
||||
|
||||
if (wait) {
|
||||
while(driver_data->regs.busy) {
|
||||
|
@ -100,10 +97,11 @@ static void ipi_dummy_register_callback(struct device *d, ipi_callback_t cb,
|
|||
static int ipi_dummy_set_enabled(struct device *d, int enable)
|
||||
{
|
||||
struct ipi_dummy_driver_data *driver_data = d->driver_data;
|
||||
|
||||
driver_data->regs.enabled = enable;
|
||||
if (enable) {
|
||||
/* In case there are pending messages */
|
||||
trigger_dummy_isr();
|
||||
irq_offload(ipi_dummy_isr, d);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -131,34 +129,11 @@ struct ipi_driver_api ipi_dummy_api = {
|
|||
|
||||
int ipi_dummy_init(struct device *d)
|
||||
{
|
||||
struct isrInitInfo iinfo;
|
||||
struct ipi_dummy_config_info *config_info;
|
||||
int irq, i;
|
||||
struct ipi_dummy_driver_data *driver_data;
|
||||
|
||||
config_info = (struct ipi_dummy_config_info *)d->config->config_info;
|
||||
driver_data = d->driver_data;
|
||||
d->driver_api = &ipi_dummy_api;
|
||||
|
||||
irq = config_info->sw_irq;
|
||||
if (irq >= NUM_SW_IRQS) {
|
||||
printk("ipi_dummy_init: invalid sw irq %d\n", irq);
|
||||
return DEV_INVALID_CONF;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_SW_IRQS; ++i) {
|
||||
if (i == irq) {
|
||||
iinfo.isr[i] = ipi_dummy_isr;
|
||||
iinfo.arg[i] = d;
|
||||
} else {
|
||||
iinfo.isr[i] = NULL;
|
||||
iinfo.arg[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (initIRQ(&iinfo)) {
|
||||
printk("ipi_dummy_init: couldn't install sw irq handler\n");
|
||||
return DEV_FAIL;
|
||||
}
|
||||
|
||||
return DEV_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,6 @@ struct ipi_dummy_driver_data {
|
|||
volatile struct ipi_dummy_regs regs;
|
||||
};
|
||||
|
||||
struct ipi_dummy_config_info {
|
||||
int sw_irq;
|
||||
};
|
||||
|
||||
int ipi_dummy_init(struct device *d);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,12 +39,8 @@
|
|||
#define INIT_PRIO_IPI_SEND 50
|
||||
|
||||
/* Set up the dummy IPI driver */
|
||||
struct ipi_dummy_config_info ipi_dummy0_config_info = {
|
||||
.sw_irq = 0
|
||||
};
|
||||
struct ipi_dummy_driver_data ipi_dummy0_driver_data;
|
||||
DECLARE_DEVICE_INIT_CONFIG(ipi_dummy0, "ipi_dummy0", ipi_dummy_init,
|
||||
&ipi_dummy0_config_info);
|
||||
DECLARE_DEVICE_INIT_CONFIG(ipi_dummy0, "ipi_dummy0", ipi_dummy_init, NULL);
|
||||
SYS_DEFINE_DEVICE(ipi_dummy0, &ipi_dummy0_driver_data, SECONDARY,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_ASSERT_LEVEL=2
|
||||
|
|
|
@ -5,4 +5,4 @@ CONFIG_TEST_RANDOM_GENERATOR=y
|
|||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_ASSERT_LEVEL=2
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -46,11 +46,11 @@ These scenarios will be tested using a combinations of tasks, fibers and ISRs.
|
|||
#include <tc_util.h>
|
||||
#include <misc/util.h>
|
||||
#include <misc/__assert.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 2 software IRQs */
|
||||
#define NUM_SW_IRQS 2
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
#ifndef FIBER_STACKSIZE
|
||||
|
@ -87,9 +87,6 @@ static volatile int fiberDetectedFailure = 0; /* non-zero on failure */
|
|||
|
||||
static char __stack fiberStack[FIBER_STACKSIZE];
|
||||
|
||||
static void (*_trigger_nano_isr_lifo_put)(void) = (vvfn)sw_isr_trigger_0;
|
||||
static void (*_trigger_nano_isr_lifo_get)(void) = (vvfn)sw_isr_trigger_1;
|
||||
|
||||
static struct nano_lifo multi_waiters;
|
||||
static struct nano_sem reply_multi_waiters;
|
||||
|
||||
|
@ -112,6 +109,12 @@ void isr_lifo_put(void *data)
|
|||
nano_isr_lifo_put(pInfo->lifo_ptr, pInfo->data);
|
||||
}
|
||||
|
||||
static void _trigger_nano_isr_lifo_put(void)
|
||||
{
|
||||
irq_offload(isr_lifo_put, &isrLifoInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get an item from a LIFO
|
||||
|
@ -131,6 +134,12 @@ void isr_lifo_get(void *data)
|
|||
pInfo->data = nano_isr_lifo_get(pInfo->lifo_ptr);
|
||||
}
|
||||
|
||||
static void _trigger_nano_isr_lifo_get(void)
|
||||
{
|
||||
irq_offload(isr_lifo_get, &isrLifoInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Fiber portion of test that waits on a LIFO
|
||||
|
@ -445,13 +454,6 @@ int taskLifoNonWaitTest(void)
|
|||
|
||||
void initNanoObjects(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{isr_lifo_put, isr_lifo_get},
|
||||
{&isrLifoInfo, &isrLifoInfo},
|
||||
};
|
||||
|
||||
(void)initIRQ(&i);
|
||||
|
||||
nano_lifo_init(&test_lifo); /* Initialize the LIFO */
|
||||
nano_sem_init(&taskWaitSem); /* Initialize the task waiting semaphore */
|
||||
nano_sem_init(&fiberWaitSem); /* Initialize the fiber waiting semaphore */
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NANO_TIMEOUTS=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -43,11 +43,8 @@ Scenario #4:
|
|||
#include <tc_util.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <misc/util.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 2 software IRQs */
|
||||
#define NUM_SW_IRQS 2
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
#ifndef FIBER_STACKSIZE
|
||||
|
@ -77,9 +74,6 @@ static void *timerData[1];
|
|||
|
||||
static char __stack fiberStack[FIBER_STACKSIZE];
|
||||
|
||||
static void (*_trigger_nano_isr_sem_give)(void) = (vvfn)sw_isr_trigger_0;
|
||||
static void (*_trigger_nano_isr_sem_take)(void) = (vvfn)sw_isr_trigger_1;
|
||||
|
||||
static struct nano_sem multi_waiters;
|
||||
static struct nano_sem reply_multi_waiters;
|
||||
|
||||
|
@ -102,6 +96,11 @@ void isr_sem_take(void *data)
|
|||
pInfo->data = nano_isr_sem_take(pInfo->sem);
|
||||
}
|
||||
|
||||
static void _trigger_nano_isr_sem_take(void)
|
||||
{
|
||||
irq_offload(isr_sem_take, &isrSemInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Give a semaphore
|
||||
|
@ -122,6 +121,11 @@ void isr_sem_give(void *data)
|
|||
pInfo->data = 1; /* Indicate semaphore has been given */
|
||||
}
|
||||
|
||||
static void _trigger_nano_isr_sem_give(void)
|
||||
{
|
||||
irq_offload(isr_sem_give, &isrSemInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Give and take the semaphore in a fiber without blocking
|
||||
|
@ -253,13 +257,6 @@ static void fiberEntry(int arg1, int arg2)
|
|||
|
||||
void initNanoObjects(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{isr_sem_give, isr_sem_take},
|
||||
{&isrSemInfo, &isrSemInfo},
|
||||
};
|
||||
|
||||
(void)initIRQ(&i);
|
||||
|
||||
nano_sem_init(&testSem);
|
||||
nano_sem_init(&multi_waiters);
|
||||
nano_sem_init(&reply_multi_waiters);
|
||||
|
|
|
@ -1 +1 @@
|
|||
CONFIG_NUM_IRQS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
# This option is NOT to be used in production code.
|
||||
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NUM_DYNAMIC_STUBS=2
|
||||
CONFIG_IRQ_OFFLOAD=y
|
||||
|
|
|
@ -48,11 +48,8 @@ these are run in ISR context.
|
|||
|
||||
#include <tc_util.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
/* test uses 2 software IRQs */
|
||||
#define NUM_SW_IRQS 2
|
||||
|
||||
#include <irq_test_common.h>
|
||||
#include <util_test_common.h>
|
||||
|
||||
#define STACKSIZE 2048
|
||||
|
@ -96,9 +93,6 @@ int retCode = TC_PASS;
|
|||
|
||||
static ISR_STACK_INFO isrStackInfo = {&nanoStackObj, 0};
|
||||
|
||||
static void (*_trigger_nano_isr_stack_push)(void) = (vvfn)sw_isr_trigger_0;
|
||||
static void (*_trigger_nano_isr_stack_pop)(void) = (vvfn)sw_isr_trigger_1;
|
||||
|
||||
void initData(void);
|
||||
void fiber1(void);
|
||||
void fiber2(void);
|
||||
|
@ -149,6 +143,11 @@ void isr_stack_push(void *parameter)
|
|||
|
||||
} /* isr_stack_push */
|
||||
|
||||
static void _trigger_nano_isr_stack_push(void)
|
||||
{
|
||||
irq_offload(isr_stack_push, &isrStackInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get an item from a STACK
|
||||
|
@ -173,6 +172,10 @@ void isr_stack_pop(void *parameter)
|
|||
|
||||
} /* isr_stack_pop */
|
||||
|
||||
static void _trigger_nano_isr_stack_pop(void)
|
||||
{
|
||||
irq_offload(isr_stack_pop, &isrStackInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -468,13 +471,6 @@ void fiber3(void)
|
|||
|
||||
void initNanoObjects(void)
|
||||
{
|
||||
struct isrInitInfo i = {
|
||||
{isr_stack_push, isr_stack_pop},
|
||||
{&isrStackInfo, &isrStackInfo},
|
||||
};
|
||||
|
||||
(void)initIRQ(&i);
|
||||
|
||||
nano_stack_init(&nanoStackObj, stack1);
|
||||
nano_stack_init(&nanoStackObj2, stack2);
|
||||
nano_sem_init(&nanoSemObj);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue