summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2010-04-30 11:27:01 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2010-04-30 11:27:01 +0000
commit11d6263b83d009b199dad5995a0b0c5aedde44b2 (patch)
tree1e6977420defba0f905742949f12a628248a3e58 /c
parent2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff)
downloadrtems-11d6263b83d009b199dad5995a0b0c5aedde44b2.tar.bz2
2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de>
* include/irq-config.h: Removed file. * include/irq.h: New file (renamed from 'include/irq-config.h'). * include/irq-generic.h, src/irq-info.c: Include <bsp/irq.h> instead of <bsp/irq-config.h>. * src/irq-server.c: Use events instead of semaphore. Added error counter for multiple chain appends. Added error counter to detect erroneous interrupt events.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/shared/ChangeLog10
-rw-r--r--c/src/lib/libbsp/shared/include/irq-generic.h46
-rw-r--r--c/src/lib/libbsp/shared/include/irq.h (renamed from c/src/lib/libbsp/shared/include/irq-config.h)2
-rw-r--r--c/src/lib/libbsp/shared/src/irq-info.c5
-rw-r--r--c/src/lib/libbsp/shared/src/irq-server.c116
5 files changed, 87 insertions, 92 deletions
diff --git a/c/src/lib/libbsp/shared/ChangeLog b/c/src/lib/libbsp/shared/ChangeLog
index 6c0f8adcc5..011cf2e866 100644
--- a/c/src/lib/libbsp/shared/ChangeLog
+++ b/c/src/lib/libbsp/shared/ChangeLog
@@ -1,5 +1,15 @@
2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de>
+ * include/irq-config.h: Removed file.
+ * include/irq.h: New file (renamed from 'include/irq-config.h').
+ * include/irq-generic.h, src/irq-info.c: Include <bsp/irq.h> instead
+ of <bsp/irq-config.h>.
+ * src/irq-server.c: Use events instead of semaphore. Added error
+ counter for multiple chain appends. Added error counter to detect
+ erroneous interrupt events.
+
+2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
* include/bootcard.h: Documentation.
2010-04-28 Joel Sherrill <joel.sherrilL@OARcorp.com>
diff --git a/c/src/lib/libbsp/shared/include/irq-generic.h b/c/src/lib/libbsp/shared/include/irq-generic.h
index e35b57a366..181bc58e2c 100644
--- a/c/src/lib/libbsp/shared/include/irq-generic.h
+++ b/c/src/lib/libbsp/shared/include/irq-generic.h
@@ -9,7 +9,7 @@
/*
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
*
- * Copyright (c) 2008, 2009
+ * Copyright (c) 2008, 2009, 2010
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
@@ -28,7 +28,7 @@
#include <rtems/irq-extension.h>
-#include <bsp/irq-config.h>
+#include <bsp/irq.h>
#ifdef __cplusplus
extern "C" {
@@ -86,30 +86,30 @@ static inline rtems_vector_number bsp_interrupt_handler_index(
*
* The BSP interrupt support manages a sequence of interrupt vector numbers
* ranging from @ref BSP_INTERRUPT_VECTOR_MIN to @ref BSP_INTERRUPT_VECTOR_MAX
- * including the end points. It provides methods to @ref
- * bsp_interrupt_handler_install() "install", @ref
- * bsp_interrupt_handler_remove() "remove" and @ref
- * bsp_interrupt_handler_dispatch() "dispatch" interrupt handlers for each
+ * including the end points. It provides methods to
+ * @ref bsp_interrupt_handler_install() "install",
+ * @ref bsp_interrupt_handler_remove() "remove" and
+ * @ref bsp_interrupt_handler_dispatch() "dispatch" interrupt handlers for each
* vector number. It implements parts of the RTEMS interrupt manager.
*
* The entry points to a list of interrupt handlers are stored in a table
* (= handler table).
*
- * You have to configure the BSP interrupt support in the bsp/irq-config.h file
- * for each BSP. For a minimum configuration you have to provide @ref
- * BSP_INTERRUPT_VECTOR_MIN and @ref BSP_INTERRUPT_VECTOR_MAX.
+ * You have to configure the BSP interrupt support in the <bsp/irq.h> file
+ * for each BSP. For a minimum configuration you have to provide
+ * @ref BSP_INTERRUPT_VECTOR_MIN and @ref BSP_INTERRUPT_VECTOR_MAX.
*
- * For boards with small memory requirements you can define @ref
- * BSP_INTERRUPT_USE_INDEX_TABLE. With an enabled index table the handler
+ * For boards with small memory requirements you can define
+ * @ref BSP_INTERRUPT_USE_INDEX_TABLE. With an enabled index table the handler
* table will be accessed via a small index table. You can define the size of
* the handler table with @ref BSP_INTERRUPT_HANDLER_TABLE_SIZE. You must
- * provide a data type for the index table (@ref
- * bsp_interrupt_handler_index_type). It must be an integer type big enough to
- * index the complete handler table.
+ * provide a data type for the index table
+ * (@ref bsp_interrupt_handler_index_type). It must be an integer type big
+ * enough to index the complete handler table.
*
- * Normally new list entries are allocated from the heap. You may define @ref
- * BSP_INTERRUPT_NO_HEAP_USAGE, if you do not want to use the heap. For this
- * option you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as well.
+ * Normally new list entries are allocated from the heap. You may define
+ * @ref BSP_INTERRUPT_NO_HEAP_USAGE, if you do not want to use the heap. For
+ * this option you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as well.
*
* You have to provide some special routines in your BSP (follow the links for
* the details):
@@ -182,9 +182,9 @@ rtems_status_code bsp_interrupt_facility_initialize(void);
*
* This function shall enable the vector at the corresponding facility (in most
* cases the interrupt controller). It will be called then the first handler
- * is installed for the vector in bsp_interrupt_handler_install(). For a
- * vector out of range this function shall do nothing except returning
- * RTEMS_SUCCESSFUL.
+ * is installed for the vector in bsp_interrupt_handler_install(). It is
+ * guaranteed that the vector number is within the BSP_INTERRUPT_VECTOR_MIN and
+ * BSP_INTERRUPT_VECTOR_MAX range.
*
* @note You must not install or remove an interrupt handler in this function.
* This may result in a deadlock.
@@ -198,9 +198,9 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector);
*
* This function shall disable the vector at the corresponding facility (in
* most cases the interrupt controller). It will be called then the last
- * handler is removed for the vector in bsp_interrupt_handler_remove(). For a
- * vector out of range this function shall do nothing except returning
- * RTEMS_SUCCESSFUL.
+ * handler is removed for the vector in bsp_interrupt_handler_remove(). It is
+ * guaranteed that the vector number is within the BSP_INTERRUPT_VECTOR_MIN and
+ * BSP_INTERRUPT_VECTOR_MAX range.
*
* @note You must not install or remove an interrupt handler in this function.
* This may result in a deadlock.
diff --git a/c/src/lib/libbsp/shared/include/irq-config.h b/c/src/lib/libbsp/shared/include/irq.h
index ff3136e795..ae57bd1c54 100644
--- a/c/src/lib/libbsp/shared/include/irq-config.h
+++ b/c/src/lib/libbsp/shared/include/irq.h
@@ -9,7 +9,7 @@
/*
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
*
- * Copyright (c) 2008, 2009
+ * Copyright (c) 2008, 2009, 2010
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
diff --git a/c/src/lib/libbsp/shared/src/irq-info.c b/c/src/lib/libbsp/shared/src/irq-info.c
index 474784752d..5e68e5efd0 100644
--- a/c/src/lib/libbsp/shared/src/irq-info.c
+++ b/c/src/lib/libbsp/shared/src/irq-info.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2008, 2009
+ * Copyright (c) 2008, 2009, 2010
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
@@ -21,11 +21,8 @@
#include <inttypes.h>
-#include <rtems/irq.h>
-
#include <bsp/irq-generic.h>
#include <bsp/irq-info.h>
-#include <bsp/irq-config.h>
typedef struct {
void *context;
diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c
index 933c15d55f..0026f0f5a6 100644
--- a/c/src/lib/libbsp/shared/src/irq-server.c
+++ b/c/src/lib/libbsp/shared/src/irq-server.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2009
+ * Copyright (c) 2009, 2010
* embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
@@ -21,68 +21,89 @@
#include <stdlib.h>
+#include <rtems.h>
+#include <rtems/chain.h>
+
#include <bsp/irq-generic.h>
+#define BSP_INTERRUPT_EVENT RTEMS_EVENT_13
+
typedef struct bsp_interrupt_server_entry {
+ rtems_chain_node node;
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;
+static rtems_id bsp_interrupt_server_id = RTEMS_ID_NONE;
-/* LIFO list head */
-static bsp_interrupt_server_entry *volatile
-bsp_interrupt_server_list_head = NULL;
+static RTEMS_CHAIN_DEFINE_EMPTY(bsp_interrupt_server_chain);
static rtems_status_code bsp_interrupt_server_is_initialized(void)
{
- if (bsp_interrupt_server_semaphore != RTEMS_ID_NONE) {
+ if (bsp_interrupt_server_id != RTEMS_ID_NONE) {
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_INCORRECT_STATE;
}
}
+static unsigned bsp_interrupt_server_errors;
+
static void bsp_interrupt_server_trigger(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 */
+ if (e->node.next == NULL) {
+ rtems_chain_append(&bsp_interrupt_server_chain, &e->node);
+ } else {
+ ++bsp_interrupt_server_errors;
+ }
+
+ rtems_event_send(bsp_interrupt_server_id, BSP_INTERRUPT_EVENT);
+}
+
+static bsp_interrupt_server_entry *bsp_interrupt_server_get_entry(void)
+{
+ rtems_interrupt_level level;
+ bsp_interrupt_server_entry *e;
+
rtems_interrupt_disable(level);
- e->next = bsp_interrupt_server_list_head;
- bsp_interrupt_server_list_head = e;
+ e = (bsp_interrupt_server_entry *)
+ rtems_chain_get_unprotected(&bsp_interrupt_server_chain);
+ if (e != NULL) {
+ e->node.next = NULL;
+ }
rtems_interrupt_enable(level);
- rtems_semaphore_release(bsp_interrupt_server_semaphore);
+ return e;
}
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);
+ rtems_event_set events = 0;
+ bsp_interrupt_server_entry *e = NULL;
+
+ sc = rtems_event_receive(
+ BSP_INTERRUPT_EVENT,
+ RTEMS_EVENT_ALL | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
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->arg);
+ while ((e = bsp_interrupt_server_get_entry()) != NULL) {
+ (*e->handler)(e->arg);
- bsp_interrupt_vector_enable(e->vector);
+ bsp_interrupt_vector_enable(e->vector);
+ }
}
rtems_task_delete(RTEMS_SELF);
@@ -137,7 +158,7 @@ rtems_status_code rtems_interrupt_server_handler_install(
return RTEMS_NOT_IMPLEMENTED;
}
- e = malloc(sizeof(bsp_interrupt_server_entry));
+ e = calloc(1, sizeof(*e));
if (e == NULL) {
return RTEMS_NO_MEMORY;
}
@@ -220,67 +241,34 @@ rtems_status_code rtems_interrupt_server_initialize(
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_id sema_id = RTEMS_ID_NONE;
- rtems_id task_id = RTEMS_ID_NONE;
- rtems_interrupt_level level;
if (server != NULL) {
return RTEMS_NOT_IMPLEMENTED;
}
- 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
+ &bsp_interrupt_server_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;
+ return RTEMS_TOO_MANY;
}
sc = rtems_task_start(
- task_id,
+ bsp_interrupt_server_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);
+ rtems_task_delete(bsp_interrupt_server_id);
+ bsp_interrupt_server_id = RTEMS_ID_NONE;
- return sc;
+ return RTEMS_TOO_MANY;
}
return RTEMS_SUCCESSFUL;