forked from Imagelibrary/rtems
2009-09-08 Sebastian Huber <sebastian.huber@embedded-brains.de>
* include/irq-config.h, include/irq-generic.h, include/irq-info.h, src/irq-generic.c, src/irq-info.c, src/irq-legacy.c, src/irq-shell.c: Format, cleanup and documentation. * src/irq-server.c: New file. * include/bootcard.h, include/stackalloc.h, src/stackalloc.c, bsplibc.c: Update for heap API changes. Documentation.
This commit is contained in:
@@ -1,3 +1,12 @@
|
|||||||
|
2009-09-08 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* include/irq-config.h, include/irq-generic.h, include/irq-info.h,
|
||||||
|
src/irq-generic.c, src/irq-info.c, src/irq-legacy.c, src/irq-shell.c:
|
||||||
|
Format, cleanup and documentation.
|
||||||
|
* src/irq-server.c: New file.
|
||||||
|
* include/bootcard.h, include/stackalloc.h, src/stackalloc.c,
|
||||||
|
bsplibc.c: Update for heap API changes. Documentation.
|
||||||
|
|
||||||
2009-08-28 Joel Sherrill <joel.sherrill@OARcorp.com>
|
2009-08-28 Joel Sherrill <joel.sherrill@OARcorp.com>
|
||||||
|
|
||||||
* bootcard.c, bsplibc.c, clockdrv_shell.h, console-polled.c: Fix
|
* bootcard.c, bsplibc.c, clockdrv_shell.h, console-polled.c: Fix
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
#include <bsp/bootcard.h>
|
#include <bsp/bootcard.h>
|
||||||
|
|
||||||
void bsp_libc_init(
|
void bsp_libc_init(
|
||||||
void *heap_start,
|
void *heap_begin,
|
||||||
size_t heap_size,
|
uintptr_t heap_size,
|
||||||
size_t sbrk_amount
|
size_t sbrk_amount
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
RTEMS_Malloc_Initialize( heap_start, heap_size, sbrk_amount );
|
RTEMS_Malloc_Initialize( heap_begin, heap_size, sbrk_amount );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init the RTEMS libio facility to provide UNIX-like system
|
* Init the RTEMS libio facility to provide UNIX-like system
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* @ingroup bsp_shared
|
* @ingroup bsp_bootcard
|
||||||
*
|
*
|
||||||
* @brief Header file for basic BSP startup functions.
|
* @brief Standard system startup.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -21,7 +21,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup bsp_shared Shared BSP Code
|
* @defgroup bsp_kit Board Support Package
|
||||||
|
*
|
||||||
|
* @brief Board support package dependent code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup bsp_bootcard Bootcard
|
||||||
|
*
|
||||||
|
* @ingroup bsp_kit
|
||||||
|
*
|
||||||
|
* @brief Standard system startup.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBBSP_SHARED_BOOTCARD_H
|
#ifndef LIBBSP_SHARED_BOOTCARD_H
|
||||||
@@ -37,6 +49,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Global pointer to the command line of boot_card().
|
||||||
|
*/
|
||||||
|
extern const char *bsp_boot_cmdline;
|
||||||
|
|
||||||
void bsp_start(void);
|
void bsp_start(void);
|
||||||
|
|
||||||
void bsp_pretasking_hook(void);
|
void bsp_pretasking_hook(void);
|
||||||
@@ -49,20 +66,72 @@ void bsp_cleanup(void);
|
|||||||
|
|
||||||
void bsp_reset(void);
|
void bsp_reset(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Should be used as the heap begin address in bsp_get_work_area() if
|
||||||
|
* the heap area is contained in the work area.
|
||||||
|
*/
|
||||||
#define BSP_BOOTCARD_HEAP_USES_WORK_AREA NULL
|
#define BSP_BOOTCARD_HEAP_USES_WORK_AREA NULL
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Should be used to request the default heap size in bsp_get_work_area().
|
||||||
|
*
|
||||||
|
* In case that the heap area is contained in the work area this heap size
|
||||||
|
* value indicates that the area outside the work space should be used as heap
|
||||||
|
* space.
|
||||||
|
*/
|
||||||
#define BSP_BOOTCARD_HEAP_SIZE_DEFAULT 0
|
#define BSP_BOOTCARD_HEAP_SIZE_DEFAULT 0
|
||||||
|
|
||||||
void bsp_get_work_area(
|
void bsp_get_work_area(
|
||||||
void **work_area_start,
|
void **work_area_begin,
|
||||||
uintptr_t *work_area_size,
|
uintptr_t *work_area_size,
|
||||||
void **heap_start,
|
void **heap_begin,
|
||||||
uintptr_t *heap_size
|
uintptr_t *heap_size
|
||||||
);
|
);
|
||||||
|
|
||||||
int boot_card( const char *cmdline );
|
/**
|
||||||
|
* @brief Standard system initialization procedure.
|
||||||
|
*
|
||||||
|
* You may pass a command line in @a cmdline. It is later available via the
|
||||||
|
* global @ref bsp_boot_cmdline variable.
|
||||||
|
*
|
||||||
|
* This is the C entry point for ALL RTEMS BSPs. It is invoked from the
|
||||||
|
* assembly language initialization file usually called @c start.S which does
|
||||||
|
* the basic CPU setup (stack, C runtime environment, zero BSS, load other
|
||||||
|
* sections) and calls afterwards boot_card(). The boot card function provides
|
||||||
|
* the framework for the BSP initialization sequence. The basic flow of
|
||||||
|
* initialization is:
|
||||||
|
*
|
||||||
|
* - disable interrupts, interrupts will be enabled during the first context switch
|
||||||
|
* - bsp_start() - more advanced initialization
|
||||||
|
* - obtain information on BSP memory via bsp_get_work_area() and allocate RTEMS Workspace
|
||||||
|
* - rtems_initialize_data_structures()
|
||||||
|
* - allocate memory for C Program Heap
|
||||||
|
* - initialize C Library and C Program Heap
|
||||||
|
* - bsp_pretasking_hook()
|
||||||
|
* - if defined( RTEMS_DEBUG )
|
||||||
|
* - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK )
|
||||||
|
* - rtems_initialize_before_drivers()
|
||||||
|
* - bsp_predriver_hook()
|
||||||
|
* - rtems_initialize_device_drivers()
|
||||||
|
* - initialization of all device drivers
|
||||||
|
* - bsp_postdriver_hook()
|
||||||
|
* - rtems_initialize_start_multitasking()
|
||||||
|
* - 1st task executes C++ global constructors
|
||||||
|
* - .... appplication runs ...
|
||||||
|
* - exit
|
||||||
|
* - back to here eventually
|
||||||
|
* - bsp_cleanup()
|
||||||
|
*
|
||||||
|
* If something goes wrong bsp_cleanup() will be called out of order.
|
||||||
|
*
|
||||||
|
* This style of initialization ensures that the C++ global constructors are
|
||||||
|
* executed after RTEMS is initialized.
|
||||||
|
*/
|
||||||
|
int boot_card(const char *cmdline);
|
||||||
|
|
||||||
void bsp_libc_init( void *heap_start, size_t heap_size, size_t sbrk_amount);
|
/** @} */
|
||||||
|
|
||||||
|
void bsp_libc_init(void *heap_begin, uintptr_t heap_size, size_t sbrk_amount);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,16 @@
|
|||||||
/*
|
/*
|
||||||
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008, 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be found in the file
|
* The license and distribution terms for this file may be
|
||||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBBSP_SHARED_IRQ_CONFIG_H
|
#ifndef LIBBSP_SHARED_IRQ_CONFIG_H
|
||||||
@@ -60,18 +61,16 @@
|
|||||||
#undef BSP_INTERRUPT_NO_HEAP_USAGE
|
#undef BSP_INTERRUPT_NO_HEAP_USAGE
|
||||||
|
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
|
/**
|
||||||
|
* @brief Size of the handler table.
|
||||||
|
*/
|
||||||
|
#define BSP_INTERRUPT_HANDLER_TABLE_SIZE 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size of the handler table.
|
* @brief Integer type capable to index the complete handler table.
|
||||||
*/
|
*/
|
||||||
#define BSP_INTERRUPT_HANDLER_TABLE_SIZE 0
|
typedef uint8_t bsp_interrupt_handler_index_type;
|
||||||
|
#endif
|
||||||
/**
|
|
||||||
* @brief Integer type capable to index the complete handler table.
|
|
||||||
*/
|
|
||||||
typedef uint8_t bsp_interrupt_handler_index_type;
|
|
||||||
|
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|||||||
@@ -3,21 +3,22 @@
|
|||||||
*
|
*
|
||||||
* @ingroup bsp_interrupt
|
* @ingroup bsp_interrupt
|
||||||
*
|
*
|
||||||
* @brief Header file for generic BSP interrupt support.
|
* @brief Generic BSP interrupt support API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008, 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be found in the file
|
* The license and distribution terms for this file may be
|
||||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBBSP_SHARED_IRQ_GENERIC_H
|
#ifndef LIBBSP_SHARED_IRQ_GENERIC_H
|
||||||
@@ -33,29 +34,30 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#if !defined( BSP_INTERRUPT_VECTOR_MIN) || !defined( BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
|
#if !defined(BSP_INTERRUPT_VECTOR_MIN) || !defined(BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
|
||||||
#error Invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX.
|
#error "invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX"
|
||||||
#endif /* !defined( BSP_INTERRUPT_VECTOR_MIN) ... */
|
#endif
|
||||||
|
|
||||||
#if defined( BSP_INTERRUPT_USE_INDEX_TABLE) && !defined( BSP_INTERRUPT_HANDLER_TABLE_SIZE)
|
#if defined(BSP_INTERRUPT_USE_INDEX_TABLE) && !defined(BSP_INTERRUPT_HANDLER_TABLE_SIZE)
|
||||||
#error If you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well.
|
#error "if you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well"
|
||||||
#endif /* defined( BSP_INTERRUPT_USE_INDEX_TABLE) ... */
|
#endif
|
||||||
|
|
||||||
#if defined( BSP_INTERRUPT_NO_HEAP_USAGE) && !defined( BSP_INTERRUPT_USE_INDEX_TABLE)
|
#if defined(BSP_INTERRUPT_NO_HEAP_USAGE) && !defined(BSP_INTERRUPT_USE_INDEX_TABLE)
|
||||||
#error If you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well.
|
#error "if you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well"
|
||||||
#endif /* defined( BSP_INTERRUPT_NO_HEAP_USAGE) ... */
|
#endif
|
||||||
|
|
||||||
#define BSP_INTERRUPT_VECTOR_NUMBER (BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
|
#define BSP_INTERRUPT_VECTOR_NUMBER \
|
||||||
|
(BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
|
||||||
|
|
||||||
#ifndef BSP_INTERRUPT_HANDLER_TABLE_SIZE
|
#ifndef BSP_INTERRUPT_HANDLER_TABLE_SIZE
|
||||||
#define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
|
#define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
|
||||||
#endif /* BSP_INTERRUPT_HANDLER_TABLE_SIZE */
|
#endif
|
||||||
|
|
||||||
struct bsp_interrupt_handler_entry {
|
struct bsp_interrupt_handler_entry {
|
||||||
rtems_interrupt_handler handler;
|
rtems_interrupt_handler handler;
|
||||||
void *arg;
|
void *arg;
|
||||||
const char *info;
|
const char *info;
|
||||||
struct bsp_interrupt_handler_entry *next;
|
struct bsp_interrupt_handler_entry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct bsp_interrupt_handler_entry bsp_interrupt_handler_entry;
|
typedef struct bsp_interrupt_handler_entry bsp_interrupt_handler_entry;
|
||||||
@@ -63,16 +65,18 @@ typedef struct bsp_interrupt_handler_entry bsp_interrupt_handler_entry;
|
|||||||
extern bsp_interrupt_handler_entry bsp_interrupt_handler_table [];
|
extern bsp_interrupt_handler_entry bsp_interrupt_handler_table [];
|
||||||
|
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
|
extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#endif
|
||||||
|
|
||||||
static inline rtems_vector_number bsp_interrupt_handler_index( rtems_vector_number vector)
|
static inline rtems_vector_number bsp_interrupt_handler_index(
|
||||||
|
rtems_vector_number vector
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
|
return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
|
||||||
#else /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#else
|
||||||
return vector - BSP_INTERRUPT_VECTOR_MIN;
|
return vector - BSP_INTERRUPT_VECTOR_MIN;
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,10 +133,10 @@ static inline rtems_vector_number bsp_interrupt_handler_index( rtems_vector_numb
|
|||||||
/**
|
/**
|
||||||
* @brief Returns true if the interrupt vector with number @a vector is valid.
|
* @brief Returns true if the interrupt vector with number @a vector is valid.
|
||||||
*/
|
*/
|
||||||
static inline bool bsp_interrupt_is_valid_vector( rtems_vector_number vector)
|
static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
|
||||||
{
|
{
|
||||||
return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
|
return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
|
||||||
&& vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
|
&& vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +148,7 @@ static inline bool bsp_interrupt_is_valid_vector( rtems_vector_number vector)
|
|||||||
*
|
*
|
||||||
* @note This function must cope with arbitrary vector numbers @a vector.
|
* @note This function must cope with arbitrary vector numbers @a vector.
|
||||||
*/
|
*/
|
||||||
void bsp_interrupt_handler_default( rtems_vector_number vector);
|
void bsp_interrupt_handler_default(rtems_vector_number vector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize BSP interrupt support.
|
* @brief Initialize BSP interrupt support.
|
||||||
@@ -154,7 +158,7 @@ void bsp_interrupt_handler_default( rtems_vector_number vector);
|
|||||||
* function will be called after all internals are initialized. Initialization
|
* function will be called after all internals are initialized. Initialization
|
||||||
* is complete if everything was successful.
|
* is complete if everything was successful.
|
||||||
*/
|
*/
|
||||||
rtems_status_code bsp_interrupt_initialize( void);
|
rtems_status_code bsp_interrupt_initialize(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief BSP specific initialization.
|
* @brief BSP specific initialization.
|
||||||
@@ -171,7 +175,7 @@ rtems_status_code bsp_interrupt_initialize( void);
|
|||||||
*
|
*
|
||||||
* @return On success RTEMS_SUCCESSFUL shall be returned.
|
* @return On success RTEMS_SUCCESSFUL shall be returned.
|
||||||
*/
|
*/
|
||||||
rtems_status_code bsp_interrupt_facility_initialize( void);
|
rtems_status_code bsp_interrupt_facility_initialize(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables the interrupt vector with number @a vector.
|
* @brief Enables the interrupt vector with number @a vector.
|
||||||
@@ -187,7 +191,7 @@ rtems_status_code bsp_interrupt_facility_initialize( void);
|
|||||||
*
|
*
|
||||||
* @return On success RTEMS_SUCCESSFUL shall be returned.
|
* @return On success RTEMS_SUCCESSFUL shall be returned.
|
||||||
*/
|
*/
|
||||||
rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector);
|
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables the interrupt vector with number @a vector.
|
* @brief Disables the interrupt vector with number @a vector.
|
||||||
@@ -203,7 +207,7 @@ rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector);
|
|||||||
*
|
*
|
||||||
* @return On success RTEMS_SUCCESSFUL shall be returned.
|
* @return On success RTEMS_SUCCESSFUL shall be returned.
|
||||||
*/
|
*/
|
||||||
rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector);
|
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sequencially calls all interrupt handlers for the vector number @a
|
* @brief Sequencially calls all interrupt handlers for the vector number @a
|
||||||
@@ -215,18 +219,19 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector);
|
|||||||
* You can call this function within every context which can be disabled via
|
* You can call this function within every context which can be disabled via
|
||||||
* rtems_interrupt_disable().
|
* rtems_interrupt_disable().
|
||||||
*/
|
*/
|
||||||
static inline void bsp_interrupt_handler_dispatch( rtems_vector_number vector)
|
static inline void bsp_interrupt_handler_dispatch(rtems_vector_number vector)
|
||||||
{
|
{
|
||||||
if (bsp_interrupt_is_valid_vector( vector)) {
|
if (bsp_interrupt_is_valid_vector(vector)) {
|
||||||
bsp_interrupt_handler_entry *e = &bsp_interrupt_handler_table [bsp_interrupt_handler_index( vector)];
|
bsp_interrupt_handler_entry *e =
|
||||||
|
&bsp_interrupt_handler_table [bsp_interrupt_handler_index(vector)];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
e->handler( vector, e->arg);
|
(*e->handler)(vector, e->arg);
|
||||||
e = e->next;
|
e = e->next;
|
||||||
} while (e != NULL);
|
} while (e != NULL);
|
||||||
} else {
|
} else {
|
||||||
bsp_interrupt_handler_default( vector);
|
bsp_interrupt_handler_default(vector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@@ -3,19 +3,20 @@
|
|||||||
*
|
*
|
||||||
* @ingroup bsp_interrupt
|
* @ingroup bsp_interrupt
|
||||||
*
|
*
|
||||||
* @brief Header file for generic BSP interrupt information.
|
* @brief Generic BSP interrupt information API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008, 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be found in the file
|
* The license and distribution terms for this file may be
|
||||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBBSP_SHARED_IRQ_INFO_H
|
#ifndef LIBBSP_SHARED_IRQ_INFO_H
|
||||||
@@ -36,10 +37,23 @@ extern "C" {
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void bsp_interrupt_report_with_plugin( void *context, rtems_printk_plugin_t print);
|
/**
|
||||||
|
* @brief Prints interrupt information via the printk plugin @a print with the
|
||||||
|
* context @a context.
|
||||||
|
*/
|
||||||
|
void bsp_interrupt_report_with_plugin(
|
||||||
|
void *context,
|
||||||
|
rtems_printk_plugin_t print
|
||||||
|
);
|
||||||
|
|
||||||
void bsp_interrupt_report( void);
|
/**
|
||||||
|
* @brief Prints interrupt information via the default printk plugin.
|
||||||
|
*/
|
||||||
|
void bsp_interrupt_report(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shell command entry for interrupt information.
|
||||||
|
*/
|
||||||
extern struct rtems_shell_cmd_tt bsp_interrupt_shell_command;
|
extern struct rtems_shell_cmd_tt bsp_interrupt_shell_command;
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* @ingroup bsp_shared
|
* @ingroup bsp_stack
|
||||||
*
|
*
|
||||||
* @brief Stack initialization, allocation and free functions.
|
* @brief Task stack initialization, allocation and free functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -22,22 +22,68 @@
|
|||||||
#ifndef LIBBSP_SHARED_STACK_ALLOC_H
|
#ifndef LIBBSP_SHARED_STACK_ALLOC_H
|
||||||
#define LIBBSP_SHARED_STACK_ALLOC_H
|
#define LIBBSP_SHARED_STACK_ALLOC_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
void bsp_stack_initialize(void *start, intptr_t size);
|
/**
|
||||||
|
* @defgroup bsp_stack Task Stack Allocator
|
||||||
|
*
|
||||||
|
* @ingroup bsp_kit
|
||||||
|
*
|
||||||
|
* @brief Task stack initialization, allocation and free functions.
|
||||||
|
*
|
||||||
|
* Initialize the task stack allocator with bsp_stack_initialize(). To enable
|
||||||
|
* the task stack allocator use the following in the system configuration:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* #include <bsp/stackalloc.h>
|
||||||
|
*
|
||||||
|
* #define CONFIGURE_INIT
|
||||||
|
*
|
||||||
|
* #include <confdefs.h>
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
void *bsp_stack_allocate(uint32_t size);
|
/**
|
||||||
|
* @brief Task stack management initialization.
|
||||||
|
*
|
||||||
|
* This function should be called in bsp_start() with the designated task stack
|
||||||
|
* area begin address @a begin and task stack area size @a size in bytes. The
|
||||||
|
* area boundaries have to be aligned properly.
|
||||||
|
*/
|
||||||
|
void bsp_stack_initialize(void *begin, uintptr_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task stack allocator for @ref CONFIGURE_TASK_STACK_ALLOCATOR.
|
||||||
|
*
|
||||||
|
* In case the designated task stack space from bsp_stack_initialize() is
|
||||||
|
* completely in use the work space will be used to allocate the stack.
|
||||||
|
*/
|
||||||
|
void *bsp_stack_allocate(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task stack free function for @ref CONFIGURE_TASK_STACK_DEALLOCATOR.
|
||||||
|
*/
|
||||||
void bsp_stack_free(void *stack);
|
void bsp_stack_free(void *stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task stack allocator configuration option.
|
||||||
|
*/
|
||||||
#define CONFIGURE_TASK_STACK_ALLOCATOR bsp_stack_allocate
|
#define CONFIGURE_TASK_STACK_ALLOCATOR bsp_stack_allocate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task stack deallocator configuration option.
|
||||||
|
*/
|
||||||
#define CONFIGURE_TASK_STACK_DEALLOCATOR bsp_stack_free
|
#define CONFIGURE_TASK_STACK_DEALLOCATOR bsp_stack_free
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
@@ -3,219 +3,238 @@
|
|||||||
*
|
*
|
||||||
* @ingroup bsp_interrupt
|
* @ingroup bsp_interrupt
|
||||||
*
|
*
|
||||||
* @brief Source file for generic BSP interrupt support.
|
* @brief Generic BSP interrupt support implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008, 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be found in the file
|
* The license and distribution terms for this file may be
|
||||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h> /* malloc, free */
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <bsp/irq-generic.h>
|
#include <bsp/irq-generic.h>
|
||||||
|
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [BSP_INTERRUPT_VECTOR_NUMBER];
|
bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
[BSP_INTERRUPT_VECTOR_NUMBER];
|
||||||
|
#endif
|
||||||
|
|
||||||
static void bsp_interrupt_handler_empty( rtems_vector_number vector, void *arg)
|
bsp_interrupt_handler_entry bsp_interrupt_handler_table
|
||||||
{
|
[BSP_INTERRUPT_HANDLER_TABLE_SIZE];
|
||||||
bsp_interrupt_handler_default( vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
bsp_interrupt_handler_entry bsp_interrupt_handler_table [BSP_INTERRUPT_HANDLER_TABLE_SIZE] = {
|
|
||||||
[0 ... BSP_INTERRUPT_HANDLER_TABLE_SIZE - 1] = {
|
|
||||||
.handler = bsp_interrupt_handler_empty,
|
|
||||||
.arg = NULL,
|
|
||||||
.info = NULL,
|
|
||||||
.next = NULL
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The last entry indicates if everything is initialized */
|
/* The last entry indicates if everything is initialized */
|
||||||
static uint8_t bsp_interrupt_handler_unique_table [(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
|
static uint8_t bsp_interrupt_handler_unique_table
|
||||||
|
[(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
|
||||||
|
|
||||||
static rtems_id bsp_interrupt_mutex = RTEMS_ID_NONE;
|
static rtems_id bsp_interrupt_mutex = RTEMS_ID_NONE;
|
||||||
|
|
||||||
static inline bool bsp_interrupt_is_handler_unique( rtems_vector_number index)
|
static void bsp_interrupt_handler_empty(rtems_vector_number vector, void *arg)
|
||||||
{
|
{
|
||||||
rtems_vector_number i = index / 8;
|
bsp_interrupt_handler_default(vector);
|
||||||
rtems_vector_number s = index % 8;
|
|
||||||
return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bsp_interrupt_set_handler_unique( rtems_vector_number index, bool unique)
|
static inline bool bsp_interrupt_is_handler_unique(rtems_vector_number index)
|
||||||
{
|
{
|
||||||
rtems_vector_number i = index / 8;
|
rtems_vector_number i = index / 8;
|
||||||
rtems_vector_number s = index % 8;
|
rtems_vector_number s = index % 8;
|
||||||
if (unique) {
|
return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
|
||||||
bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
|
}
|
||||||
} else {
|
|
||||||
bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
|
static inline void bsp_interrupt_set_handler_unique(
|
||||||
}
|
rtems_vector_number index,
|
||||||
|
bool unique
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_vector_number i = index / 8;
|
||||||
|
rtems_vector_number s = index % 8;
|
||||||
|
if (unique) {
|
||||||
|
bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
|
||||||
|
} else {
|
||||||
|
bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool bsp_interrupt_is_initialized(void)
|
static inline bool bsp_interrupt_is_initialized(void)
|
||||||
{
|
{
|
||||||
return bsp_interrupt_is_handler_unique( BSP_INTERRUPT_HANDLER_TABLE_SIZE);
|
return bsp_interrupt_is_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bsp_interrupt_set_initialized(void)
|
static inline void bsp_interrupt_set_initialized(void)
|
||||||
{
|
{
|
||||||
bsp_interrupt_set_handler_unique( BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
|
bsp_interrupt_set_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool bsp_interrupt_is_empty_handler_entry( bsp_interrupt_handler_entry *e)
|
static inline bool bsp_interrupt_is_empty_handler_entry(
|
||||||
|
bsp_interrupt_handler_entry *e
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return e->handler == bsp_interrupt_handler_empty;
|
return e->handler == bsp_interrupt_handler_empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bsp_interrupt_clear_handler_entry( bsp_interrupt_handler_entry *e)
|
static inline void bsp_interrupt_clear_handler_entry(
|
||||||
|
bsp_interrupt_handler_entry *e
|
||||||
|
)
|
||||||
{
|
{
|
||||||
e->handler = bsp_interrupt_handler_empty;
|
e->handler = bsp_interrupt_handler_empty;
|
||||||
e->arg = NULL;
|
e->arg = NULL;
|
||||||
e->info = NULL;
|
e->info = NULL;
|
||||||
e->next = NULL;
|
e->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool bsp_interrupt_allocate_handler_index( rtems_vector_number vector, rtems_vector_number *index)
|
static inline bool bsp_interrupt_allocate_handler_index(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_vector_number *index
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
rtems_vector_number i = 0;
|
rtems_vector_number i = 0;
|
||||||
|
|
||||||
/* The first entry will remain empty */
|
/* The first entry will remain empty */
|
||||||
for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
|
for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
|
||||||
if (bsp_interrupt_is_empty_handler_entry( &bsp_interrupt_handler_table [i])) {
|
const bsp_interrupt_handler_entry *e = &bsp_interrupt_handler_table [i];
|
||||||
*index = i;
|
if (bsp_interrupt_is_empty_handler_entry(e)) {
|
||||||
return 1;
|
*index = i;
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
#else /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#else
|
||||||
*index = vector;
|
*index = vector;
|
||||||
return 1;
|
return true;
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bsp_interrupt_handler_entry *bsp_interrupt_allocate_handler_entry( void)
|
static bsp_interrupt_handler_entry *bsp_interrupt_allocate_handler_entry(void)
|
||||||
{
|
{
|
||||||
#ifdef BSP_INTERRUPT_NO_HEAP_USAGE
|
#ifdef BSP_INTERRUPT_NO_HEAP_USAGE
|
||||||
rtems_vector_number index = 0;
|
rtems_vector_number index = 0;
|
||||||
if (bsp_interrupt_allocate_handler_index( 0, &index)) {
|
if (bsp_interrupt_allocate_handler_index(0, &index)) {
|
||||||
return &bsp_interrupt_handler_table [index];
|
return &bsp_interrupt_handler_table [index];
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else /* BSP_INTERRUPT_NO_HEAP_USAGE */
|
#else
|
||||||
return malloc( sizeof( bsp_interrupt_handler_entry));
|
return malloc(sizeof(bsp_interrupt_handler_entry));
|
||||||
#endif /* BSP_INTERRUPT_NO_HEAP_USAGE */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bsp_interrupt_free_handler_entry( bsp_interrupt_handler_entry *e)
|
static void bsp_interrupt_free_handler_entry(bsp_interrupt_handler_entry *e)
|
||||||
{
|
{
|
||||||
#ifdef BSP_INTERRUPT_NO_HEAP_USAGE
|
#ifdef BSP_INTERRUPT_NO_HEAP_USAGE
|
||||||
bsp_interrupt_clear_handler_entry( e);
|
bsp_interrupt_clear_handler_entry(e);
|
||||||
#else /* BSP_INTERRUPT_NO_HEAP_USAGE */
|
#else
|
||||||
free( e);
|
free(e);
|
||||||
#endif /* BSP_INTERRUPT_NO_HEAP_USAGE */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtems_status_code bsp_interrupt_lock( void)
|
static rtems_status_code bsp_interrupt_lock(void)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
if (_System_state_Is_up( _System_state_Get())) {
|
if (_System_state_Is_up(_System_state_Get())) {
|
||||||
if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
|
if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
|
||||||
rtems_id mutex = RTEMS_ID_NONE;
|
rtems_id mutex = RTEMS_ID_NONE;
|
||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
/* Create a mutex */
|
/* Create a mutex */
|
||||||
sc = rtems_semaphore_create (
|
sc = rtems_semaphore_create (
|
||||||
rtems_build_name( 'I', 'N', 'T', 'R'),
|
rtems_build_name('I', 'N', 'T', 'R'),
|
||||||
1,
|
1,
|
||||||
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
|
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||||
RTEMS_NO_PRIORITY,
|
0,
|
||||||
&mutex
|
&mutex
|
||||||
);
|
);
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign the mutex */
|
/* Assign the mutex */
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable(level);
|
||||||
if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
|
if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
|
||||||
/* Nobody else assigned the mutex in the meantime */
|
/* Nobody else assigned the mutex in the meantime */
|
||||||
|
|
||||||
bsp_interrupt_mutex = mutex;
|
bsp_interrupt_mutex = mutex;
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
} else {
|
} else {
|
||||||
/* Somebody else won */
|
/* Somebody else won */
|
||||||
|
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
sc = rtems_semaphore_delete( mutex);
|
sc = rtems_semaphore_delete(mutex);
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rtems_semaphore_obtain( bsp_interrupt_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
return rtems_semaphore_obtain(
|
||||||
} else {
|
bsp_interrupt_mutex,
|
||||||
return RTEMS_SUCCESSFUL;
|
RTEMS_WAIT,
|
||||||
}
|
RTEMS_NO_TIMEOUT
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtems_status_code bsp_interrupt_unlock( void)
|
static rtems_status_code bsp_interrupt_unlock(void)
|
||||||
{
|
{
|
||||||
if (bsp_interrupt_mutex != RTEMS_ID_NONE) {
|
if (bsp_interrupt_mutex != RTEMS_ID_NONE) {
|
||||||
return rtems_semaphore_release( bsp_interrupt_mutex);
|
return rtems_semaphore_release(bsp_interrupt_mutex);
|
||||||
} else {
|
} else {
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_status_code bsp_interrupt_initialize( void)
|
rtems_status_code bsp_interrupt_initialize(void)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
/* Lock */
|
sc = bsp_interrupt_lock();
|
||||||
sc = bsp_interrupt_lock();
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
return sc;
|
||||||
return sc;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if already initialized */
|
/* We need one semaphore */
|
||||||
if (bsp_interrupt_is_initialized()) {
|
if (_System_state_Is_before_initialization(_System_state_Get())) {
|
||||||
bsp_interrupt_unlock();
|
Configuration.work_space_size += sizeof(Semaphore_Control);
|
||||||
return RTEMS_INTERNAL_ERROR;
|
++Configuration_RTEMS_API.maximum_semaphores;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BSP specific initialization */
|
if (bsp_interrupt_is_initialized()) {
|
||||||
sc = bsp_interrupt_facility_initialize();
|
bsp_interrupt_unlock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
return RTEMS_INTERNAL_ERROR;
|
||||||
bsp_interrupt_unlock();
|
}
|
||||||
return sc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we are initialized */
|
/* Initialize handler table */
|
||||||
bsp_interrupt_set_initialized();
|
for (i = 0; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
|
||||||
|
bsp_interrupt_handler_table [i].handler = bsp_interrupt_handler_empty;
|
||||||
|
}
|
||||||
|
|
||||||
/* Unlock */
|
sc = bsp_interrupt_facility_initialize();
|
||||||
sc = bsp_interrupt_unlock();
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
bsp_interrupt_unlock();
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
bsp_interrupt_set_initialized();
|
||||||
|
|
||||||
|
sc = bsp_interrupt_unlock();
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -231,132 +250,141 @@ rtems_status_code bsp_interrupt_initialize( void)
|
|||||||
*
|
*
|
||||||
* @see rtems_interrupt_handler_install()
|
* @see rtems_interrupt_handler_install()
|
||||||
*/
|
*/
|
||||||
static rtems_status_code bsp_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
|
static rtems_status_code bsp_interrupt_handler_install(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
const char *info,
|
||||||
|
rtems_option options,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
rtems_vector_number index = 0;
|
rtems_vector_number index = 0;
|
||||||
bsp_interrupt_handler_entry *head = NULL;
|
bsp_interrupt_handler_entry *head = NULL;
|
||||||
bsp_interrupt_handler_entry *tail = NULL;
|
bsp_interrupt_handler_entry *tail = NULL;
|
||||||
bsp_interrupt_handler_entry *current = NULL;
|
bsp_interrupt_handler_entry *current = NULL;
|
||||||
bsp_interrupt_handler_entry *match = NULL;
|
bsp_interrupt_handler_entry *match = NULL;
|
||||||
bool enable_vector = false;
|
bool enable_vector = false;
|
||||||
|
|
||||||
/* Check parameters and system state */
|
/* Check parameters and system state */
|
||||||
if (!bsp_interrupt_is_initialized()) {
|
if (!bsp_interrupt_is_initialized()) {
|
||||||
return RTEMS_INTERNAL_ERROR;
|
return RTEMS_INTERNAL_ERROR;
|
||||||
} else if (!bsp_interrupt_is_valid_vector( vector)) {
|
} else if (!bsp_interrupt_is_valid_vector(vector)) {
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_ID;
|
||||||
} else if (handler == NULL) {
|
} else if (handler == NULL) {
|
||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
} else if (rtems_interrupt_is_in_progress()) {
|
} else if (rtems_interrupt_is_in_progress()) {
|
||||||
return RTEMS_CALLED_FROM_ISR;
|
return RTEMS_CALLED_FROM_ISR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
sc = bsp_interrupt_lock();
|
sc = bsp_interrupt_lock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get handler table index */
|
/* Get handler table index */
|
||||||
index = bsp_interrupt_handler_index( vector);
|
index = bsp_interrupt_handler_index(vector);
|
||||||
|
|
||||||
/* Get head entry of the handler list for current vector */
|
/* Get head entry of the handler list for current vector */
|
||||||
head = &bsp_interrupt_handler_table [index];
|
head = &bsp_interrupt_handler_table [index];
|
||||||
|
|
||||||
if (bsp_interrupt_is_empty_handler_entry( head)) {
|
if (bsp_interrupt_is_empty_handler_entry(head)) {
|
||||||
/*
|
/*
|
||||||
* No real handler installed yet. So allocate a new index in
|
* No real handler installed yet. So allocate a new index in
|
||||||
* the handler table and fill the entry with life.
|
* the handler table and fill the entry with life.
|
||||||
*/
|
*/
|
||||||
if (bsp_interrupt_allocate_handler_index( vector, &index)) {
|
if (bsp_interrupt_allocate_handler_index(vector, &index)) {
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable(level);
|
||||||
bsp_interrupt_handler_table [index].handler = handler;
|
bsp_interrupt_handler_table [index].handler = handler;
|
||||||
bsp_interrupt_handler_table [index].arg = arg;
|
bsp_interrupt_handler_table [index].arg = arg;
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
bsp_interrupt_handler_index_table [vector] = index;
|
bsp_interrupt_handler_index_table [vector] = index;
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#endif
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
bsp_interrupt_handler_table [index].info = info;
|
bsp_interrupt_handler_table [index].info = info;
|
||||||
} else {
|
} else {
|
||||||
/* Handler table is full */
|
/* Handler table is full */
|
||||||
bsp_interrupt_unlock();
|
bsp_interrupt_unlock();
|
||||||
return RTEMS_NO_MEMORY;
|
return RTEMS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the first handler so enable the vector later */
|
/* This is the first handler so enable the vector later */
|
||||||
enable_vector = true;
|
enable_vector = true;
|
||||||
} else {
|
} else {
|
||||||
/* Ensure that a unique handler remains unique */
|
/* Ensure that a unique handler remains unique */
|
||||||
if (RTEMS_INTERRUPT_IS_UNIQUE( options) || bsp_interrupt_is_handler_unique( index)) {
|
if (
|
||||||
/*
|
RTEMS_INTERRUPT_IS_UNIQUE(options)
|
||||||
* Tried to install a unique handler on a not empty
|
|| bsp_interrupt_is_handler_unique(index)
|
||||||
* list or there is already a unique handler installed.
|
) {
|
||||||
*/
|
/*
|
||||||
bsp_interrupt_unlock();
|
* Tried to install a unique handler on a not empty
|
||||||
return RTEMS_RESOURCE_IN_USE;
|
* list or there is already a unique handler installed.
|
||||||
}
|
*/
|
||||||
|
bsp_interrupt_unlock();
|
||||||
|
return RTEMS_RESOURCE_IN_USE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for the list tail and check if the handler is already
|
* Search for the list tail and check if the handler is already
|
||||||
* installed.
|
* installed.
|
||||||
*/
|
*/
|
||||||
current = head;
|
current = head;
|
||||||
do {
|
do {
|
||||||
if (current->handler == handler && current->arg == arg) {
|
if (current->handler == handler && current->arg == arg) {
|
||||||
match = current;
|
match = current;
|
||||||
}
|
}
|
||||||
tail = current;
|
tail = current;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
} while (current != NULL);
|
} while (current != NULL);
|
||||||
|
|
||||||
/* Ensure the handler is not already installed */
|
/* Ensure the handler is not already installed */
|
||||||
if (match != NULL) {
|
if (match != NULL) {
|
||||||
/* The handler is already installed */
|
/* The handler is already installed */
|
||||||
bsp_interrupt_unlock();
|
bsp_interrupt_unlock();
|
||||||
return RTEMS_TOO_MANY;
|
return RTEMS_TOO_MANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new entry */
|
/* Allocate a new entry */
|
||||||
current = bsp_interrupt_allocate_handler_entry();
|
current = bsp_interrupt_allocate_handler_entry();
|
||||||
if (current == NULL) {
|
if (current == NULL) {
|
||||||
/* Not enough memory */
|
/* Not enough memory */
|
||||||
bsp_interrupt_unlock();
|
bsp_interrupt_unlock();
|
||||||
return RTEMS_NO_MEMORY;
|
return RTEMS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set entry */
|
/* Set entry */
|
||||||
current->handler = handler;
|
current->handler = handler;
|
||||||
current->arg = arg;
|
current->arg = arg;
|
||||||
current->info = info;
|
current->info = info;
|
||||||
current->next = NULL;
|
current->next = NULL;
|
||||||
|
|
||||||
/* Link to list tail */
|
/* Link to list tail */
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable(level);
|
||||||
tail->next = current;
|
tail->next = current;
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the handler unique if necessary */
|
/* Make the handler unique if necessary */
|
||||||
bsp_interrupt_set_handler_unique( index, RTEMS_INTERRUPT_IS_UNIQUE( options));
|
bsp_interrupt_set_handler_unique(index, RTEMS_INTERRUPT_IS_UNIQUE(options));
|
||||||
|
|
||||||
/* Enable the vector if necessary */
|
/* Enable the vector if necessary */
|
||||||
if (enable_vector) {
|
if (enable_vector) {
|
||||||
sc = bsp_interrupt_vector_enable( vector);
|
sc = bsp_interrupt_vector_enable(vector);
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
bsp_interrupt_unlock();
|
bsp_interrupt_unlock();
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock */
|
/* Unlock */
|
||||||
sc = bsp_interrupt_unlock();
|
sc = bsp_interrupt_unlock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -369,116 +397,120 @@ static rtems_status_code bsp_interrupt_handler_install( rtems_vector_number vect
|
|||||||
*
|
*
|
||||||
* @see rtems_interrupt_handler_remove().
|
* @see rtems_interrupt_handler_remove().
|
||||||
*/
|
*/
|
||||||
static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
|
static rtems_status_code bsp_interrupt_handler_remove(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
rtems_vector_number index = 0;
|
rtems_vector_number index = 0;
|
||||||
bsp_interrupt_handler_entry *head = NULL;
|
bsp_interrupt_handler_entry *head = NULL;
|
||||||
bsp_interrupt_handler_entry *current = NULL;
|
bsp_interrupt_handler_entry *current = NULL;
|
||||||
bsp_interrupt_handler_entry *previous = NULL;
|
bsp_interrupt_handler_entry *previous = NULL;
|
||||||
bsp_interrupt_handler_entry *match = NULL;
|
bsp_interrupt_handler_entry *match = NULL;
|
||||||
|
|
||||||
/* Check parameters and system state */
|
/* Check parameters and system state */
|
||||||
if (!bsp_interrupt_is_initialized()) {
|
if (!bsp_interrupt_is_initialized()) {
|
||||||
return RTEMS_INTERNAL_ERROR;
|
return RTEMS_INTERNAL_ERROR;
|
||||||
} else if (!bsp_interrupt_is_valid_vector( vector)) {
|
} else if (!bsp_interrupt_is_valid_vector(vector)) {
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_ID;
|
||||||
} else if (handler == NULL) {
|
} else if (handler == NULL) {
|
||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
} else if (rtems_interrupt_is_in_progress()) {
|
} else if (rtems_interrupt_is_in_progress()) {
|
||||||
return RTEMS_CALLED_FROM_ISR;
|
return RTEMS_CALLED_FROM_ISR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
sc = bsp_interrupt_lock();
|
sc = bsp_interrupt_lock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get handler table index */
|
/* Get handler table index */
|
||||||
index = bsp_interrupt_handler_index( vector);
|
index = bsp_interrupt_handler_index(vector);
|
||||||
|
|
||||||
/* Get head entry of the handler list for current vector */
|
/* Get head entry of the handler list for current vector */
|
||||||
head = &bsp_interrupt_handler_table [index];
|
head = &bsp_interrupt_handler_table [index];
|
||||||
|
|
||||||
/* Search for a matching entry */
|
/* Search for a matching entry */
|
||||||
current = head;
|
current = head;
|
||||||
do {
|
do {
|
||||||
if (current->handler == handler && current->arg == arg) {
|
if (current->handler == handler && current->arg == arg) {
|
||||||
match = current;
|
match = current;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
previous = current;
|
previous = current;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
} while (current != NULL);
|
} while (current != NULL);
|
||||||
|
|
||||||
/* Remove the matching entry */
|
/* Remove the matching entry */
|
||||||
if (match != NULL) {
|
if (match != NULL) {
|
||||||
if (match->next != NULL) {
|
if (match->next != NULL) {
|
||||||
/*
|
/*
|
||||||
* The match has a successor. A successor is always
|
* The match has a successor. A successor is always
|
||||||
* allocated. So replace the match with its successor
|
* allocated. So replace the match with its successor
|
||||||
* and free the successor entry.
|
* and free the successor entry.
|
||||||
*/
|
*/
|
||||||
current = match->next;
|
current = match->next;
|
||||||
|
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable(level);
|
||||||
*match = *current;
|
*match = *current;
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
|
|
||||||
bsp_interrupt_free_handler_entry( current);
|
bsp_interrupt_free_handler_entry(current);
|
||||||
} else if (match == head) {
|
} else if (match == head) {
|
||||||
/*
|
/*
|
||||||
* The match is the list head and has no successor.
|
* The match is the list head and has no successor.
|
||||||
* The list head is stored in a static table so clear
|
* The list head is stored in a static table so clear
|
||||||
* this entry. Since now the list is empty disable the
|
* this entry. Since now the list is empty disable the
|
||||||
* vector.
|
* vector.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Disable the vector */
|
/* Disable the vector */
|
||||||
sc = bsp_interrupt_vector_disable( vector);
|
sc = bsp_interrupt_vector_disable(vector);
|
||||||
|
|
||||||
/* Clear entry */
|
/* Clear entry */
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable(level);
|
||||||
bsp_interrupt_clear_handler_entry( head);
|
bsp_interrupt_clear_handler_entry(head);
|
||||||
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
|
||||||
bsp_interrupt_handler_index_table [vector] = 0;
|
bsp_interrupt_handler_index_table [vector] = 0;
|
||||||
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
|
#endif
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
|
|
||||||
/* Allow shared handlers */
|
/* Allow shared handlers */
|
||||||
bsp_interrupt_set_handler_unique( index, false);
|
bsp_interrupt_set_handler_unique(index, false);
|
||||||
|
|
||||||
/* Check status code */
|
/* Check status code */
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
bsp_interrupt_unlock();
|
bsp_interrupt_unlock();
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* The match is the list tail and has a predecessor.
|
* The match is the list tail and has a predecessor.
|
||||||
* So terminate the predecessor and free the match.
|
* So terminate the predecessor and free the match.
|
||||||
*/
|
*/
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable(level);
|
||||||
previous->next = NULL;
|
previous->next = NULL;
|
||||||
rtems_interrupt_enable( level);
|
rtems_interrupt_enable(level);
|
||||||
|
|
||||||
bsp_interrupt_free_handler_entry( match);
|
bsp_interrupt_free_handler_entry(match);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* No matching entry found */
|
/* No matching entry found */
|
||||||
bsp_interrupt_unlock();
|
bsp_interrupt_unlock();
|
||||||
return RTEMS_UNSATISFIED;
|
return RTEMS_UNSATISFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock */
|
/* Unlock */
|
||||||
sc = bsp_interrupt_unlock();
|
sc = bsp_interrupt_unlock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -491,59 +523,78 @@ static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vecto
|
|||||||
*
|
*
|
||||||
* @see rtems_interrupt_handler_iterate().
|
* @see rtems_interrupt_handler_iterate().
|
||||||
*/
|
*/
|
||||||
static rtems_status_code bsp_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
|
static rtems_status_code bsp_interrupt_handler_iterate(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_per_handler_routine routine,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
bsp_interrupt_handler_entry *current = NULL;
|
bsp_interrupt_handler_entry *current = NULL;
|
||||||
rtems_option options = 0;
|
rtems_option options = 0;
|
||||||
rtems_vector_number index = 0;
|
rtems_vector_number index = 0;
|
||||||
|
|
||||||
/* Check parameters and system state */
|
/* Check parameters and system state */
|
||||||
if (!bsp_interrupt_is_initialized()) {
|
if (!bsp_interrupt_is_initialized()) {
|
||||||
return RTEMS_INTERNAL_ERROR;
|
return RTEMS_INTERNAL_ERROR;
|
||||||
} else if (!bsp_interrupt_is_valid_vector( vector)) {
|
} else if (!bsp_interrupt_is_valid_vector(vector)) {
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_ID;
|
||||||
} else if (rtems_interrupt_is_in_progress()) {
|
} else if (rtems_interrupt_is_in_progress()) {
|
||||||
return RTEMS_CALLED_FROM_ISR;
|
return RTEMS_CALLED_FROM_ISR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
sc = bsp_interrupt_lock();
|
sc = bsp_interrupt_lock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interate */
|
/* Interate */
|
||||||
index = bsp_interrupt_handler_index( vector);
|
index = bsp_interrupt_handler_index(vector);
|
||||||
current = &bsp_interrupt_handler_table [index];
|
current = &bsp_interrupt_handler_table [index];
|
||||||
if (!bsp_interrupt_is_empty_handler_entry( current)) {
|
if (!bsp_interrupt_is_empty_handler_entry(current)) {
|
||||||
do {
|
do {
|
||||||
options = bsp_interrupt_is_handler_unique( index) ? RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
|
options = bsp_interrupt_is_handler_unique(index) ?
|
||||||
routine( arg, current->info, options, current->handler, current->arg);
|
RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
|
||||||
current = current->next;
|
routine(arg, current->info, options, current->handler, current->arg);
|
||||||
} while (current != NULL);
|
current = current->next;
|
||||||
}
|
} while (current != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Unlock */
|
/* Unlock */
|
||||||
sc = bsp_interrupt_unlock();
|
sc = bsp_interrupt_unlock();
|
||||||
if (sc != RTEMS_SUCCESSFUL) {
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_status_code rtems_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
|
rtems_status_code rtems_interrupt_handler_install(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
const char *info,
|
||||||
|
rtems_option options,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return bsp_interrupt_handler_install( vector, info, options, handler, arg);
|
return bsp_interrupt_handler_install(vector, info, options, handler, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_status_code rtems_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
|
rtems_status_code rtems_interrupt_handler_remove(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return bsp_interrupt_handler_remove( vector, handler, arg);
|
return bsp_interrupt_handler_remove(vector, handler, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_status_code rtems_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
|
rtems_status_code rtems_interrupt_handler_iterate(
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_per_handler_routine routine,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return bsp_interrupt_handler_iterate( vector, routine, arg);
|
return bsp_interrupt_handler_iterate(vector, routine, arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,20 @@
|
|||||||
*
|
*
|
||||||
* @ingroup bsp_interrupt
|
* @ingroup bsp_interrupt
|
||||||
*
|
*
|
||||||
* @brief Source file for generic BSP interrupt information code.
|
* @brief Generic BSP interrupt information implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008, 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be found in the file
|
* The license and distribution terms for this file may be
|
||||||
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -27,62 +28,70 @@
|
|||||||
#include <bsp/irq-config.h>
|
#include <bsp/irq-config.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *context;
|
void *context;
|
||||||
rtems_printk_plugin_t print;
|
rtems_printk_plugin_t print;
|
||||||
rtems_vector_number vector;
|
rtems_vector_number vector;
|
||||||
} bsp_interrupt_report_entry;
|
} bsp_interrupt_report_entry;
|
||||||
|
|
||||||
static void bsp_interrupt_report_per_handler_routine(
|
static void bsp_interrupt_report_per_handler_routine(
|
||||||
void *arg,
|
void *arg,
|
||||||
const char *info,
|
const char *info,
|
||||||
rtems_option options,
|
rtems_option options,
|
||||||
rtems_interrupt_handler handler,
|
rtems_interrupt_handler handler,
|
||||||
void *handler_arg
|
void *handler_arg
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bsp_interrupt_report_entry *e = (bsp_interrupt_report_entry *) arg;
|
bsp_interrupt_report_entry *e = (bsp_interrupt_report_entry *) arg;
|
||||||
const char *opt = options == RTEMS_INTERRUPT_UNIQUE ? "UNIQUE" : "SHARED";
|
const char *opt = options == RTEMS_INTERRUPT_UNIQUE ? "UNIQUE" : "SHARED";
|
||||||
|
|
||||||
e->print( e->context, "%7" PRIu32 " | %-32s | %7s | %010p | %010p\n", e->vector, info, opt, handler, handler_arg);
|
e->print(
|
||||||
|
e->context,
|
||||||
|
"%7" PRIu32 " | %-32s | %7s | %010p | %010p\n",
|
||||||
|
e->vector,
|
||||||
|
info,
|
||||||
|
opt,
|
||||||
|
handler,
|
||||||
|
handler_arg
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void bsp_interrupt_report_with_plugin(
|
||||||
* @brief Prints interrupt information via the printk plugin @a print with the
|
void *context,
|
||||||
* context @a context.
|
rtems_printk_plugin_t print
|
||||||
*/
|
)
|
||||||
void bsp_interrupt_report_with_plugin( void *context, rtems_printk_plugin_t print)
|
|
||||||
{
|
{
|
||||||
rtems_vector_number v = 0;
|
rtems_vector_number v = 0;
|
||||||
bsp_interrupt_report_entry e = {
|
bsp_interrupt_report_entry e = {
|
||||||
.context = context,
|
.context = context,
|
||||||
.print = print,
|
.print = print,
|
||||||
.vector = 0
|
.vector = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
print(
|
print(
|
||||||
context,
|
context,
|
||||||
"-------------------------------------------------------------------------------\n"
|
"-------------------------------------------------------------------------------\n"
|
||||||
" INTERRUPT INFORMATION\n"
|
" INTERRUPT INFORMATION\n"
|
||||||
"--------+----------------------------------+---------+------------+------------\n"
|
"--------+----------------------------------+---------+------------+------------\n"
|
||||||
" VECTOR | INFO | OPTIONS | HANDLER | ARGUMENT \n"
|
" VECTOR | INFO | OPTIONS | HANDLER | ARGUMENT \n"
|
||||||
"--------+----------------------------------+---------+------------+------------\n"
|
"--------+----------------------------------+---------+------------+------------\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (v = BSP_INTERRUPT_VECTOR_MIN; v <= BSP_INTERRUPT_VECTOR_MAX; ++v) {
|
for (v = BSP_INTERRUPT_VECTOR_MIN; v <= BSP_INTERRUPT_VECTOR_MAX; ++v) {
|
||||||
e.vector = v;
|
e.vector = v;
|
||||||
(void) rtems_interrupt_handler_iterate( v, bsp_interrupt_report_per_handler_routine, &e);
|
rtems_interrupt_handler_iterate(
|
||||||
}
|
v,
|
||||||
|
bsp_interrupt_report_per_handler_routine,
|
||||||
|
&e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
print(
|
print(
|
||||||
context,
|
context,
|
||||||
"--------+----------------------------------+---------+------------+------------\n"
|
"--------+----------------------------------+---------+------------+------------\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void bsp_interrupt_report(void)
|
||||||
* @brief Prints interrupt information via the default printk plugin.
|
|
||||||
*/
|
|
||||||
void bsp_interrupt_report( void)
|
|
||||||
{
|
{
|
||||||
bsp_interrupt_report_with_plugin( NULL, printk_plugin);
|
bsp_interrupt_report_with_plugin(NULL, printk_plugin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,26 +3,27 @@
|
|||||||
*
|
*
|
||||||
* @ingroup bsp_interrupt
|
* @ingroup bsp_interrupt
|
||||||
*
|
*
|
||||||
* @brief Source file for generic BSP interrupt support legacy code.
|
* @brief Generic BSP interrupt support legacy implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008, 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.com/license/LICENSE.
|
|
||||||
*
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define BSP_SHARED_HANDLER_SUPPORT
|
||||||
|
|
||||||
#include <rtems/irq.h>
|
#include <rtems/irq.h>
|
||||||
|
|
||||||
#include <bsp/irq-generic.h>
|
#include <bsp/irq-generic.h>
|
||||||
@@ -84,7 +85,7 @@ int BSP_get_current_rtems_irq_handler(rtems_irq_connect_data *cd)
|
|||||||
int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
|
int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
bsp_interrupt_legacy_entry *e = malloc(sizeof( bsp_interrupt_legacy_entry));
|
bsp_interrupt_legacy_entry *e = malloc(sizeof(bsp_interrupt_legacy_entry));
|
||||||
|
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -95,8 +96,7 @@ int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
|
|||||||
|
|
||||||
sc = rtems_interrupt_handler_install(
|
sc = rtems_interrupt_handler_install(
|
||||||
cd->name,
|
cd->name,
|
||||||
"Unique interrupt handler "
|
"LEGACY INSTALLED",
|
||||||
"(installed with obsolete BSP_install_rtems_irq_handler())",
|
|
||||||
RTEMS_INTERRUPT_UNIQUE,
|
RTEMS_INTERRUPT_UNIQUE,
|
||||||
bsp_interrupt_legacy_dispatch,
|
bsp_interrupt_legacy_dispatch,
|
||||||
e
|
e
|
||||||
@@ -119,7 +119,7 @@ int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
|
|||||||
int BSP_install_rtems_shared_irq_handler(const rtems_irq_connect_data *cd)
|
int BSP_install_rtems_shared_irq_handler(const rtems_irq_connect_data *cd)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
bsp_interrupt_legacy_entry *e = malloc(sizeof( bsp_interrupt_legacy_entry));
|
bsp_interrupt_legacy_entry *e = malloc(sizeof(bsp_interrupt_legacy_entry));
|
||||||
|
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -130,8 +130,7 @@ int BSP_install_rtems_shared_irq_handler(const rtems_irq_connect_data *cd)
|
|||||||
|
|
||||||
sc = rtems_interrupt_handler_install(
|
sc = rtems_interrupt_handler_install(
|
||||||
cd->name,
|
cd->name,
|
||||||
"Shared interrupt handler "
|
"LEGACY INSTALLED",
|
||||||
"(installed with obsolete BSP_install_rtems_shared_irq_handler())",
|
|
||||||
RTEMS_INTERRUPT_SHARED,
|
RTEMS_INTERRUPT_SHARED,
|
||||||
bsp_interrupt_legacy_dispatch,
|
bsp_interrupt_legacy_dispatch,
|
||||||
e
|
e
|
||||||
|
|||||||
275
c/src/lib/libbsp/shared/src/irq-server.c
Normal file
275
c/src/lib/libbsp/shared/src/irq-server.c
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup bsp_interrupt
|
||||||
|
*
|
||||||
|
* @brief Generic BSP interrupt server implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Obere Lagerstr. 30
|
||||||
|
* D-82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <bsp/irq-generic.h>
|
||||||
|
|
||||||
|
typedef struct bsp_interrupt_server_entry {
|
||||||
|
rtems_vector_number vector;
|
||||||
|
rtems_interrupt_handler handler;
|
||||||
|
void *arg;
|
||||||
|
struct bsp_interrupt_server_entry *volatile next;
|
||||||
|
} bsp_interrupt_server_entry;
|
||||||
|
|
||||||
|
static rtems_id bsp_interrupt_server_semaphore = RTEMS_ID_NONE;
|
||||||
|
|
||||||
|
/* LIFO list head */
|
||||||
|
static bsp_interrupt_server_entry *volatile
|
||||||
|
bsp_interrupt_server_list_head = NULL;
|
||||||
|
|
||||||
|
static rtems_status_code bsp_interrupt_server_is_initialized(void)
|
||||||
|
{
|
||||||
|
if (bsp_interrupt_server_semaphore != RTEMS_ID_NONE) {
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
} else {
|
||||||
|
return RTEMS_INCORRECT_STATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bsp_interrupt_server_trigger(rtems_vector_number vector, void *arg)
|
||||||
|
{
|
||||||
|
bsp_interrupt_server_entry *e = arg;
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
bsp_interrupt_vector_disable(e->vector);
|
||||||
|
|
||||||
|
/* Add interrupt server entry to the list */
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
e->next = bsp_interrupt_server_list_head;
|
||||||
|
bsp_interrupt_server_list_head = e;
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
|
||||||
|
rtems_semaphore_release(bsp_interrupt_server_semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bsp_interrupt_server_task(rtems_task_argument arg)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
rtems_id sema = bsp_interrupt_server_semaphore;
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
bsp_interrupt_server_entry *e = NULL;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
sc = rtems_semaphore_obtain(sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch next interrupt server entry from the list */
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
e = bsp_interrupt_server_list_head;
|
||||||
|
bsp_interrupt_server_list_head = e->next;
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
|
||||||
|
(*e->handler)(e->vector, e->arg);
|
||||||
|
|
||||||
|
bsp_interrupt_vector_enable(e->vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_task_delete(RTEMS_SELF);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rtems_interrupt_handler handler;
|
||||||
|
void *arg;
|
||||||
|
bsp_interrupt_server_entry *entry;
|
||||||
|
} bsp_interrupt_server_iterate_entry;
|
||||||
|
|
||||||
|
static void bsp_interrupt_server_per_handler_routine(
|
||||||
|
void *iterate_arg,
|
||||||
|
const char *info,
|
||||||
|
rtems_option options,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *handler_arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bsp_interrupt_server_iterate_entry *ie = iterate_arg;
|
||||||
|
bsp_interrupt_server_entry *e = handler_arg;
|
||||||
|
|
||||||
|
if (handler == bsp_interrupt_server_trigger) {
|
||||||
|
if (e->handler == ie->handler && e->arg == ie->arg) {
|
||||||
|
ie->entry = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code rtems_interrupt_server_handler_install(
|
||||||
|
rtems_id server,
|
||||||
|
rtems_vector_number vector,
|
||||||
|
const char *info,
|
||||||
|
rtems_option options,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
bsp_interrupt_server_entry *e = NULL;
|
||||||
|
|
||||||
|
sc = bsp_interrupt_server_is_initialized();
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RTEMS_INTERRUPT_IS_SHARED(options)) {
|
||||||
|
return RTEMS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = malloc(sizeof(bsp_interrupt_server_entry));
|
||||||
|
if (e == NULL) {
|
||||||
|
return RTEMS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
e->vector = vector;
|
||||||
|
e->handler = handler;
|
||||||
|
e->arg = arg;
|
||||||
|
|
||||||
|
sc = rtems_interrupt_handler_install(
|
||||||
|
vector,
|
||||||
|
info,
|
||||||
|
options,
|
||||||
|
bsp_interrupt_server_trigger,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
free(e);
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code rtems_interrupt_server_handler_remove(
|
||||||
|
rtems_id server,
|
||||||
|
rtems_vector_number vector,
|
||||||
|
rtems_interrupt_handler handler,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
bsp_interrupt_server_iterate_entry ie = {
|
||||||
|
.handler = handler,
|
||||||
|
.arg = arg,
|
||||||
|
.entry = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
sc = bsp_interrupt_server_is_initialized();
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Query corresponding interrupt server entry */
|
||||||
|
sc = rtems_interrupt_handler_iterate(
|
||||||
|
vector,
|
||||||
|
bsp_interrupt_server_per_handler_routine,
|
||||||
|
&ie
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
return sc;
|
||||||
|
} else if (ie.entry == NULL) {
|
||||||
|
return RTEMS_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc = rtems_interrupt_handler_remove(
|
||||||
|
vector,
|
||||||
|
ie.entry->handler,
|
||||||
|
ie.entry->arg
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ie.entry);
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_status_code rtems_interrupt_server_initialize(
|
||||||
|
rtems_task_priority priority,
|
||||||
|
size_t stack_size,
|
||||||
|
rtems_mode modes,
|
||||||
|
rtems_attribute attributes,
|
||||||
|
rtems_id *server
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
rtems_id sema_id = RTEMS_ID_NONE;
|
||||||
|
rtems_id task_id = RTEMS_ID_NONE;
|
||||||
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
|
sc = rtems_semaphore_create(
|
||||||
|
rtems_build_name('I', 'R', 'Q', 'S'),
|
||||||
|
0,
|
||||||
|
RTEMS_LOCAL | RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE,
|
||||||
|
0,
|
||||||
|
&sema_id
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc = rtems_task_create(
|
||||||
|
rtems_build_name('I', 'R', 'Q', 'S'),
|
||||||
|
priority,
|
||||||
|
stack_size,
|
||||||
|
modes,
|
||||||
|
attributes,
|
||||||
|
&task_id
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
rtems_semaphore_delete(sema_id);
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize global data (this must be done before the task starts) */
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
if (bsp_interrupt_server_semaphore == RTEMS_ID_NONE) {
|
||||||
|
bsp_interrupt_server_semaphore = sema_id;
|
||||||
|
sc = RTEMS_SUCCESSFUL;
|
||||||
|
} else {
|
||||||
|
sc = RTEMS_INCORRECT_STATE;
|
||||||
|
}
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
rtems_semaphore_delete(sema_id);
|
||||||
|
rtems_task_delete(task_id);
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc = rtems_task_start(
|
||||||
|
task_id,
|
||||||
|
bsp_interrupt_server_task,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
/* In this case we could also panic */
|
||||||
|
bsp_interrupt_server_semaphore = RTEMS_ID_NONE;
|
||||||
|
rtems_semaphore_delete(sema_id);
|
||||||
|
rtems_task_delete(task_id);
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
@@ -3,20 +3,20 @@
|
|||||||
*
|
*
|
||||||
* @ingroup bsp_interrupt
|
* @ingroup bsp_interrupt
|
||||||
*
|
*
|
||||||
* @brief Source file for generic BSP interrupt shell code.
|
* @brief Generic BSP interrupt shell implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2009
|
||||||
* Embedded Brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Obere Lagerstr. 30
|
||||||
* D-82178 Puchheim
|
* D-82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.com/license/LICENSE.
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -25,16 +25,13 @@
|
|||||||
|
|
||||||
#include <bsp/irq-info.h>
|
#include <bsp/irq-info.h>
|
||||||
|
|
||||||
static int bsp_interrupt_shell_main( int argc, char **argv)
|
static int bsp_interrupt_shell_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bsp_interrupt_report_with_plugin( stdout, (rtems_printk_plugin_t) fprintf);
|
bsp_interrupt_report_with_plugin(stdout, (rtems_printk_plugin_t) fprintf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Shell command entry for interrupt information.
|
|
||||||
*/
|
|
||||||
struct rtems_shell_cmd_tt bsp_interrupt_shell_command = {
|
struct rtems_shell_cmd_tt bsp_interrupt_shell_command = {
|
||||||
.name = "irq",
|
.name = "irq",
|
||||||
.usage = "Prints interrupt information",
|
.usage = "Prints interrupt information",
|
||||||
|
|||||||
@@ -30,21 +30,21 @@ static Heap_Control bsp_stack_heap = {
|
|||||||
.page_size = BSP_STACK_MAGIC
|
.page_size = BSP_STACK_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
void bsp_stack_initialize(void *start, intptr_t size)
|
void bsp_stack_initialize(void *begin, uintptr_t size)
|
||||||
{
|
{
|
||||||
bsp_stack_heap.begin = start;
|
bsp_stack_heap.area_begin = (uintptr_t) begin;
|
||||||
bsp_stack_heap.end = (void *) size;
|
bsp_stack_heap.area_end = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *bsp_stack_allocate(uint32_t size)
|
void *bsp_stack_allocate(size_t size)
|
||||||
{
|
{
|
||||||
void *stack = NULL;
|
void *stack = NULL;
|
||||||
|
|
||||||
if (bsp_stack_heap.page_size == BSP_STACK_MAGIC) {
|
if (bsp_stack_heap.page_size == BSP_STACK_MAGIC) {
|
||||||
uint32_t rv = _Heap_Initialize(
|
uintptr_t rv = _Heap_Initialize(
|
||||||
&bsp_stack_heap,
|
&bsp_stack_heap,
|
||||||
bsp_stack_heap.begin,
|
(void *) bsp_stack_heap.area_begin,
|
||||||
(intptr_t) bsp_stack_heap.end,
|
bsp_stack_heap.area_end,
|
||||||
CPU_STACK_ALIGNMENT
|
CPU_STACK_ALIGNMENT
|
||||||
);
|
);
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
@@ -52,7 +52,7 @@ void *bsp_stack_allocate(uint32_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stack = _Heap_Allocate(&bsp_stack_heap, (intptr_t) size);
|
stack = _Heap_Allocate(&bsp_stack_heap, size);
|
||||||
|
|
||||||
if (stack == NULL) {
|
if (stack == NULL) {
|
||||||
stack = _Workspace_Allocate(size);
|
stack = _Workspace_Allocate(size);
|
||||||
|
|||||||
Reference in New Issue
Block a user