summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-04-16 08:56:41 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-04-16 08:56:41 +0200
commit9502079586fa3034865bdcff91cf4e5f881762f0 (patch)
tree93a289c651acfcb522fcd06e01c62f661e5bf26a
parentFilesystem: Remove NULL pointer check (diff)
parentPR1908: QoS library for CBS scheduler (diff)
downloadrtems-9502079586fa3034865bdcff91cf4e5f881762f0.tar.bz2
Merge branch 'upstream'
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/Makefile.am1
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/configure.ac4
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/console/usart.c43
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/include/io.h73
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/include/rcc.h6
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c6
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/startup/io.c63
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/startup/rcc.c17
-rw-r--r--c/src/lib/libbsp/arm/stm32f4/startup/start-config-io.c44
-rw-r--r--cpukit/Makefile.am1
-rw-r--r--cpukit/configure.ac1
-rw-r--r--cpukit/libqos/Makefile.am12
-rw-r--r--cpukit/libqos/qreslib.h81
-rw-r--r--cpukit/libqos/qreslib.inl214
-rw-r--r--doc/ada_user/Makefile.am2
-rw-r--r--doc/ada_user/ada_user.texi2
-rw-r--r--doc/user/Makefile.am9
-rw-r--r--doc/user/c_user.texi2
-rw-r--r--doc/user/cbs.t646
-rw-r--r--doc/user/dirstat.texi2
-rw-r--r--testsuites/sptests/Makefile.am2
-rw-r--r--testsuites/sptests/configure.ac1
-rw-r--r--testsuites/sptests/spqreslib/Makefile.am28
-rw-r--r--testsuites/sptests/spqreslib/init.c227
-rw-r--r--testsuites/sptests/spqreslib/spqreslib.doc22
-rw-r--r--testsuites/sptests/spqreslib/spqreslib.scn30
-rw-r--r--testsuites/sptests/spqreslib/system.h62
-rw-r--r--testsuites/sptests/spqreslib/task_periodic.c138
28 files changed, 1651 insertions, 88 deletions
diff --git a/c/src/lib/libbsp/arm/stm32f4/Makefile.am b/c/src/lib/libbsp/arm/stm32f4/Makefile.am
index 88445fe3a4..a54d974a05 100644
--- a/c/src/lib/libbsp/arm/stm32f4/Makefile.am
+++ b/c/src/lib/libbsp/arm/stm32f4/Makefile.am
@@ -79,6 +79,7 @@ libbsp_a_SOURCES += startup/bspstarthook.c
libbsp_a_SOURCES += startup/bspreset.c
libbsp_a_SOURCES += startup/io.c
libbsp_a_SOURCES += startup/rcc.c
+libbsp_a_SOURCES += startup/start-config-io.c
# IRQ
libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c
diff --git a/c/src/lib/libbsp/arm/stm32f4/configure.ac b/c/src/lib/libbsp/arm/stm32f4/configure.ac
index 1e0e7db983..fc1bc9649f 100644
--- a/c/src/lib/libbsp/arm/stm32f4/configure.ac
+++ b/c/src/lib/libbsp/arm/stm32f4/configure.ac
@@ -35,13 +35,13 @@ RTEMS_BSPOPTS_HELP([STM32F4_PCLK2],[PCLK2 frequency in Hz])
RTEMS_BSPOPTS_SET([STM32F4_USART_BAUD],[*],[115200])
RTEMS_BSPOPTS_HELP([STM32F4_USART_BAUD],[baud for USARTs])
-RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_1],[*],[1])
+RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_1],[*],[])
RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_1],[enable USART 1])
RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_2],[*],[])
RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_2],[enable USART 2])
-RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_3],[*],[])
+RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_3],[*],[1])
RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_3],[enable USART 3])
RTEMS_BSPOPTS_SET([STM32F4_ENABLE_UART_4],[*],[])
diff --git a/c/src/lib/libbsp/arm/stm32f4/console/usart.c b/c/src/lib/libbsp/arm/stm32f4/console/usart.c
index f18dd7124f..40280ad937 100644
--- a/c/src/lib/libbsp/arm/stm32f4/console/usart.c
+++ b/c/src/lib/libbsp/arm/stm32f4/console/usart.c
@@ -118,48 +118,6 @@ static uint32_t usart_get_bbr(
| STM32F4_USART_BBR_DIV_FRACTION(div_fraction);
}
-#define USART_CFG(port, idx, altfunc) \
- { \
- .pin = STM32F4_GPIO_PIN(port, idx), \
- .mode = STM32F4_GPIO_MODE_AF, \
- .otype = STM32F4_GPIO_OTYPE_PUSH_PULL, \
- .ospeed = STM32F4_GPIO_OSPEED_2_MHZ, \
- .pupd = STM32F4_GPIO_PULL_UP, \
- .af = altfunc \
- }
-
-static const stm32f4_gpio_config usart_gpio_config [] [2] = {
- {
- USART_CFG(0, 9, STM32F4_GPIO_AF_USART1),
- USART_CFG(0, 10, STM32F4_GPIO_AF_USART1)
- }, {
- USART_CFG(0, 2, STM32F4_GPIO_AF_USART2),
- USART_CFG(0, 3, STM32F4_GPIO_AF_USART2)
- }, {
- USART_CFG(3, 8, STM32F4_GPIO_AF_USART3),
- USART_CFG(3, 9, STM32F4_GPIO_AF_USART3)
- }, {
- USART_CFG(0, 1, STM32F4_GPIO_AF_UART4),
- USART_CFG(0, 2, STM32F4_GPIO_AF_UART4)
- }, {
- USART_CFG(2, 11, STM32F4_GPIO_AF_UART5),
- USART_CFG(2, 12, STM32F4_GPIO_AF_UART5)
- }, {
- USART_CFG(2, 6, STM32F4_GPIO_AF_USART6),
- USART_CFG(2, 7, STM32F4_GPIO_AF_USART6)
- }
-};
-
-static void usart_set_gpio_config(const console_tbl *ct)
-{
- const stm32f4_gpio_config *config = usart_gpio_config [ct->ulCtrlPort2];
-
- stm32f4_rcc_set_gpio_clock(config [0].pin, true);
- stm32f4_gpio_set_config(&config [0]);
- stm32f4_rcc_set_gpio_clock(config [1].pin, true);
- stm32f4_gpio_set_config(&config [1]);
-}
-
static void usart_initialize(int minor)
{
const console_tbl *ct = Console_Port_Tbl [minor];
@@ -169,7 +127,6 @@ static void usart_initialize(int minor)
stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct);
stm32f4_rcc_set_clock(rcc_index, true);
- usart_set_gpio_config(ct);
usart->cr1 = 0;
usart->cr2 = 0;
diff --git a/c/src/lib/libbsp/arm/stm32f4/include/io.h b/c/src/lib/libbsp/arm/stm32f4/include/io.h
index 539bba567e..032664c48a 100644
--- a/c/src/lib/libbsp/arm/stm32f4/include/io.h
+++ b/c/src/lib/libbsp/arm/stm32f4/include/io.h
@@ -92,21 +92,80 @@ typedef enum {
#define STM32F4_GPIO_INDEX_OF_PIN(pin) ((pin) & 0xf)
-typedef struct {
- uint32_t pin : 8;
- uint32_t mode : 2;
- uint32_t otype : 1;
- uint32_t ospeed : 2;
- uint32_t pupd : 2;
- uint32_t af : 4;
+typedef union {
+ struct {
+ uint32_t pin_first : 8;
+ uint32_t pin_last : 8;
+ uint32_t mode : 2;
+ uint32_t otype : 1;
+ uint32_t ospeed : 2;
+ uint32_t pupd : 2;
+ uint32_t output : 1;
+ uint32_t af : 4;
+ uint32_t reserved : 4;
+ } fields;
+
+ uint32_t value;
} stm32f4_gpio_config;
+extern const stm32f4_gpio_config stm32f4_start_config_gpio [];
+
+void stm32f4_gpio_set_clock(int pin, bool set);
+
void stm32f4_gpio_set_config(const stm32f4_gpio_config *config);
+#define STM32F4_GPIO_CONFIG_TERMINAL \
+ { { 0xff, 0xff, 0x3, 0x1, 0x3, 0x3, 0x1, 0xf, 0xf } }
+
+/**
+ * @brief Sets the GPIO configuration of an array terminated by
+ * STM32F4_GPIO_CONFIG_TERMINAL.
+ */
+void stm32f4_gpio_set_config_array(const stm32f4_gpio_config *configs);
+
void stm32f4_gpio_set_output(int pin, bool set);
bool stm32f4_gpio_get_input(int pin);
+#define STM32F4_PIN_USART(port, idx, altfunc) \
+ { \
+ { \
+ .pin_first = STM32F4_GPIO_PIN(port, idx), \
+ .pin_last = STM32F4_GPIO_PIN(port, idx), \
+ .mode = STM32F4_GPIO_MODE_AF, \
+ .otype = STM32F4_GPIO_OTYPE_PUSH_PULL, \
+ .ospeed = STM32F4_GPIO_OSPEED_2_MHZ, \
+ .pupd = STM32F4_GPIO_PULL_UP, \
+ .af = altfunc \
+ } \
+ }
+
+#define STM32F4_PIN_USART1_TX_PA9 STM32F4_PIN_USART(0, 9, STM32F4_GPIO_AF_USART1)
+#define STM32F4_PIN_USART1_TX_PB6 STM32F4_PIN_USART(1, 6, STM32F4_GPIO_AF_USART1)
+#define STM32F4_PIN_USART1_RX_PA10 STM32F4_PIN_USART(0, 10, STM32F4_GPIO_AF_USART1)
+#define STM32F4_PIN_USART1_RX_PB7 STM32F4_PIN_USART(1, 7, STM32F4_GPIO_AF_USART1)
+
+#define STM32F4_PIN_USART2_TX_PA2 STM32F4_PIN_USART(0, 2, STM32F4_GPIO_AF_USART2)
+#define STM32F4_PIN_USART2_TX_PD5 STM32F4_PIN_USART(3, 5, STM32F4_GPIO_AF_USART2)
+#define STM32F4_PIN_USART2_RX_PA3 STM32F4_PIN_USART(0, 3, STM32F4_GPIO_AF_USART2)
+#define STM32F4_PIN_USART2_RX_PD6 STM32F4_PIN_USART(3, 6, STM32F4_GPIO_AF_USART2)
+
+#define STM32F4_PIN_USART3_TX_PC10 STM32F4_PIN_USART(2, 10, STM32F4_GPIO_AF_USART3)
+#define STM32F4_PIN_USART3_TX_PD8 STM32F4_PIN_USART(3, 8, STM32F4_GPIO_AF_USART3)
+#define STM32F4_PIN_USART3_RX_PC11 STM32F4_PIN_USART(2, 11, STM32F4_GPIO_AF_USART3)
+#define STM32F4_PIN_USART3_RX_PD9 STM32F4_PIN_USART(3, 9, STM32F4_GPIO_AF_USART3)
+
+#define STM32F4_PIN_UART4_TX_PA0 STM32F4_PIN_USART(0, 0, STM32F4_GPIO_AF_UART4)
+#define STM32F4_PIN_UART4_TX_PC10 STM32F4_PIN_USART(2, 10, STM32F4_GPIO_AF_UART4)
+#define STM32F4_PIN_UART4_RX_PA1 STM32F4_PIN_USART(0, 1, STM32F4_GPIO_AF_UART4)
+#define STM32F4_PIN_UART4_RX_PC11 STM32F4_PIN_USART(2, 11, STM32F4_GPIO_AF_UART4)
+
+#define STM32F4_PIN_UART5_TX_PC12 STM32F4_PIN_USART(2, 12, STM32F4_GPIO_AF_UART5)
+#define STM32F4_PIN_UART5_RX_PD2 STM32F4_PIN_USART(3, 2, STM32F4_GPIO_AF_UART5)
+
+#define STM32F4_PIN_USART6_TX_PC6 STM32F4_PIN_USART(2, 6, STM32F4_GPIO_AF_USART6)
+#define STM32F4_PIN_USART6_RX_PC7 STM32F4_PIN_USART(2, 7, STM32F4_GPIO_AF_USART6)
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/c/src/lib/libbsp/arm/stm32f4/include/rcc.h b/c/src/lib/libbsp/arm/stm32f4/include/rcc.h
index e2e4d13c79..7d49527b83 100644
--- a/c/src/lib/libbsp/arm/stm32f4/include/rcc.h
+++ b/c/src/lib/libbsp/arm/stm32f4/include/rcc.h
@@ -88,11 +88,11 @@ typedef enum {
STM32F4_RCC_TIM1 = STM32F4_RCC_INDEX(5, 0),
} stm32f4_rcc_index;
-void stm32f4_rcc_reset(stm32f4_rcc_index index, bool set);
+void stm32f4_rcc_reset(stm32f4_rcc_index index);
-void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set);
+void stm32f4_rcc_set_reset(stm32f4_rcc_index index, bool set);
-void stm32f4_rcc_set_gpio_clock(int pin, bool set);
+void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set);
void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set);
diff --git a/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c b/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c
index 219c09365c..fb1d5b1f86 100644
--- a/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c
+++ b/c/src/lib/libbsp/arm/stm32f4/startup/bspstart.c
@@ -13,13 +13,15 @@
*/
#include <bsp.h>
+#include <bsp/io.h>
+#include <bsp/irq.h>
#include <bsp/bootcard.h>
#include <bsp/irq-generic.h>
-#include <bsp/irq.h>
-#include <bsp/linker-symbols.h>
void bsp_start(void)
{
+ stm32f4_gpio_set_config_array(&stm32f4_start_config_gpio [0]);
+
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
_CPU_Fatal_halt(0xe);
}
diff --git a/c/src/lib/libbsp/arm/stm32f4/startup/io.c b/c/src/lib/libbsp/arm/stm32f4/startup/io.c
index 1bba73cd37..5ecbabe394 100644
--- a/c/src/lib/libbsp/arm/stm32f4/startup/io.c
+++ b/c/src/lib/libbsp/arm/stm32f4/startup/io.c
@@ -13,9 +13,20 @@
*/
#include <bsp/io.h>
+#include <bsp/rcc.h>
#include <rtems.h>
+RTEMS_STATIC_ASSERT(sizeof(stm32f4_gpio_config) == 4, size_of_config);
+
+void stm32f4_gpio_set_clock(int pin, bool set)
+{
+ int port = STM32F4_GPIO_PORT_OF_PIN(pin);
+ stm32f4_rcc_index index = STM32F4_RCC_GPIOA + port;
+
+ stm32f4_rcc_set_clock(index, set);
+}
+
static void clear_and_set(
volatile uint32_t *reg,
unsigned index,
@@ -23,8 +34,7 @@ static void clear_and_set(
uint32_t set
)
{
- uint32_t one = 1;
- uint32_t mask = (one << width) - one;
+ uint32_t mask = (1U << width) - 1U;
unsigned shift = width * index;
uint32_t val = *reg;
@@ -34,34 +44,56 @@ static void clear_and_set(
*reg = val;
}
-void stm32f4_gpio_set_config(const stm32f4_gpio_config *config)
+static void set_config(unsigned pin, const stm32f4_gpio_config *config)
{
- unsigned pin = config->pin;
unsigned port = STM32F4_GPIO_PORT_OF_PIN(pin);
volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
unsigned index = STM32F4_GPIO_INDEX_OF_PIN(pin);
- unsigned af_reg = index >> 8;
- unsigned af_index = index & 0x3;
+ unsigned af_reg = index >> 3;
+ unsigned af_index = index & 0x7;
+ int set_or_clear_offset = config->fields.output ? 0 : 16;
rtems_interrupt_level level;
rtems_interrupt_disable(level);
- clear_and_set(&gpio->moder, index, 2, config->mode);
- clear_and_set(&gpio->afr [af_reg], af_index, 4, config->af);
- clear_and_set(&gpio->pupdr, index, 2, config->pupd);
- clear_and_set(&gpio->otyper, index, 1, config->otype);
- clear_and_set(&gpio->ospeedr, index, 2, config->ospeed);
+ gpio->bsrr = 1U << (index + set_or_clear_offset);
+ clear_and_set(&gpio->pupdr, index, 2, config->fields.pupd);
+ clear_and_set(&gpio->otyper, index, 1, config->fields.otype);
+ clear_and_set(&gpio->ospeedr, index, 2, config->fields.ospeed);
+ clear_and_set(&gpio->afr [af_reg], af_index, 4, config->fields.af);
+ clear_and_set(&gpio->moder, index, 2, config->fields.mode);
rtems_interrupt_enable(level);
}
+void stm32f4_gpio_set_config(const stm32f4_gpio_config *config)
+{
+ int current = config->fields.pin_first;
+ int last = config->fields.pin_last;
+
+ while (current <= last) {
+ stm32f4_gpio_set_clock(current, true);
+ set_config(current, config);
+ ++current;
+ }
+}
+
+void stm32f4_gpio_set_config_array(const stm32f4_gpio_config *configs)
+{
+ stm32f4_gpio_config terminal = STM32F4_GPIO_CONFIG_TERMINAL;
+
+ while (configs->value != terminal.value) {
+ stm32f4_gpio_set_config(configs);
+ ++configs;
+ }
+}
+
void stm32f4_gpio_set_output(int pin, bool set)
{
int port = STM32F4_GPIO_PORT_OF_PIN(pin);
volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
int index = STM32F4_GPIO_INDEX_OF_PIN(pin);
- int offset = set ? 0 : 16;
- uint32_t one = 1;
+ int set_or_clear_offset = set ? 0 : 16;
- gpio->bsrr = one << (index + offset);
+ gpio->bsrr = 1U << (index + set_or_clear_offset);
}
bool stm32f4_gpio_get_input(int pin)
@@ -69,7 +101,6 @@ bool stm32f4_gpio_get_input(int pin)
int port = STM32F4_GPIO_PORT_OF_PIN(pin);
volatile stm32f4_gpio *gpio = STM32F4_GPIO(port);
int index = STM32F4_GPIO_INDEX_OF_PIN(pin);
- uint32_t one = 1;
- return (gpio->idr & (one << index)) != 0;
+ return (gpio->idr & (1U << index)) != 0;
}
diff --git a/c/src/lib/libbsp/arm/stm32f4/startup/rcc.c b/c/src/lib/libbsp/arm/stm32f4/startup/rcc.c
index aa3022cef7..b2cbadff0f 100644
--- a/c/src/lib/libbsp/arm/stm32f4/startup/rcc.c
+++ b/c/src/lib/libbsp/arm/stm32f4/startup/rcc.c
@@ -13,7 +13,6 @@
*/
#include <bsp/rcc.h>
-#include <bsp/io.h>
#include <rtems.h>
@@ -40,7 +39,13 @@ static void rcc_set(
rtems_interrupt_enable(level);
}
-void stm32f4_rcc_reset(stm32f4_rcc_index index, bool set)
+void stm32f4_rcc_reset(stm32f4_rcc_index index)
+{
+ stm32f4_rcc_set_reset(index, true);
+ stm32f4_rcc_set_reset(index, false);
+}
+
+void stm32f4_rcc_set_reset(stm32f4_rcc_index index, bool set)
{
volatile stm32f4_rcc *rcc = STM32F4_RCC;
@@ -54,14 +59,6 @@ void stm32f4_rcc_set_clock(stm32f4_rcc_index index, bool set)
rcc_set(index, set, &rcc->ahbenr [0]);
}
-void stm32f4_rcc_set_gpio_clock(int pin, bool set)
-{
- int port = STM32F4_GPIO_PORT_OF_PIN(pin);
- stm32f4_rcc_index index = STM32F4_RCC_GPIOA + port;
-
- stm32f4_rcc_set_clock(index, set);
-}
-
void stm32f4_rcc_set_low_power_clock(stm32f4_rcc_index index, bool set)
{
volatile stm32f4_rcc *rcc = STM32F4_RCC;
diff --git a/c/src/lib/libbsp/arm/stm32f4/startup/start-config-io.c b/c/src/lib/libbsp/arm/stm32f4/startup/start-config-io.c
new file mode 100644
index 0000000000..2cd542ccda
--- /dev/null
+++ b/c/src/lib/libbsp/arm/stm32f4/startup/start-config-io.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Sebastian Huber. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 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 <bsp/io.h>
+#include <bsp.h>
+
+const stm32f4_gpio_config stm32f4_start_config_gpio [] = {
+ #ifdef STM32F4_ENABLE_USART_1
+ STM32F4_PIN_USART1_TX_PA9,
+ STM32F4_PIN_USART1_RX_PA10,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_2
+ STM32F4_PIN_USART2_TX_PA2,
+ STM32F4_PIN_USART2_RX_PA3,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_3
+ STM32F4_PIN_USART3_TX_PD8,
+ STM32F4_PIN_USART3_RX_PD9,
+ #endif
+ #ifdef STM32F4_ENABLE_UART_4
+ STM32F4_PIN_UART4_TX_PA0,
+ STM32F4_PIN_UART4_RX_PA1,
+ #endif
+ #ifdef STM32F4_ENABLE_UART_5
+ STM32F4_PIN_UART5_TX_PC12,
+ STM32F4_PIN_UART5_RX_PD2,
+ #endif
+ #ifdef STM32F4_ENABLE_USART_6
+ STM32F4_PIN_USART6_TX_PC6,
+ STM32F4_PIN_USART6_RX_PC7,
+ #endif
+ STM32F4_GPIO_CONFIG_TERMINAL
+};
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 1cb9dc7b93..9df5533735 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -15,6 +15,7 @@ SUBDIRS += libi2c
SUBDIRS += libmisc
SUBDIRS += libmd
SUBDIRS += libgnat
+SUBDIRS += libqos
SUBDIRS += wrapup
SUBDIRS += zlib
diff --git a/cpukit/configure.ac b/cpukit/configure.ac
index 24bcdc2f20..30443488db 100644
--- a/cpukit/configure.ac
+++ b/cpukit/configure.ac
@@ -384,6 +384,7 @@ librpc/Makefile
libmisc/Makefile
libi2c/Makefile
libmd/Makefile
+libqos/Makefile
zlib/Makefile
ftpd/Makefile
telnetd/Makefile
diff --git a/cpukit/libqos/Makefile.am b/cpukit/libqos/Makefile.am
new file mode 100644
index 0000000000..3223dcddd2
--- /dev/null
+++ b/cpukit/libqos/Makefile.am
@@ -0,0 +1,12 @@
+##
+## $Id$
+##
+
+include $(top_srcdir)/automake/multilib.am
+include $(top_srcdir)/automake/compile.am
+
+include_HEADERS = qreslib.h
+include_HEADERS += qreslib.inl
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/automake/local.am
diff --git a/cpukit/libqos/qreslib.h b/cpukit/libqos/qreslib.h
new file mode 100644
index 0000000000..22bbd3ee62
--- /dev/null
+++ b/cpukit/libqos/qreslib.h
@@ -0,0 +1,81 @@
+/**
+ * @file qreslib.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the QoS RES library in RTEMS.
+ *
+ * @note The library is available only together with CBS scheduler.
+ */
+
+/*
+ * Copyright (C) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef CONFIGURE_SCHEDULER_CBS
+ #error "qreslib.h available only with CONFIGURE_SCHEDULER_CBS"
+#endif
+
+#ifndef _QRESLIB_H
+#define _QRESLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rtems/score/schedulercbs.h>
+
+/** Return values. */
+typedef int qos_rv;
+
+/* Return codes. */
+#define QOS_OK SCHEDULER_CBS_OK
+#define QOS_E_GENERIC SCHEDULER_CBS_ERROR_GENERIC
+#define QOS_E_NO_MEMORY SCHEDULER_CBS_ERROR_NO_MEMORY
+#define QOS_E_INVALID_PARAM SCHEDULER_CBS_ERROR_INVALID_PARAMETER
+#define QOS_E_UNAUTHORIZED SCHEDULER_CBS_ERROR_UNAUTHORIZED
+#define QOS_E_UNIMPLEMENTED SCHEDULER_CBS_ERROR_UNIMPLEMENTED
+#define QOS_E_MISSING_COMPONENT SCHEDULER_CBS_ERROR_MISSING_COMPONENT
+#define QOS_E_INCONSISTENT_STATE SCHEDULER_CBS_ERROR_INCONSISTENT_STATE
+#define QOS_E_SYSTEM_OVERLOAD SCHEDULER_CBS_ERROR_SYSTEM_OVERLOAD
+#define QOS_E_INTERNAL_ERROR SCHEDULER_CBS_ERROR_INTERNAL_ERROR
+#define QOS_E_NOT_FOUND SCHEDULER_CBS_ERROR_NOT_FOUND
+#define QOS_E_FULL SCHEDULER_CBS_ERROR_FULL
+#define QOS_E_EMPTY SCHEDULER_CBS_ERROR_EMPTY
+#define QOS_E_NOSERVER SCHEDULER_CBS_ERROR_NOSERVER
+
+/** Server id. */
+typedef Scheduler_CBS_Server_id qres_sid_t;
+
+/** Task id. */
+typedef rtems_id tid_t;
+
+/** Time value. */
+typedef time_t qres_time_t;
+
+/** Absolute time value */
+typedef time_t qres_atime_t;
+
+/** Server parameters. */
+typedef struct {
+ /** Relative deadline of the server. */
+ uint32_t P;
+ /** Budget (computation time) of the server. */
+ uint32_t Q;
+} qres_params_t;
+
+#include <qreslib.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/libqos/qreslib.inl b/cpukit/libqos/qreslib.inl
new file mode 100644
index 0000000000..094d1e6cdd
--- /dev/null
+++ b/cpukit/libqos/qreslib.inl
@@ -0,0 +1,214 @@
+/**
+ * @file qreslib.inl
+ *
+ * This include file contains all the constants and structures associated
+ * with the QoS RES library.
+ *
+ * @note The library is available only together with CBS scheduler.
+ */
+
+/*
+ * Copyright (C) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _QRESLIB_H
+# error "Never use <qreslib.inl> directly; include <qreslib.h> instead."
+#endif
+
+#include <rtems/score/schedulercbs.h>
+
+/**
+ * @brief qres init
+ *
+ * Initializes the QoS RES library.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_init ( void )
+{
+ return _Scheduler_CBS_Initialize();
+}
+
+/**
+ * @brief qres cleanup
+ *
+ * Cleanup resources associated to the QoS RES Library.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_cleanup ( void )
+{
+ return _Scheduler_CBS_Cleanup();
+}
+
+/**
+ * @brief qres create server
+ *
+ * Create a new server with specified parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_create_server (
+ qres_params_t *params,
+ qres_sid_t *server_id
+)
+{
+ return _Scheduler_CBS_Create_server(
+ (Scheduler_CBS_Parameters *) params,
+ NULL,
+ server_id
+ );
+}
+
+/**
+ * @brief qres attach thread
+ *
+ * Attach a task to an already existing server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_attach_thread (
+ qres_sid_t server_id,
+ pid_t pid,
+ tid_t task_id
+)
+{
+ return _Scheduler_CBS_Attach_thread( server_id, task_id );
+}
+
+/**
+ * @brief qres detach thread
+ *
+ * Detach from the QoS Server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_detach_thread (
+ qres_sid_t server_id,
+ pid_t pid,
+ tid_t task_id
+)
+{
+ return _Scheduler_CBS_Detach_thread( server_id, task_id );
+}
+
+/**
+ * @brief qres destroy server
+ *
+ * Detach all tasks from a server and destroy it.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_destroy_server (
+ qres_sid_t server_id
+)
+{
+ return _Scheduler_CBS_Destroy_server( server_id );
+}
+
+/**
+ * @brief qres get server id
+ *
+ * Get a thread server id, or QOS_E_NOT_FOUND if it is not
+ * attached to any server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_sid (
+ pid_t pid,
+ tid_t task_id,
+ qres_sid_t *server_id
+)
+{
+ return _Scheduler_CBS_Get_server_id( task_id, server_id );
+}
+
+/**
+ * @brief qres get params
+ *
+ * Retrieve QoS scheduling parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_params (
+ qres_sid_t server_id,
+ qres_params_t *params
+)
+{
+ return _Scheduler_CBS_Get_parameters(
+ server_id,
+ (Scheduler_CBS_Parameters *) params
+ );
+}
+
+/**
+ * @brief qres set params
+ *
+ * Change QoS scheduling parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_set_params (
+ qres_sid_t server_id,
+ qres_params_t *params
+)
+{
+ return _Scheduler_CBS_Set_parameters(
+ server_id,
+ (Scheduler_CBS_Parameters *) params
+ );
+}
+
+/**
+ * @brief qres get execution time
+ *
+ * Retrieve time info relative to the current server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_exec_time (
+ qres_sid_t server_id,
+ qres_time_t *exec_time,
+ qres_atime_t *abs_time
+)
+{
+ return _Scheduler_CBS_Get_execution_time( server_id, exec_time, abs_time );
+}
+
+/**
+ * @brief qres get current budget
+ *
+ * Retrieve remaining budget for the current server instance.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_curr_budget (
+ qres_sid_t server_id,
+ qres_time_t *current_budget
+)
+{
+ return _Scheduler_CBS_Get_remaining_budget( server_id, current_budget );
+}
+
+/**
+ * @brief qres get approved budget
+ *
+ * Retrieve the budget that has been approved for the subsequent
+ * server instances.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_appr_budget (
+ qres_sid_t server_id,
+ qres_time_t *appr_budget
+)
+{
+ return _Scheduler_CBS_Get_approved_budget( server_id, appr_budget );
+}
diff --git a/doc/ada_user/Makefile.am b/doc/ada_user/Makefile.am
index 9ba4feedae..d4b8bac599 100644
--- a/doc/ada_user/Makefile.am
+++ b/doc/ada_user/Makefile.am
@@ -27,7 +27,7 @@ COMMON_FILES += \
$(top_builddir)/user/task.texi $(top_builddir)/user/timer.texi \
$(top_builddir)/user/userext.texi $(top_builddir)/user/stackchk.texi \
$(top_builddir)/user/cpuuse.texi $(top_srcdir)/common/cpright.texi \
- $(top_builddir)/user/object.texi
+ $(top_builddir)/user/object.texi $(top_builddir)/user/cbs.texi
FILES = example.texi
diff --git a/doc/ada_user/ada_user.texi b/doc/ada_user/ada_user.texi
index 279f219922..c7073fc01f 100644
--- a/doc/ada_user/ada_user.texi
+++ b/doc/ada_user/ada_user.texi
@@ -112,6 +112,7 @@
@include user/cpuuse.texi
@include user/object.texi
@include user/chains.texi
+@include user/cbs.texi
@include user/dirstat.texi
@include example.texi
@include user/glossary.texi
@@ -149,6 +150,7 @@
* CPU Usage Statistics::
* Object Services::
* Chains::
+* Constant Bandwidth Server Scheduler API::
* Directive Status Codes::
* Example Application::
* Glossary::
diff --git a/doc/user/Makefile.am b/doc/user/Makefile.am
index af2b24dbca..de950b168c 100644
--- a/doc/user/Makefile.am
+++ b/doc/user/Makefile.am
@@ -17,7 +17,7 @@ GENERATED_FILES = overview.texi concepts.texi datatypes.texi init.texi \
task.texi intr.texi clock.texi timer.texi sem.texi msg.texi event.texi \
signal.texi part.texi region.texi dpmem.texi io.texi fatal.texi \
schedule.texi rtmon.texi barrier.texi bsp.texi userext.texi conf.texi \
- mp.texi stackchk.texi cpuuse.texi object.texi chains.texi
+ mp.texi stackchk.texi cpuuse.texi object.texi chains.texi cbs.texi
COMMON_FILES += $(top_srcdir)/common/cpright.texi
@@ -183,9 +183,14 @@ object.texi: object.t
chains.texi: chains.t
$(BMENU2) -p "Object Services OBJECT_GET_CLASS_INFORMATION - Obtain Class Information" \
-u "Top" \
+ -n "Constant Bandwidth Server Scheduler API" < $< > $@
+
+cbs.texi: cbs.t
+ $(BMENU2) -p "Chains Prepend a Node" \
+ -u "Top" \
-n "Directive Status Codes" < $< > $@
-EXTRA_DIST = bsp.t clock.t chains.t concepts.t cpuuse.t datatypes.t conf.t \
+EXTRA_DIST = bsp.t cbs.t clock.t chains.t concepts.t cpuuse.t datatypes.t conf.t \
dpmem.t event.t fatal.t init.t intr.t io.t mp.t msg.t overview.t \
part.t region.t rtmon.t sem.t schedule.t signal.t stackchk.t \
task.t timer.t userext.t $(TXT_FILES) $(PNG_FILES) $(EPS_IMAGES) \
diff --git a/doc/user/c_user.texi b/doc/user/c_user.texi
index b1bc087406..27c49b15cb 100644
--- a/doc/user/c_user.texi
+++ b/doc/user/c_user.texi
@@ -111,6 +111,7 @@
@include cpuuse.texi
@include object.texi
@include chains.texi
+@include cbs.texi
@include dirstat.texi
@include example.texi
@include glossary.texi
@@ -148,6 +149,7 @@
* CPU Usage Statistics::
* Object Services::
* Chains::
+* Constant Bandwidth Server Scheduler API::
* Directive Status Codes::
* Example Application::
* Glossary::
diff --git a/doc/user/cbs.t b/doc/user/cbs.t
new file mode 100644
index 0000000000..425885d321
--- /dev/null
+++ b/doc/user/cbs.t
@@ -0,0 +1,646 @@
+@c
+@c COPYRIGHT (c) 2011.
+@c On-Line Applications Research Corporation (OAR).
+@c All rights reserved.
+@c
+@c $Id:$
+@c
+
+@chapter Constant Bandwidth Server Scheduler API
+
+@cindex cbs
+
+@section Introduction
+
+Unlike simple schedulers, the Constant Bandwidth Server (CBS) requires
+a special API for tasks to indicate their scheduling parameters.
+The directives provided by the CBS API are:
+
+@itemize @bullet
+@item @code{@value{DIRPREFIX}cbs_initialize} - Initialize the CBS library
+@item @code{@value{DIRPREFIX}cbs_cleanup} - Cleanup the CBS library
+@item @code{@value{DIRPREFIX}cbs_create_server} - Create a new bandwidth server
+@item @code{@value{DIRPREFIX}cbs_attach_thread} - Attach a thread to server
+@item @code{@value{DIRPREFIX}cbs_detach_thread} - Detach a thread from server
+@item @code{@value{DIRPREFIX}cbs_destroy_server} - Destroy a bandwidth server
+@item @code{@value{DIRPREFIX}cbs_get_server_id} - Get an ID of a server
+@item @code{@value{DIRPREFIX}cbs_get_parameters} - Get scheduling parameters of a server
+@item @code{@value{DIRPREFIX}cbs_set_parameters} - Set scheduling parameters of a server
+@item @code{@value{DIRPREFIX}cbs_get_execution_time} - Get elapsed execution time
+@item @code{@value{DIRPREFIX}cbs_get_remaining_budget} - Get remainig execution time
+@item @code{@value{DIRPREFIX}cbs_get_approved_budget} - Get scheduler approved execution time
+@end itemize
+
+@section Background
+
+@subsection Constant Bandwidth Server Definitions
+
+@cindex CBS parameters
+
+@findex rtems_cbs_parameters
+
+The Constant Bandwidth Server API enables tasks to communicate with
+the scheduler and indicate its scheduling parameters. The scheduler
+has to be set up first (by defining @code{CONFIGURE_SCHEDULER_CBS} macro).
+
+The difference to a plain EDF is the presence of servers.
+It is a budget aware extention of the EDF scheduler, therefore, tasks
+attached to servers behave in a similar way as with EDF unless they
+exceed their budget.
+
+The intention of servers is reservation of a certain computation
+time (budget) of the processor for all subsequent periods. The structure
+@code{rtems_cbs_parameters} determines the behavior of
+a server. It contains @code{deadline} which is equal to period,
+and @code{budget} which is the time the server is allowed to
+spend on CPU per each period. The ratio between those two parameters
+yields the maximum percentage of the CPU the server can use
+(bandwidth). Moreover, thanks to this limitation the overall
+utilization of CPU is under control, and the sum of bandwidths
+of all servers in the system yields the overall reserved portion
+of processor. The rest is still available for ordinary tasks that
+are not attached to any server.
+
+In order to make the server effective to the executing tasks,
+tasks have to be attached to the servers. The
+@code{rtems_cbs_server_id} is a type denoting an id of a server
+and @code{rtems_id} a type for id of tasks.
+
+@subsection Handling Periodic Tasks
+
+@cindex CBS periodic tasks
+
+Each task's execution begins with a default background priority
+(see the chapter Scheduling Concepts to understand the concept of
+priorities in EDF). Once you decide the tasks should start periodic
+execution, you have two possibilities. Either you use only the Rate
+Monotonic manager which takes care of periodic behavior, or you declare
+deadline and budget using the CBS API in which case these properties
+are constant for all subsequent periods, unless you change them using
+the CBS API again. Task now only has to indicate and end of
+each period using @code{rtems_rate_monotonic_period}.
+
+@subsection Registering a Callback Function
+
+@cindex CBS overrun handler
+
+In case tasks attached to servers are not aware of their execution time
+and happen to exceed it, the scheduler does not guarantee execution any
+more and pulls the priority of the task to background, which would
+possibly lead to immediate preemption (if there is at least one ready
+task with a higher pirority). However, the task is not blocked but a
+callback function is invoked. The callback function
+(@code{rtems_cbs_budget_overrun}) might be optionally registered upon
+a server creation (@code{rtems_cbs_create_server}).
+
+This enables the user to define what should happen in case of budget
+overrun. There is obviously no space for huge operations because the
+priority is down and not real time any more, however, you still can at
+least in release resources for other tasks, restart the task or log an
+error information. Since the routine is called directly from kernel,
+use @code{printk()} instead of @code{printf()}.
+
+The calling convention of the callback function is:
+@ifset is-C
+@findex rtems_asr
+@example
+void overrun_handler(
+ rtems_cbs_server_id server_id
+);
+@end example
+@end ifset
+
+@subsection Limitations
+
+@cindex CBS limitations
+
+When using this scheduler you have to keep in mind several things:
+
+@itemize @bullet
+@c it_limitations
+@item In the current implementation it is possible to attach only
+a single task to each server.
+@item If you have a task attached to a server and you voluntatily
+block it in the beginning of its execution, its priority will be
+probably pulled to background upon unblock, thus not guaranteed
+deadline any more. This is because you are effectively raising
+computation time of the task. When unbocking, you should be always
+sure that the ratio between remaining computation time and remaining
+deadline is not higher that the utilization you have agreed with the
+scheduler.
+@end itemize
+
+@section Operations
+
+@subsection Setting up a server
+
+The directive @code{rtems_cbs_create_server} is used to create a new
+server that is characterized by @code{rtems_cbs_parameters}. You also
+might want to register the @code{rtems_cbs_budget_overrun} callback
+routine. After this step tasks can be attached to the server. The directive
+@code{rtems_cbs_set_parameters} can change the scheduling parameters
+to avoid destroying and creating a new server again.
+
+@subsection Attaching Task to a Server
+
+If a task is attached to a server using @code{rtems_cbs_attach_thread},
+the task's computation time per period is limited by the server and
+the deadline (period) of task is equal to deadline of the server which
+means if you conclude a period using @code{rate_monotonic_period},
+the length of next period is always determined by the server's property.
+
+The task has a guaranteed bandwidth given by the server but should not
+exceed it, otherwise the priority is pulled to background until the
+start of next period and the @code{rtems_cbs_budget_overrun} callback
+function is invoked.
+
+When attaching a task to server, the preemptability flag of the task
+is raised, otherwise it would not be possible to control the execution
+of the task.
+
+@subsection Detaching Task from a Server
+
+The directive @code{rtems_cbs_detach_thread} is just an inverse
+operation to the previous one, the task continues its execution with
+the initial priority.
+
+Preemptability of the task is restored to the initial value.
+
+@subsection Examples
+
+The following example presents a simple common use of the API.
+
+You can see the initialization and cleanup call here, if there are
+multiple tasks in the system, it is obvious that the initialization
+should be called before creating the task.
+
+Notice also that in this case we decided to register an overrun handler,
+instead of which there could be @code{NULL}. This handler just prints
+a message to terminal, what else may be done here depends on a specific
+application.
+
+During the periodic execution, remaining budget should be watched
+to avoid overrun.
+
+@example
+void overrun_handler (
+ rtems_cbs_server_id server_id
+)
+@{
+ printk( "Budget overrun, fixing the task\n" );
+ return;
+@}
+
+rtems_task Tasks_Periodic(
+ rtems_task_argument argument
+)
+@{
+ rtems_id rmid;
+
+ rtems_cbs_server_id server_id;
+ rtems_cbs_parameters params;
+
+ params.deadline = 10;
+ params.budget = 4;
+
+ rtems_cbs_initialize();
+
+ rtems_cbs_create_server( &params, &overrun_handler, &server_id )
+
+ rtems_cbs_attach_thread( server_id, SELF );
+
+ rtems_rate_monotonic_create( argument, &rmid );
+
+ while ( 1 ) @{
+ if (rtems_rate_monotonic_period(rmid, params.deadline)==RTEMS_TIMEOUT)
+ break;
+
+ /* Perform some periodic action */
+ @}
+
+ rtems_rate_monotonic_delete( rmid );
+
+ rtems_cbs_cleanup();
+ exit( 1 );
+@}
+@end example
+
+@section Directives
+
+This section details the Constant Bandwidth Server's directives.
+A subsection is dedicated to each of this manager's directives
+and describes the calling sequence, related constants, usage,
+and status codes.
+
+@c
+@c
+@c
+@page
+@subsection CBS_INITIALIZE - Initialize the CBS library
+
+@cindex initialize the CBS library
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_initialize
+@example
+int rtems_cbs_initialize( void );
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful initialization@*
+@code{@value{RPREFIX}CBS_ERROR_NO_MEMORY} - not enough memory for data@*
+
+@subheading DESCRIPTION:
+
+This routine initializes the library in terms of allocating necessary memory
+for the servers. In case not enough memory is available in the system,
+@code{@value{RPREFIX}CBS_ERROR_NO_MEMORY} is returned, otherwise
+@code{@value{RPREFIX}CBS_OK}.
+
+@subheading NOTES:
+
+Additional memory per each server is allocated upon invocation of
+@code{rtems_cbs_create_server}.
+
+Tasks in the system are not influenced, they still keep executing
+with their initial parameters.
+
+@c
+@c
+@c
+@page
+@subsection CBS_CLEANUP - Cleanup the CBS library
+
+@cindex cleanup the CBS library
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_cleanup
+@example
+int rtems_cbs_cleanup( void );
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - always successful
+
+@subheading DESCRIPTION:
+
+This routine detaches all tasks from their servers, destroys all servers
+and returns memory back to the system.
+
+@subheading NOTES:
+
+All tasks continue executing with their initial priorities.
+
+@c
+@c
+@c
+@page
+@subsection CBS_CREATE_SERVER - Create a new bandwidth server
+
+@cindex create a new bandwidth server
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_create_server
+@example
+int rtems_cbs_create_server (
+ rtems_cbs_parameters *params,
+ rtems_cbs_budget_overrun budget_overrun_callback,
+ rtems_cbs_server_id *server_id
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successfully created@*
+@code{@value{RPREFIX}CBS_ERROR_NO_MEMORY} - not enough memory for data@*
+@code{@value{RPREFIX}CBS_ERROR_FULL} - maximum servers exceeded@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+
+@subheading DESCRIPTION:
+
+This routine prepares an instance of a constant bandwidth server.
+The input parameter @code{rtems_cbs_parameters} specifies scheduling
+parameters of the server (period and budget). If these are not valid,
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} is returned.
+The @code{budget_overrun_callback} is an optional callback function, which is
+invoked in case the server's budget within one period is exceeded.
+Output parameter @code{server_id} becomes an id of the newly created server.
+If there is not enough memory, the @code{@value{RPREFIX}CBS_ERROR_NO_MEMORY}
+is returned. If the maximum server count in the system is exceeded,
+@code{@value{RPREFIX}CBS_ERROR_FULL} is returned.
+
+@subheading NOTES:
+
+No task execution is being influenced so far.
+
+@c
+@c
+@c
+@page
+@subsection CBS_ATTACH_THREAD - Attach a thread to server
+
+@cindex attach a thread to server
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_attach_thread
+@example
+int rtems_cbs_attach_thread (
+ rtems_cbs_server_id server_id,
+ rtems_id task_id
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successfully attached@*
+@code{@value{RPREFIX}CBS_ERROR_FULL} - server maximum tasks exceeded@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+Attaches a task (@code{task_id}) to a server (@code{server_id}).
+The server has to be previously created. Now, the task starts
+to be scheduled according to the server parameters and not
+using initial priority. This implementation allows only one task
+per server, if the user tries to bind another task to the same
+server, @code{@value{RPREFIX}CBS_ERROR_FULL} is returned.
+
+@subheading NOTES:
+
+Tasks attached to servers become preemptible.
+
+@c
+@c
+@c
+@page
+@subsection CBS_DETACH_THREAD - Detach a thread from server
+
+@cindex detach a thread from server
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_detach_thread
+@example
+int rtems_cbs_detach_thread (
+ rtems_cbs_server_id server_id,
+ rtems_id task_id
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successfully detached@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive detaches a thread from server. The task continues its
+execution with initial priority.
+
+@subheading NOTES:
+
+The server can be reused for any other task.
+
+@c
+@c
+@c
+@page
+@subsection CBS_DESTROY_SERVER - Destroy a bandwidth server
+
+@cindex destroy a bandwidth server
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_destroy_server
+@example
+int rtems_cbs_destroy_server (
+ rtems_cbs_server_id server_id
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successfully destroyed@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive destroys a server. If any task was attached to the server,
+the task is detached and continues its execution according to EDF rules
+with initial properties.
+
+@subheading NOTES:
+
+This again enables one more task to be created.
+
+@c
+@c
+@c
+@page
+@subsection CBS_GET_SERVER_ID - Get an ID of a server
+
+@cindex get an ID of a server
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_get_server_id
+@example
+int rtems_cbs_get_server_id (
+ rtems_id task_id,
+ rtems_cbs_server_id *server_id
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive returns an id of server belonging to a given task.
+
+@c
+@c
+@c
+@page
+@subsection CBS_GET_PARAMETERS - Get scheduling parameters of a server
+
+@cindex get scheduling parameters of a server
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_get_parameters
+@example
+rtems_cbs_get_parameters (
+ rtems_cbs_server_id server_id,
+ rtems_cbs_parameters *params
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive returns a structure with current scheduling parameters
+of a given server (period and execution time).
+
+@subheading NOTES:
+
+It makes no difference if any task is assigned or not.
+
+@c
+@c
+@c
+@page
+@subsection CBS_SET_PARAMETERS - Set scheduling parameters
+
+@cindex set scheduling parameters
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_set_parameters
+@example
+int rtems_cbs_set_parameters (
+ rtems_cbs_server_id server_id,
+ rtems_cbs_parameters *params
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive sets new scheduling parameters to the server. This operation
+can be performed regardless of whether a task is assigned or not.
+If a task is assigned, the parameters become effective imediately, therefore it
+is recommended to apply the change between two subsequent periods.
+
+@subheading NOTES:
+
+There is an upper limit on both period and budget equal to (2^31)-1 ticks.
+
+@c
+@c
+@c
+@page
+@subsection CBS_GET_EXECUTION_TIME - Get elapsed execution time
+
+@cindex get elapsed execution time
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_get_execution_time
+@example
+int rtems_cbs_get_execution_time (
+ rtems_cbs_server_id server_id,
+ time_t *exec_time,
+ time_t *abs_time
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This routine returns consumed execution time (@code{exec_time}) of a server
+during the current period.
+
+@subheading NOTES:
+
+Absolute time (@code{abs_time}) not supported now.
+
+@c
+@c
+@c
+@page
+@subsection CBS_GET_REMAINING_BUDGET - Get remaining execution time
+
+@cindex get remaining execution time
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_get_remaining_budget
+@example
+int rtems_cbs_get_remaining_budget (
+ rtems_cbs_server_id server_id,
+ time_t *remaining_budget
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive returns remaining execution time of a given server for
+current period.
+
+@subheading NOTES:
+
+If the execution time approaches zero, the assigned task should finish
+computations of the current period.
+
+@c
+@c
+@c
+@page
+@subsection CBS_GET_APPROVED_BUDGET - Get scheduler approved execution time
+
+@cindex get scheduler approved execution time
+
+@subheading CALLING SEQUENCE:
+
+@ifset is-C
+@findex rtems_cbs_get_approved_budget
+@example
+int rtems_cbs_get_approved_budget (
+ rtems_cbs_server_id server_id,
+ time_t *appr_budget
+);
+@end example
+@end ifset
+
+@subheading DIRECTIVE STATUS CODES:
+@code{@value{RPREFIX}CBS_OK} - successful@*
+@code{@value{RPREFIX}CBS_ERROR_INVALID_PARAMETER} - invalid input argument@*
+@code{@value{RPREFIX}CBS_ERROR_NOSERVER} - server is not valid@*
+
+@subheading DESCRIPTION:
+
+This directive returns server's approved budget for subsequent periods.
diff --git a/doc/user/dirstat.texi b/doc/user/dirstat.texi
index 25c4ece1f2..9ad866cf52 100644
--- a/doc/user/dirstat.texi
+++ b/doc/user/dirstat.texi
@@ -6,7 +6,7 @@
@c $Id$
@c
-@node Directive Status Codes, Example Application, Chains Prepend a Node, Top
+@node Directive Status Codes, Example Application, Constant Bandwidth Server Scheduler API CBS_GET_APPROVED_BUDGET - Get scheduler approved execution time, Top
@chapter Directive Status Codes
@table @b
@item @code{@value{RPREFIX}SUCCESSFUL} - successful completion
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index 5cb24d1eba..4a1ac8a0cc 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -31,7 +31,7 @@ SUBDIRS = \
spintrcritical17 spmkdir spmountmgr01 spheapprot \
spsimplesched01 spsimplesched02 spsimplesched03 spnsext01 \
spedfsched01 spedfsched02 spedfsched03 \
- spcbssched01 spcbssched02 spcbssched03
+ spcbssched01 spcbssched02 spcbssched03 spqreslib
include $(top_srcdir)/../automake/subdirs.am
include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index bf79928a25..17c56caf4b 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -174,6 +174,7 @@ spnsext01/Makefile
spobjgetnext/Makefile
spprintk/Makefile
spprivenv01/Makefile
+spqreslib/Makefile
sprbtree01/Makefile
spsimplesched01/Makefile
spsimplesched02/Makefile
diff --git a/testsuites/sptests/spqreslib/Makefile.am b/testsuites/sptests/spqreslib/Makefile.am
new file mode 100644
index 0000000000..bd8323ff9d
--- /dev/null
+++ b/testsuites/sptests/spqreslib/Makefile.am
@@ -0,0 +1,28 @@
+##
+## $Id$
+##
+
+MANAGERS = io rate_monotonic semaphore clock
+
+rtems_tests_PROGRAMS = spqreslib
+spqreslib_SOURCES = init.c task_periodic.c system.h
+
+dist_rtems_tests_DATA = spqreslib.scn
+dist_rtems_tests_DATA += spqreslib.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+spqreslib_LDADD = $(MANAGERS_NOT_WANTED:%=$(PROJECT_LIB)/no-%.rel)
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(spqreslib_OBJECTS) $(spqreslib_LDADD)
+LINK_LIBS = $(spqreslib_LDLIBS)
+
+spqreslib$(EXEEXT): $(spqreslib_OBJECTS) $(spqreslib_DEPENDENCIES)
+ @rm -f spqreslib$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/spqreslib/init.c b/testsuites/sptests/spqreslib/init.c
new file mode 100644
index 0000000000..20745d7ea2
--- /dev/null
+++ b/testsuites/sptests/spqreslib/init.c
@@ -0,0 +1,227 @@
+/* Init
+ *
+ * This routine is the initialization task for this test program.
+ * It is a user initialization task and has the responsibility for creating
+ * and starting the tasks that make up the test. If the time of day
+ * clock is required for the test, it should also be set to a known
+ * value by this function.
+ *
+ * Input params:
+ * argument - task argument
+ *
+ * Output params: NONE
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#define CONFIGURE_INIT
+#include "system.h"
+
+rtems_task Init(
+ rtems_task_argument argument
+)
+{
+ rtems_status_code status;
+ qres_sid_t server_id, server_id2;
+ time_t approved_budget, exec_time, abs_time, current_budget;
+ qres_params_t params, params1, params2, params3, params4;
+
+ Priority = 30;
+ Period = 30;
+ Execution = 10;
+ Phase = 0;
+
+ params.P = 1;
+ params.Q = 1;
+
+ params1 = params2 = params3 = params4 = params;
+ params1.Q = -1;
+ params2.Q = SCHEDULER_EDF_PRIO_MSB + 1;
+ params3.P = -1;
+ params4.P = SCHEDULER_EDF_PRIO_MSB + 1;
+
+ puts( "\n\n*** TEST QRES LIBRARY ***" );
+
+ Task_name = rtems_build_name( 'P', 'T', '1', ' ' );
+
+ status = rtems_task_create(
+ Task_name,
+ Priority,
+ RTEMS_MINIMUM_STACK_SIZE * 4,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &Task_id
+ );
+ directive_failed( status, "rtems_task_create loop" );
+
+ printf( "Init: Initializing the qres library\n" );
+ if ( qres_init() )
+ printf( "ERROR: QRES INITIALIZATION FAILED\n" );
+
+ /* Error checks for Create server and Destroy server */
+ printf( "Init: Create server and Destroy server\n" );
+ if ( qres_destroy_server( -5 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: DESTROY SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_destroy_server( 5 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: DESTROY SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_destroy_server( 0 ) != QOS_E_NOSERVER )
+ printf( "ERROR: DESTROY SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_create_server( &params1, &server_id ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_create_server( &params2, &server_id ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_create_server( &params3, &server_id ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_create_server( &params4, &server_id ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" );
+ if ( qres_create_server( &params, &server_id2 ) )
+ printf( "ERROR: CREATE SERVER FAILED\n" );
+ if ( qres_create_server( &params, &server_id ) )
+ printf( "ERROR: CREATE SERVER FAILED\n" );
+ if ( qres_create_server( &params, &server_id ) !=
+ QOS_E_FULL )
+ printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" );
+
+ /* Error checks for Attach thread and Detach thread */
+ printf( "Init: Attach thread\n" );
+ if ( qres_attach_thread( -5, 0, RTEMS_SELF ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" );
+ if ( qres_attach_thread( 5, 0, RTEMS_SELF ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" );
+ if ( qres_attach_thread( server_id, 0, 1234 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" );
+ if ( qres_attach_thread( server_id, 0, RTEMS_SELF ) )
+ printf( "ERROR: ATTACH THREAD FAILED\n" );
+ if ( qres_attach_thread( server_id, 0, RTEMS_SELF ) !=
+ QOS_E_FULL )
+ printf( "ERROR: ATTACH THREAD AGAIN PASSED UNEXPECTEDLY\n" );
+ if ( qres_attach_thread( server_id, 0, Task_id ) !=
+ QOS_E_FULL )
+ printf( "ERROR: ATTACH THREAD TO FULL SERVER PASSED UNEXPECTEDLY \n" );
+ if ( qres_destroy_server( server_id ) )
+ printf( "ERROR: DESTROY SERVER WITH THREAD ATTACHED FAILED\n" );
+ if ( qres_attach_thread( server_id, 0, RTEMS_SELF ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" );
+
+ printf( "Init: Detach thread\n" );
+ if ( qres_detach_thread( -5, 0, RTEMS_SELF ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY\n" );
+ if ( qres_detach_thread( 5, 0, RTEMS_SELF ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY\n" );
+ if ( qres_detach_thread( server_id2, 0, 1234 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY \n" );
+ if ( qres_detach_thread( server_id, 0, RTEMS_SELF ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY4\n" );
+ qres_destroy_server( server_id2 );
+
+ /* Error checks for Set params and Get params */
+ printf( "Init: Set params and Get params\n" );
+ if ( qres_set_params( -5, &params ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_set_params( 5, &params ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_set_params( server_id, &params ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+
+ if ( qres_get_params( -5, &params ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_params( 5, &params ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_params( server_id, &params ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: GET PARAMS PASSED UNEXPECTEDLY\n" );
+
+ if ( qres_set_params( server_id, &params1 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_set_params( server_id, &params2 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_set_params( server_id, &params3 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+ if ( qres_set_params( server_id, &params4 ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: SET PARAMS PASSED UNEXPECTEDLY\n" );
+
+ /* Error checks for Get server id */
+ printf( "Init: Get server id\n" );
+ if ( qres_get_sid( 0, RTEMS_SELF, &server_id ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: GET SERVER ID PASSED UNEXPECTEDLY\n" );
+
+ /* Error checks for Get approved budget */
+ printf( "Init: Get approved budget\n" );
+ if ( qres_get_appr_budget( -5, &approved_budget ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET APPROVED BUDGET PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_appr_budget( 5, &approved_budget ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET APPROVED BUDGET PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_appr_budget( server_id, &approved_budget ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: GET APPROVED BUDGET PASSED UNEXPECTEDLY\n" );
+
+ /* Error checks for Get current budget */
+ printf( "Init: Get current budget\n" );
+ if ( qres_get_curr_budget( -5, &current_budget ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET REMAINING BUDGET PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_curr_budget( 5, &current_budget ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET REMAINING BUDGET PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_curr_budget( server_id, &current_budget ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: GET REMAINING BUDGET PASSED UNEXPECTEDLY\n" );
+
+ /* Error checks for Get execution time */
+ printf( "Init: Get execution time\n" );
+ if ( qres_get_exec_time( -5, &exec_time, &abs_time ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_exec_time( 5, &exec_time, &abs_time ) !=
+ QOS_E_INVALID_PARAM )
+ printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" );
+ if ( qres_get_exec_time( server_id, &exec_time, &abs_time ) !=
+ QOS_E_NOSERVER )
+ printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" );
+
+ /* Restart QRES library */
+ printf( "Init: Cleaning up QRES\n" );
+ if ( qres_cleanup() )
+ printf( "ERROR: QRES CLEANUP FAILED\n" );
+ printf( "Init: Initializing the QRES\n" );
+ if ( qres_init() )
+ printf( "ERROR: QRES INITIALIZATION FAILED\n" );
+
+ /* Start periodic task */
+ printf( "Init: Starting periodic task\n" );
+ status = rtems_task_start( Task_id, Task_Periodic, 1 );
+ directive_failed( status, "rtems_task_start periodic" );
+
+ status = rtems_task_delete( RTEMS_SELF );
+ directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
+}
diff --git a/testsuites/sptests/spqreslib/spqreslib.doc b/testsuites/sptests/spqreslib/spqreslib.doc
new file mode 100644
index 0000000000..f590216547
--- /dev/null
+++ b/testsuites/sptests/spqreslib/spqreslib.doc
@@ -0,0 +1,22 @@
+#
+# $Id$
+#
+# COPYRIGHT (c) 1989-1999.
+# On-Line Applications Research Corporation (OAR).
+#
+# 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.
+#
+
+
+This file describes the directives and concepts tested by this test set.
+
+test set name: spqreslib
+
+directives:
+
+
+concepts:
+
+ a. Verifies QRES library functionality.
diff --git a/testsuites/sptests/spqreslib/spqreslib.scn b/testsuites/sptests/spqreslib/spqreslib.scn
new file mode 100644
index 0000000000..de79c34fec
--- /dev/null
+++ b/testsuites/sptests/spqreslib/spqreslib.scn
@@ -0,0 +1,30 @@
+*** TEST QRES LIBRARY ***
+Init: Initializing the qres library
+Init: Create server and Destroy server
+Init: Attach thread
+Init: Detach thread
+Init: Set params and Get params
+Init: Get server id
+Init: Get approved budget
+Init: Get current budget
+Init: Get execution time
+Init: Cleaning up QRES
+Init: Initializing the QRES
+Init: Starting periodic task
+Periodic task: Create server and Attach thread
+Periodic task: ID and Get parameters
+Periodic task: Detach thread and Destroy server
+Periodic task: Current budget and Execution time
+Periodic task: Set parameters
+Periodic task: Approved budget
+Periodic task: Starting periodic behavior
+P1-S ticks:1
+P1-F ticks:11
+P1-S ticks:31
+P1-F ticks:41
+P1-S ticks:61
+P1-F ticks:71
+P1-S ticks:91
+P1-F ticks:101
+P1-S ticks:121
+*** END OF TEST QRES LIBRARY ***
diff --git a/testsuites/sptests/spqreslib/system.h b/testsuites/sptests/spqreslib/system.h
new file mode 100644
index 0000000000..f99b5f459d
--- /dev/null
+++ b/testsuites/sptests/spqreslib/system.h
@@ -0,0 +1,62 @@
+/* system.h
+ *
+ * This include file contains information that is included in every
+ * function in the test set.
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <tmacros.h>
+
+/* functions */
+
+rtems_task Init(
+ rtems_task_argument argument
+);
+
+rtems_task Task_Periodic(
+ rtems_task_argument argument
+);
+
+/* configuration information */
+
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 100000
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+#define CONFIGURE_MAXIMUM_PERIODS 10
+
+#define CONFIGURE_INIT_TASK_PRIORITY 100
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_EXTRA_TASK_STACKS (6 * 4 * RTEMS_MINIMUM_STACK_SIZE)
+
+#define CONFIGURE_SCHEDULER_CBS
+
+#include <rtems/confdefs.h>
+
+#include <rtems/rtems/clock.h>
+#include <rtems/score/isr.h>
+#include <rtems/rtems/intr.h>
+#include <qreslib.h>
+
+/* global variables */
+
+rtems_id Task_id;
+rtems_name Task_name;
+rtems_task_priority Priority;
+time_t Period;
+time_t Execution;
+time_t Phase;
+
+/* end of include file */
diff --git a/testsuites/sptests/spqreslib/task_periodic.c b/testsuites/sptests/spqreslib/task_periodic.c
new file mode 100644
index 0000000000..eb353c5c0c
--- /dev/null
+++ b/testsuites/sptests/spqreslib/task_periodic.c
@@ -0,0 +1,138 @@
+/* Tasks_Periodic
+ *
+ * This routine serves as a test task for the CBS scheduler
+ * implementation.
+ *
+ * Input parameters:
+ * argument - task argument
+ *
+ * Output parameters: NONE
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "system.h"
+
+rtems_task Task_Periodic(
+ rtems_task_argument argument
+)
+{
+ rtems_id rmid;
+ rtems_status_code status;
+
+ time_t approved_budget, exec_time, abs_time, current_budget;
+
+ int start, stop, now;
+
+ qres_sid_t server_id, tsid;
+ qres_params_t params, tparams;
+
+ params.P = Period;
+ params.Q = Execution+1;
+
+ printf( "Periodic task: Create server and Attach thread\n" );
+ if ( qres_create_server( &params, &server_id ) )
+ printf( "ERROR: CREATE SERVER FAILED\n" );
+ if ( qres_attach_thread( server_id, 0, Task_id ) )
+ printf( "ERROR: ATTACH THREAD FAILED\n" );
+
+ printf( "Periodic task: ID and Get parameters\n" );
+ if ( qres_get_sid( 0, Task_id, &tsid ) )
+ printf( "ERROR: GET SERVER ID FAILED\n" );
+ if ( tsid != server_id )
+ printf( "ERROR: SERVER ID MISMATCH\n" );
+ if ( qres_get_params( server_id, &tparams ) )
+ printf( "ERROR: GET PARAMETERS FAILED\n" );
+ if ( params.P != tparams.P ||
+ params.Q != tparams.Q )
+ printf( "ERROR: PARAMETERS MISMATCH\n" );
+
+ printf( "Periodic task: Detach thread and Destroy server\n" );
+ if ( qres_detach_thread( server_id, 0, Task_id ) )
+ printf( "ERROR: DETACH THREAD FAILED\n" );
+ if ( qres_destroy_server( server_id ) )
+ printf( "ERROR: DESTROY SERVER FAILED\n" );
+ if ( qres_create_server( &params, &server_id ) )
+ printf( "ERROR: CREATE SERVER FAILED\n" );
+
+ printf( "Periodic task: Current budget and Execution time\n" );
+ if ( qres_get_curr_budget( server_id, &current_budget ) )
+ printf( "ERROR: GET REMAINING BUDGET FAILED\n" );
+ if ( current_budget != params.Q )
+ printf( "ERROR: REMAINING BUDGET MISMATCH\n" );
+ if ( qres_get_exec_time( server_id, &exec_time, &abs_time ) )
+ printf( "ERROR: GET EXECUTION TIME FAILED\n" );
+
+ printf( "Periodic task: Set parameters\n" );
+ if ( qres_attach_thread( server_id, 0, Task_id ) )
+ printf( "ERROR: ATTACH THREAD FAILED\n" );
+ params.P = Period * 2;
+ params.Q = Execution * 2 +1;
+ if ( qres_set_params( server_id, &params ) )
+ printf( "ERROR: SET PARAMS FAILED\n" );
+ if ( qres_get_params( server_id, &tparams ) )
+ printf( "ERROR: GET PARAMS FAILED\n" );
+ if ( params.P != tparams.P ||
+ params.Q != tparams.Q )
+ printf( "ERROR: PARAMS MISMATCH\n" );
+ params.P = Period;
+ params.Q = Execution+1;
+ if ( qres_set_params( server_id, &params ) )
+ printf( "ERROR: SET PARAMS FAILED\n" );
+ if ( qres_get_appr_budget( server_id, &approved_budget ) )
+ printf( "ERROR: GET APPROVED BUDGET FAILED\n" );
+
+ printf( "Periodic task: Approved budget\n" );
+ if ( approved_budget != params.Q )
+ printf( "ERROR: APPROVED BUDGET MISMATCH\n" );
+
+ status = rtems_rate_monotonic_create( argument, &rmid );
+ directive_failed( status, "rtems_rate_monotonic_create" );
+
+ /* Starting periodic behavior of the task */
+ printf( "Periodic task: Starting periodic behavior\n" );
+ status = rtems_task_wake_after( 1 + Phase );
+ directive_failed( status, "rtems_task_wake_after" );
+
+ while ( FOREVER ) {
+ if ( rtems_rate_monotonic_period(rmid, Period) == RTEMS_TIMEOUT )
+ printf( "P%" PRIdPTR " - Deadline miss\n", argument );
+
+ rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start );
+ printf( "P%" PRIdPTR "-S ticks:%d\n", argument, start );
+ if ( start > 4*Period+Phase ) break; /* stop */
+ /* active computing */
+ while(FOREVER) {
+ rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now );
+ if ( now >= start + Execution ) break;
+
+ if ( qres_get_exec_time( server_id, &exec_time, &abs_time ) )
+ printf( "ERROR: GET EXECUTION TIME FAILED\n" );
+ if ( qres_get_curr_budget( server_id, &current_budget) )
+ printf( "ERROR: GET CURRENT BUDGET FAILED\n" );
+ if ( (current_budget + exec_time) > (Execution + 1) ) {
+ printf( "ERROR: CURRENT BUDGET AND EXECUTION TIME MISMATCH\n" );
+ rtems_test_exit( 0 );
+ }
+ }
+ rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &stop );
+ printf( "P%" PRIdPTR "-F ticks:%d\n", argument, stop );
+ }
+
+ /* delete period and SELF */
+ status = rtems_rate_monotonic_delete( rmid );
+ if ( status != RTEMS_SUCCESSFUL ) {
+ printf("rtems_rate_monotonic_delete failed with status of %d.\n", status);
+ rtems_test_exit( 0 );
+ }
+ if ( qres_cleanup() )
+ printf( "ERROR: QRES CLEANUP\n" );
+
+ fflush(stdout);
+ puts( "*** END OF TEST QRES LIBRARY ***" );
+ rtems_test_exit( 0 );
+}