[PATCH] Beagle BSP Improvements (GPIO driver)

Ketul Shah ketulshah1993 at gmail.com
Tue Jun 23 14:50:17 UTC 2015


Hello all,

Sorry as I am updating you related to my GPIO API after a huge delay.

I have developed it and tested it on my BBB. I did some big changes in the
API taking in the account comment(s)/suggestion(s) from my respective
mentors.

I am also looking the API developed by Andre working for Raspberry Pi. Now
I think it is a good time to merge the gpio code as API is getting more
stable and generalized.

So now it is good time to take the best things from API and we can have
common API for GPIO driver running on every embedded board.

Your comment(s) are welcomed.

Thanks.

Best Regards,
Ketul

On 29 April 2015 at 06:39, Chris Johns <chrisj at rtems.org> wrote:

>  [ Just catching up ]
>
> On 26/04/2015 9:26 pm, Ben Gras wrote:
> > All,
> >
> > I think the API as it is (for digital GPIO's) is pretty close to
> > generic. I like my suggestion (gpio_* in my previous mail) better as
> > more generic. (More configuration is hidden from the application.)
> >
> > Joel I just read your presentation.
> >
> > I have come up with a minimal GPIO API based on the above (so
> > ultimately based on the RPI API) that just covers the GPIO digital out
> > case but allows expansion (with more defines and functions).
> >
> > https://devel.rtems.org/wiki/TBR/User/BenGras
> >
> > Is this an idea? Then we can merge this code implementing a reasonably
> > generic API without having to flesh out the whole thing.
> >
>
> How do we define hardware specific details without bloating the API ?
>
> For example on a zynq project I am working on I needed a GPIO interface
> and I decided to use a struct to define the pin and the API takes
> references to it. For example to control the write enable pin on a flash
> device I have:
>
> static const gpio_pin_def gpio_Flash_WD =
> {
>   pin:      4,
>   output:   true,
>   on:       GPIO_FLASH_WD_EN,
>   outen:    true,
>   volts:    gpio_LVCMOS33,
>   pullup:   true,
>   fast:     false,
>   tristate: false
> };
>
> and then I have:
>
>    gpio_error ge = gpio_setup_pin(&gpio_Flash_WD);
>    if (ge != GPIO_NO_ERROR)
>        return FLASH_WRITE_LOCK_FAIL;
>
>    ....
>
>     gpio_output(gpio_Flash_WD.pin, GPIO_FLASH_WD_EN);
>
>    ....
>
> I need to set the voltage on the pin on the Zynq but this is Zynq specific.
>
> We need a way to let a user convey specific hardware details to the BSP
> driver through the API plus we need a light weight API with minimal
> internal translations. This approach also lets me define an array of
> pins and a single set up call configures them.
>
> So you could have:
>
> typedef struct
> {
>     int   pin;       /* The pin number. */
>     bool  output;    /* True for output, false for input. */
>     bool  on;        /* True default output is on */
>     bool  outen;     /* True for output enable on, false for off. */
>     bool  pullup;    /* True to enable the pull up. */
>     bool  tristate;  /* True to enable tri-state. */
>     void* platform;  /* Opaque hardware specific set up details. */
> } gpio_pin_def;
>
> where the 'platform' references a struct agreed between the BSP (or
> device layer) and the user code. For the generic cases this is not
> needed and NULL. It also allows layering where a device set up phase of
> user code sets the voltages and the generic code can play with the pin
> at a generic level, eg direction etc.
>
> What locking is being considered in this API ?
>
> Chris
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20150623/bc259a2d/attachment-0001.html>
-------------- next part --------------
diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am
index abef8ba..6b876dd 100644
--- a/c/src/lib/libbsp/arm/beagle/Makefile.am
+++ b/c/src/lib/libbsp/arm/beagle/Makefile.am
@@ -39,6 +39,7 @@ include_bsp_HEADERS += ../shared/include/arm-release-id.h
 include_bsp_HEADERS += ../shared/include/start.h
 include_bsp_HEADERS += include/irq.h
 include_bsp_HEADERS += include/i2c.h
+include_bsp_HEADERS += include/beagleboneblack.h
 
 include_libcpu_HEADERS =
 include_libcpu_HEADERS += ../../../libcpu/arm/shared/include/arm-cp15.h
@@ -111,6 +112,9 @@ libbsp_a_SOURCES += ../../shared/console.c \
         ../../shared/console_write.c \
         ../../shared/console_control.c
 
+# GPIO
+libbsp_a_SOURCES += gpio/gpio.c
+
 # I2C
 libbsp_a_SOURCES += misc/i2c.c
 
diff --git a/c/src/lib/libbsp/arm/beagle/gpio/gpio.c b/c/src/lib/libbsp/arm/beagle/gpio/gpio.c
new file mode 100644
index 0000000..7ffb17b
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/gpio/gpio.c
@@ -0,0 +1,198 @@
+/**
+ * @file
+ *
+ * @ingroup arm_beagle
+ *
+ * @brief Global BSP definitions.
+ */
+ 
+/**
+ * Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+ 
+#include <libcpu/am335x.h>
+#include <rtems.h>
+#include <rtems/gpio.h>
+#include <bsp/irq.h>
+#include <bsp/beagleboneblack.h>
+#include <bsp.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+
+/**
+ * @brief GPIO API mutex atributes.
+ */
+#define MUTEX_ATRIBUTES                         \
+  ( RTEMS_LOCAL                                 \
+    | RTEMS_PRIORITY                            \
+    | RTEMS_BINARY_SEMAPHORE                    \
+    | RTEMS_INHERIT_PRIORITY                    \
+    | RTEMS_NO_PRIORITY_CEILING                 \
+    )
+
+#define OBTAIN_LOCK(s) assert( rtems_semaphore_obtain(s,                \
+                                                      RTEMS_WAIT,       \
+                                                      RTEMS_NO_TIMEOUT  \
+                                                      ) == RTEMS_SUCCESSFUL )
+
+#define RELEASE_LOCK(s) assert( rtems_semaphore_release(s) == RTEMS_SUCCESSFUL )
+
+/* GPIO bank pin number as per TRM of AM335X */
+static unsigned int gpio_bank_pin[GPIO_PIN_COUNT]; 
+/* GPIO bank determines register of AM335X */
+static unsigned int gpio_bank[GPIO_PIN_COUNT];
+/* Pin states for all GPIO pins*/
+static unsigned int gpio_pin_state[GPIO_PIN_COUNT];
+/* Variable for gpio initialization */
+static bool is_initialized = false;
+/* Total number of gpio banks */
+static int gpio_bank_count = GPIO_PIN_COUNT / GPIO_PINS_PER_BANK;
+/* Semaphore for avoiding race condition */
+static rtems_id bank_lock;
+
+static const uint32_t gpio_bank_addrs[] = 
+ { AM335X_GPIO0, AM335X_GPIO1, AM335X_GPIO2, AM335X_GPIO3 };
+
+static uint32_t inline get_pin_mask(unsigned int pin_number)
+{
+  return (1UL << gpio_bank_pin[pin_number]);
+}
+
+static void inline reg_update_set(unsigned int pin_number,uint32_t reg)
+{
+ uint32_t gpioreg=gpio_bank[pin_number]+reg;
+ uint32_t gpioreg_val=mmio_read(gpioreg);
+ gpioreg_val |= get_pin_mask(pin_number);
+ mmio_write(gpioreg, gpioreg_val);
+}
+
+static void inline reg_update_unset(unsigned int pin_number,uint32_t reg)
+{
+ uint32_t gpioreg=gpio_bank[pin_number]+reg;
+ uint32_t gpioreg_val=mmio_read(gpioreg);
+ gpioreg_val &= ~get_pin_mask(pin_number);
+ mmio_write(gpioreg, gpioreg_val);
+}
+
+/**
+ * @brief Initializes the GPIO API. 
+ *        Allocates space to gpio_pin_state and sets pin state as UNCONFIGURED.
+ *        Creates Semaphore for avoiding any race condition.
+ *        If the API has already been initialized silently exits.
+ */
+void rtems_gpio_initialize(void)
+{ 
+ int i;
+ rtems_status_code status;
+ if ( is_initialized )
+   return;
+ 
+ is_initialized = true;
+ for ( i = 0; i < GPIO_PIN_COUNT; ++i ) {
+   gpio_pin_state[i] = GPIO_PIN_STATE_UNCONFIGURED;
+ }
+ /* Create GPIO bank Semaphores */
+    status = rtems_semaphore_create(
+      rtems_build_name('G', 'S', 'E', ' '), 
+      1, 
+      MUTEX_ATRIBUTES, 
+      0, 
+      &bank_lock
+      );
+    printf("%s %d\n",status,status );
+    assert (status == RTEMS_SUCCESSFUL);
+}
+
+/**
+ * @brief Configures a GPIO pin to perform a digital output.
+ *
+ * @retval GPIO_SUCCESSFUL Pin was configured successfully as output.
+ * @retval GPIO_UNKNOWN_PIN Pin is invalid or unknown.
+ * @retval GPIO_MISCONFIGURED_PIN Pin is already configured for another state.
+ */
+int rtems_gpio_configure_pin_digital_out(gpio_pin_handle *gpio_pin_assign,unsigned int pin_number)
+{
+ if (pin_number > 128 || pin_number < 0)
+   return GPIO_UNKNOWN_PIN;
+ if (gpio_pin_state[gpio_pin_assign->pin_number] != GPIO_PIN_STATE_UNCONFIGURED &&
+       gpio_pin_state[gpio_pin_assign->pin_number] != GPIO_PIN_STATE_DIGITAL_OUT)
+   return GPIO_MISCONFIGURED_PIN;
+ 
+ gpio_pin_state[gpio_pin_assign->pin_number] = GPIO_PIN_STATE_DIGITAL_OUT;
+ gpio_pin_assign->pin_number = pin_number;
+ gpio_bank_pin[pin_number] = pin_number % GPIO_PINS_PER_BANK;
+ gpio_bank[pin_number] = gpio_bank_addrs[pin_number/GPIO_PINS_PER_BANK];
+
+ OBTAIN_LOCK(bank_lock);
+
+ reg_update_unset(gpio_pin_assign->pin_number,AM335X_GPIO_OE);
+
+ RELEASE_LOCK(bank_lock);
+ 
+ return GPIO_SUCCESSFUL;
+}
+
+/**
+ * @brief Gives an output GPIO pin the logical value of 1.
+ * @retval GPIO_SUCCESSFUL Pin was set successfully.
+ * @retval GPIO_MISCONFIGURED_PIN The received pin is not configured 
+ *         for digital output.
+ */
+int rtems_gpio_digital_set(gpio_pin_handle *gpio_pin_assign)
+{
+ if (gpio_pin_state[gpio_pin_assign->pin_number] != GPIO_PIN_STATE_DIGITAL_OUT)
+   return GPIO_MISCONFIGURED_PIN;
+
+ OBTAIN_LOCK(bank_lock);
+ 
+ reg_update_set(gpio_pin_assign->pin_number,AM335X_GPIO_DATAOUT);
+ 
+ RELEASE_LOCK(bank_lock);
+ 
+ return GPIO_SUCCESSFUL;
+}
+
+/**
+ * @brief Gives an output GPIO pin the logical value of 0.
+ * @retval GPIO_SUCCESSFUL Pin was cleared successfully.
+ * @retval GPIO_MISCONFIGURED_PIN The received pin is not configured 
+ *         for digital output.
+ */
+int rtems_gpio_digital_clear(gpio_pin_handle *gpio_pin_assign)
+{
+ if (gpio_pin_state[gpio_pin_assign->pin_number] == GPIO_PIN_STATE_DIGITAL_OUT)
+   return GPIO_MISCONFIGURED_PIN ;
+ 
+ OBTAIN_LOCK(bank_lock);
+
+ reg_update_unset(gpio_pin_assign->pin_number,AM335X_GPIO_DATAOUT);
+ 
+ RELEASE_LOCK(bank_lock);
+
+ return GPIO_SUCCESSFUL;
+}
+/**
+ * @brief Releases currently configured pin and makes unused for repurposing.
+ * @retval GPIO_SUCCESSFUL Pin was released successfully or it is already 
+ *         UNCONFIGURED state.
+ *
+ */
+int rtems_gpio_release_pin(gpio_pin_handle *gpio_pin_assign)
+{
+ if (gpio_pin_state[gpio_pin_assign->pin_number] == GPIO_PIN_STATE_UNCONFIGURED)
+   return GPIO_SUCCESSFUL;
+ 
+ OBTAIN_LOCK(bank_lock);
+ 
+ gpio_pin_state[gpio_pin_assign->pin_number] = GPIO_PIN_STATE_UNCONFIGURED;
+ reg_update_set(gpio_pin_assign->pin_number,AM335X_GPIO_OE);
+
+ RELEASE_LOCK(bank_lock);
+ 
+ return GPIO_SUCCESSFUL;
+}
\ No newline at end of file
diff --git a/c/src/lib/libbsp/arm/beagle/include/beagleboneblack.h b/c/src/lib/libbsp/arm/beagle/include/beagleboneblack.h
new file mode 100644
index 0000000..5630645
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/include/beagleboneblack.h
@@ -0,0 +1,63 @@
+/**
+ * @file
+ *
+ * @ingroup arm_beagle
+ *
+ * @brief Global BSP definitions.
+ */
+
+/**
+ * Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_BEAGLE_BEAGLEBONEBLACK_H
+#define LIBBSP_ARM_BEAGLE_BEAGLEBONEBLACK_H
+
+/* USER LEDs of BeagleBone Black */
+#define BBB_LED_USR0  53 /* USR LED0 */
+#define BBB_LED_USR1  54 /* USR LED1 */
+#define BBB_LED_USR2  55 /* USR LED2 */
+#define BBB_LED_USR3  56 /* USR LED3 */
+
+/* Header P8 of BeagleBone Black */
+#define BBB_P8_7      66 /* GPIO2_2 */
+#define BBB_P8_8      67 /* GPIO2_3 */
+#define BBB_P8_9      69 /* GPIO2_5 */
+#define BBB_P8_10     68 /* GPIO2_4 */
+#define BBB_P8_11     45 /* GPIO1_13 */
+#define BBB_P8_12     44 /* GPIO1_12 */
+#define BBB_P8_13     23 /* GPIO0_23 */
+#define BBB_P8_14     26 /* GPIO0_26 */
+#define BBB_P8_15     47 /* GPIO1_15 */
+#define BBB_P8_16     46 /* GPIO1_14 */
+#define BBB_P8_17     27 /* GPIO0_27 */
+#define BBB_P8_18     65 /* GPIO2_1 */
+#define BBB_P8_19     22 /* GPIO0_22 */
+#define BBB_P8_26     61 /* GPIO1_29 */
+	
+/* Header P9 of BeagleBone Black */
+#define BBB_P9_11     30 /* GPIO0_30 */
+#define BBB_P9_12     60 /* GPIO1_28 */
+#define BBB_P9_13     31 /* GPIO0_31 */
+#define BBB_P9_14     50 /* GPIO1_18 */
+#define BBB_P9_15     48 /* GPIO1_16 */
+#define BBB_P9_16     51 /* GPIO1_19 */
+#define BBB_P9_17      5 /* GPIO0_5 */
+#define BBB_P9_18      4 /* GPIO0_4 */
+#define BBB_P9_23     49 /* GPIO1_17 */
+#define BBB_P9_24     15 /* GPIO0_15 */
+#define BBB_P9_26     14 /* GPIO1_14 */
+#define BBB_P9_27     115/* GPIO3_19 */
+#define BBB_P9_30     112/* GPIO3_16 */
+#define BBB_P9_41     20 /* GPIO0_20 */
+#define BBB_P9_42      7 /* GPIO0_7 */
+
+/* BSP related specifications */
+#define GPIO_PIN_COUNT 128
+#define GPIO_PINS_PER_BANK 32 
+
+#endif /* LIBBSP_ARM_BEAGLE_GPIO_H */
\ No newline at end of file
diff --git a/c/src/lib/libbsp/arm/beagle/preinstall.am b/c/src/lib/libbsp/arm/beagle/preinstall.am
index dd1ec95..7802724 100644
--- a/c/src/lib/libbsp/arm/beagle/preinstall.am
+++ b/c/src/lib/libbsp/arm/beagle/preinstall.am
@@ -110,6 +110,10 @@ $(PROJECT_INCLUDE)/bsp/i2c.h: include/i2c.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i2c.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i2c.h
 
+$(PROJECT_INCLUDE)/bsp/beagleboneblack.h: include/beagleboneblack.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/beagleboneblack.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/beagleboneblack.h
+
 $(PROJECT_INCLUDE)/libcpu/arm-cp15.h: ../../../libcpu/arm/shared/include/arm-cp15.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
diff --git a/c/src/lib/libbsp/arm/beagle/simscripts/bone_gpio.exe-sdcard.img b/c/src/lib/libbsp/arm/beagle/simscripts/bone_gpio.exe-sdcard.img
new file mode 100644
index 0000000..93908dd
Binary files /dev/null and b/c/src/lib/libbsp/arm/beagle/simscripts/bone_gpio.exe-sdcard.img differ
diff --git a/c/src/lib/libbsp/arm/beagle/simscripts/bone_hello.exe-sdcard.img b/c/src/lib/libbsp/arm/beagle/simscripts/bone_hello.exe-sdcard.img
new file mode 100644
index 0000000..7f492eb
Binary files /dev/null and b/c/src/lib/libbsp/arm/beagle/simscripts/bone_hello.exe-sdcard.img differ
diff --git a/c/src/lib/libbsp/bfin/acinclude.m4 b/c/src/lib/libbsp/bfin/acinclude.m4
deleted file mode 100644
index ab6082e..0000000
--- a/c/src/lib/libbsp/bfin/acinclude.m4
+++ /dev/null
@@ -1,14 +0,0 @@
-# RTEMS_CHECK_BSPDIR(RTEMS_BSP_FAMILY)
-AC_DEFUN([RTEMS_CHECK_BSPDIR],
-[
-  case "$1" in
-  TLL6527M )
-    AC_CONFIG_SUBDIRS([TLL6527M]);;
-  bf537Stamp )
-    AC_CONFIG_SUBDIRS([bf537Stamp]);;
-  eZKit533 )
-    AC_CONFIG_SUBDIRS([eZKit533]);;
-  *)
-    AC_MSG_ERROR([Invalid BSP]);;
-  esac
-])
diff --git a/c/src/lib/libbsp/or1k/generic_or1k/start/start.S b/c/src/lib/libbsp/or1k/generic_or1k/start/start.S
index d951a55..ae6d41a 100644
--- a/c/src/lib/libbsp/or1k/generic_or1k/start/start.S
+++ b/c/src/lib/libbsp/or1k/generic_or1k/start/start.S
@@ -180,3 +180,10 @@ _end_clear_bss:
 
 unhandled_exception:
   l.nop
+
+/* Make C++ compiler happy */
+.section .data
+.global __dso_handle
+.weak   __dso_handle
+__dso_handle:
+.long 0
diff --git a/c/src/lib/libbsp/powerpc/acinclude.m4 b/c/src/lib/libbsp/powerpc/acinclude.m4
deleted file mode 100644
index 6442399..0000000
--- a/c/src/lib/libbsp/powerpc/acinclude.m4
+++ /dev/null
@@ -1,50 +0,0 @@
-# RTEMS_CHECK_BSPDIR(RTEMS_BSP_FAMILY)
-AC_DEFUN([RTEMS_CHECK_BSPDIR],
-[
-  case "$1" in
-  beatnik )
-    AC_CONFIG_SUBDIRS([beatnik]);;
-  ep1a )
-    AC_CONFIG_SUBDIRS([ep1a]);;
-  gen5200 )
-    AC_CONFIG_SUBDIRS([gen5200]);;
-  gen83xx )
-    AC_CONFIG_SUBDIRS([gen83xx]);;
-  haleakala )
-    AC_CONFIG_SUBDIRS([haleakala]);;
-  mbx8xx )
-    AC_CONFIG_SUBDIRS([mbx8xx]);;
-  motorola_powerpc )
-    AC_CONFIG_SUBDIRS([motorola_powerpc]);;
-  mpc55xxevb )
-    AC_CONFIG_SUBDIRS([mpc55xxevb]);;
-  mpc8260ads )
-    AC_CONFIG_SUBDIRS([mpc8260ads]);;
-  mvme3100 )
-    AC_CONFIG_SUBDIRS([mvme3100]);;
-  mvme5500 )
-    AC_CONFIG_SUBDIRS([mvme5500]);;
-  psim )
-    AC_CONFIG_SUBDIRS([psim]);;
-  qemuppc )
-    AC_CONFIG_SUBDIRS([qemuppc]);;
-  qoriq )
-    AC_CONFIG_SUBDIRS([qoriq]);;
-  score603e )
-    AC_CONFIG_SUBDIRS([score603e]);;
-  ss555 )
-    AC_CONFIG_SUBDIRS([ss555]);;
-  t32mppc )
-    AC_CONFIG_SUBDIRS([t32mppc]);;
-  tqm8xx )
-    AC_CONFIG_SUBDIRS([tqm8xx]);;
-  virtex )
-    AC_CONFIG_SUBDIRS([virtex]);;
-  virtex4 )
-    AC_CONFIG_SUBDIRS([virtex4]);;
-  virtex5 )
-    AC_CONFIG_SUBDIRS([virtex5]);;
-  *)
-    AC_MSG_ERROR([Invalid BSP]);;
-  esac
-])
diff --git a/c/src/lib/libcpu/arm/shared/include/am335x.h b/c/src/lib/libcpu/arm/shared/include/am335x.h
index 1f638bd..ebaa703 100644
--- a/c/src/lib/libcpu/arm/shared/include/am335x.h
+++ b/c/src/lib/libcpu/arm/shared/include/am335x.h
@@ -280,3 +280,43 @@
     /* Command posted status */
 #define AM335X_WDT_WSPR                0x48
     /* Activate/deactivate sequence */
+
+    /*Gpio memory registers am335x*/
+#define AM335X_GPIO0                  0x44E07000
+    /* GPIO Bank 0 base Register */
+#define AM335X_GPIO1                  0x4804C000
+    /* GPIO Bank 1 base Register */
+#define AM335X_GPIO2                  0x481AC000
+    /* GPIO Bank 2 base Register */
+#define AM335X_GPIO3                  0x481AE000
+    /* GPIO Bank 3 base Register */
+#define AM335X_GPIO_OE                0x134
+    /* GPIO Output Enable Register */
+#define AM335X_GPIO_DATAOUT           0x13C
+    /* GPIO Output pin set Register */
+#define AM335X_GPIO_DATAIN            0x138
+    /* GPIO Read Data Register */
+#define AM335X_GPIO_CLEARDATAOUT      0x190
+    /* GPIO Output Clear Register */
+#define AM335X_GPIO_SETDATAOUT        0x194
+    /* GPIO Output Set Register */
\ No newline at end of file
diff --git a/c/src/lib/libcpu/shared/include/cache.h b/c/src/lib/libcpu/shared/include/cache.h
index d9df423..9220a20 100644
--- a/c/src/lib/libcpu/shared/include/cache.h
+++ b/c/src/lib/libcpu/shared/include/cache.h
@@ -21,13 +21,10 @@
 #ifndef __LIBCPU_CACHE_h
 #define __LIBCPU_CACHE_h
 
-void _CPU_cache_flush_data_range(const void *d_addr, size_t n_bytes);
 void _CPU_cache_flush_1_data_line(const void *d_addr);
-void _CPU_cache_invalidate_data_range(const void *d_addr, size_t n_bytes);
 void _CPU_cache_invalidate_1_data_line(const void *d_addr);
 void _CPU_cache_freeze_data(void);
 void _CPU_cache_unfreeze_data(void);
-void _CPU_cache_invalidate_instruction_range(const void *i_addr, size_t n_bytes);
 void _CPU_cache_invalidate_1_instruction_line(const void *d_addr);
 void _CPU_cache_freeze_instruction(void);
 void _CPU_cache_unfreeze_instruction(void);
diff --git a/c/src/lib/libcpu/shared/src/cache_manager.c b/c/src/lib/libcpu/shared/src/cache_manager.c
index 3f7a066..202ea8e 100644
--- a/c/src/lib/libcpu/shared/src/cache_manager.c
+++ b/c/src/lib/libcpu/shared/src/cache_manager.c
@@ -20,9 +20,13 @@
  *  rtems/c/src/lib/libcpu/CPU/cache_.h
  *
  *  The cache implementation header file can define
- *  CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
+ *
+ *    #define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
+ *
  *  if it provides cache maintenance functions which operate on multiple lines.
- *  Otherwise a generic loop with single line operations will be used.
+ *  Otherwise a generic loop with single line operations will be used.  It is
+ *  strongly recommended to provide the implementation in terms of static
+ *  inline functions for performance reasons.
  *
  *  The functions below are implemented with CPU dependent inline routines
  *  found in the cache.c files for each CPU. In the event that a CPU does
diff --git a/c/src/lib/libcpu/sparc/Makefile.am b/c/src/lib/libcpu/sparc/Makefile.am
index ceed3bc..c7565d8 100644
--- a/c/src/lib/libcpu/sparc/Makefile.am
+++ b/c/src/lib/libcpu/sparc/Makefile.am
@@ -10,7 +10,7 @@ include_libcpu_HEADERS += include/libcpu/byteorder.h
 include_libcpu_HEADERS += include/libcpu/access.h
 
 noinst_PROGRAMS += cache.rel
-cache_rel_SOURCES = cache/cache.c cache/cache_.h \
+cache_rel_SOURCES = cache/cache_.h \
     ../shared/src/cache_manager.c
 cache_rel_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/cache
 cache_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
diff --git a/c/src/lib/libcpu/sparc/cache/cache.c b/c/src/lib/libcpu/sparc/cache/cache.c
deleted file mode 100644
index e87f7c0..0000000
--- a/c/src/lib/libcpu/sparc/cache/cache.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Cache Management Support Routines for the SPARC
- */
-
-#include <rtems.h>
-#include "cache_.h"
-
-
-#if defined(HAS_INSTRUCTION_CACHE)
-
-void _CPU_cache_invalidate_entire_instruction ( void )
-{
-  __asm__ volatile ("flush");
-}
-
-/* XXX these need to be addressed */
-
-void _CPU_cache_invalidate_instruction_range(
-  const void *i_addr,
-  size_t n_bytes
-)
-{
-}
-
-void _CPU_cache_freeze_instruction ( void )
-{
-}
-
-void _CPU_cache_unfreeze_instruction ( void )
-{
-}
-
-void _CPU_cache_enable_instruction ( void )
-{
-}
-
-void _CPU_cache_disable_instruction (   void )
-{
-}
-
-#endif
-/* end of file */
diff --git a/c/src/lib/libcpu/sparc/cache/cache_.h b/c/src/lib/libcpu/sparc/cache/cache_.h
index 81852a2..f7ff00c 100644
--- a/c/src/lib/libcpu/sparc/cache/cache_.h
+++ b/c/src/lib/libcpu/sparc/cache/cache_.h
@@ -14,12 +14,40 @@
  * FIXME: Some functions simply have not been implemented.
  */
 
+/* This define is set in a Makefile */
 #if defined(HAS_INSTRUCTION_CACHE)
-#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
+
 #define CPU_INSTRUCTION_CACHE_ALIGNMENT 0
-#endif
 
-#include <libcpu/cache.h>
+static inline void _CPU_cache_invalidate_entire_instruction ( void )
+{
+  __asm__ volatile ("flush");
+}
+
+/* XXX these need to be addressed */
+
+static inline void _CPU_cache_invalidate_1_instruction_line (
+  const void * i_addr )
+{
+}
+
+static inline void _CPU_cache_freeze_instruction ( void )
+{
+}
+
+static inline void _CPU_cache_unfreeze_instruction ( void )
+{
+}
+
+static inline void _CPU_cache_enable_instruction ( void )
+{
+}
+
+static inline void _CPU_cache_disable_instruction (   void )
+{
+}
+
+#endif /* defined(HAS_INSTRUCTION_CACHE) */
 
 #endif
 /* end of include file */
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index c9a4e0f..1f4e1f2 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -111,6 +111,9 @@ include_rtems_HEADERS += include/rtems/irq.h
 
 include_rtems_HEADERS += include/rtems/irq-extension.h
 
+## GPIO API
+include_rtems_HEADERS += include/rtems/gpio.h
+
 ## libfs
 include_rtems_HEADERS += libfs/src/imfs/imfs.h
 
diff --git a/cpukit/include/rtems/gpio.h b/cpukit/include/rtems/gpio.h
new file mode 100644
index 0000000..2b9ebf7
--- /dev/null
+++ b/cpukit/include/rtems/gpio.h
@@ -0,0 +1,65 @@
+/**
+ * @file rtems/gpio.h
+ *
+ * @brief Global GPIO definitions.
+ *
+ * This include the generalized definitions for GPIO 
+ */
+
+/**
+ * Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_GPIO_H
+#define _RTEMS_GPIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Returned Error Codes by function */
+#define GPIO_SUCCESSFUL        0 /* operation is OK */
+#define GPIO_UNKNOWN_PIN       1 /* pin not known by bsp */
+#define GPIO_UNCONFIGURED_PIN  2 /* pin unable to configure */
+#define GPIO_MISCONFIGURED_PIN 3 /* pin configuration can't match operation */
+
+/* Possible GPIO Pin States */
+#define GPIO_PIN_STATE_UNCONFIGURED 0
+#define GPIO_PIN_STATE_DIGITAL_OUT  1
+#define GPIO_PIN_STATE_DIGITAL_IN   2
+
+/**
+ * @brief Structure contains all the required members for GPIO access.
+ */
+typedef struct
+{
+  int   pin_number;/* The pin number. */
+  void* platform;  /* Opaque hardware specific set up details. */
+} gpio_pin_handle;
+
+/**
+ * @brief Initializes the GPIO API.
+ */
+extern void rtems_gpio_initialize(void);
+/**
+ * @brief Selects a GPIO pin for a digital output.
+ */
+extern int rtems_gpio_configure_pin_digital_out(gpio_pin_handle *, unsigned int );
+/**
+ * @brief Turns on the given pin.
+ */
+extern int rtems_gpio_digital_set(gpio_pin_handle *);
+/**
+ * @brief Turns off the given pin.
+ */
+extern int rtems_gpio_digital_clear(gpio_pin_handle *);
+/**
+ * @brief currently configured pin is released and made UNCONFIGURED.
+ */
+extern int rtems_gpio_release_pin(gpio_pin_handle *);
+
+#endif /* _RTEMS_GPIO_H */
\ No newline at end of file
diff --git a/cpukit/libfs/src/dosfs/msdos_rmnod.c b/cpukit/libfs/src/dosfs/msdos_rmnod.c
index b91728c..78aa990 100644
--- a/cpukit/libfs/src/dosfs/msdos_rmnod.c
+++ b/cpukit/libfs/src/dosfs/msdos_rmnod.c
@@ -28,7 +28,7 @@ msdos_rmnod(const rtems_filesystem_location_info_t *parent_pathloc,
     msdos_fs_info_t   *fs_info = pathloc->mt_entry->fs_info;
     fat_file_fd_t     *fat_fd = pathloc->node_access;
 
-    if (fat_fd->fat_file_type == FAT_FILE)
+    if (fat_fd->fat_file_type == FAT_DIRECTORY)
     {
         bool is_empty = false;
 
diff --git a/cpukit/libmisc/cpuuse/cpuusagetop.c b/cpukit/libmisc/cpuuse/cpuusagetop.c
index e47ba59..e4a47fe 100644
--- a/cpukit/libmisc/cpuuse/cpuusagetop.c
+++ b/cpukit/libmisc/cpuuse/cpuusagetop.c
@@ -6,6 +6,8 @@
  */
 
 /*
+ *  COPYRIGHT (c) 2015. Chris Johns <chrisj at rtems.org>
+ *
  *  COPYRIGHT (c) 2014.
  *  On-Line Applications Research Corporation (OAR).
  *
@@ -14,10 +16,15 @@
  *  http://www.rtems.org/license/LICENSE.
  */
 
+/*
+ * Based on the old capture engine ct-load.
+ */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <stdbool.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -25,29 +32,107 @@
 #include <inttypes.h>
 
 #include <rtems/cpuuse.h>
+#include <rtems/malloc.h>
 #include <rtems/score/objectimpl.h>
+#include <rtems/score/protectedheap.h>
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/todimpl.h>
 #include <rtems/score/watchdogimpl.h>
+#include <rtems/score/wkspace.h>
 
 /*
  * Common variable to sync the load monitor task.
  */
-static volatile int rtems_cpuusage_top_thread_active;
-
-typedef struct {
-  void                  *context;
+typedef struct
+{
+  void*                  context;
   rtems_printk_plugin_t  print;
-}rtems_cpu_usage_plugin_t;
+} rtems_cpu_usage_plugin;
 
-#define RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS (20)
+/*
+ * Use a struct for all data to allow more than one top and to support the
+ * thread iterator.
+ */
+typedef struct
+{
+  volatile bool          thread_run;
+  volatile bool          thread_active;
+  volatile bool          single_page;
+  volatile uint32_t      sort_order;
+  volatile uint32_t      poll_rate_usecs;
+  volatile uint32_t      show;
+  rtems_cpu_usage_plugin plugin;
+  Thread_CPU_usage_t     zero;
+  Timestamp_Control      uptime;
+  Timestamp_Control      last_uptime;
+  Timestamp_Control      period;
+  int                    task_count;        /* Number of tasks. */
+  int                    last_task_count;   /* Number of tasks in the previous sample. */
+  int                    task_size;         /* The size of the arrays */
+  Thread_Control**       tasks;             /* List of tasks in this sample. */
+  Thread_Control**       last_tasks;        /* List of tasks in the last sample. */
+  Thread_CPU_usage_t*    usage;             /* Usage of task's in this sample. */
+  Thread_CPU_usage_t*    last_usage;        /* Usage of task's in the last sample. */
+  Thread_CPU_usage_t*    current_usage;     /* Current usage for this sample. */
+  Timestamp_Control      total;             /* Total run run, should equal the uptime. */
+  Timestamp_Control      idle;              /* Time spent in idle. */
+  Timestamp_Control      current;           /* Current time run in this period. */
+  Timestamp_Control      current_idle;      /* Current time in idle this period. */
+  uint32_t               stack_size;        /* Size of stack allocated. */
+} rtems_cpu_usage_data;
 
+/*
+ * Sort orders.
+ */
+#define RTEMS_TOP_SORT_ID            (0)
+#define RTEMS_TOP_SORT_REAL_PRI      (1)
+#define RTEMS_TOP_SORT_CURRENT_PRI   (2)
+#define RTEMS_TOP_SORT_TOTAL         (3)
+#define RTEMS_TOP_SORT_CURRENT       (4)
+#define RTEMS_TOP_SORT_MAX           (4)
+
+/*
+ * Private version of the iterator with an arg. This will be moved
+ * to the public version in 5.0.
+ */
+
+typedef void (*rtems_per_thread_routine_2)( Thread_Control *, void* );
+
+void rtems_iterate_over_all_threads_2(rtems_per_thread_routine_2 routine,
+                                      void*                      arg);
+
+void rtems_iterate_over_all_threads_2(rtems_per_thread_routine_2 routine,
+                                      void*                      arg)
+{
+  uint32_t             i;
+  uint32_t             api_index;
+  Thread_Control      *the_thread;
+  Objects_Information *information;
+
+  if ( !routine )
+    return;
+
+  for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
+    #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
+      if ( !_Objects_Information_table[ api_index ] )
+        continue;
+    #endif
+    information = _Objects_Information_table[ api_index ][ 1 ];
+    if ( information ) {
+      for ( i=1 ; i <= information->maximum ; i++ ) {
+        the_thread = (Thread_Control *)information->local_table[ i ];
+        if ( the_thread )
+          (*routine)(the_thread, arg);
+      }
+    }
+  }
+}
 
 static inline bool equal_to_uint32_t( uint32_t * lhs, uint32_t * rhs )
 {
    if ( *lhs == *rhs )
      return true;
-   else 
+   else
      return false;
 }
 
@@ -60,31 +145,175 @@ static inline bool less_than_uint32_t( uint32_t * lhs, uint32_t * rhs )
 }
 
 #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-  #define _Thread_CPU_usage_Equal_to( _lhs, _rhs ) \
+  #define CPU_usage_Equal_to( _lhs, _rhs ) \
           _Timestamp_Equal_to( _lhs, _rhs )
 #else
-  #define _Thread_CPU_usage_Equal_to( _lhs, _rhs ) \
+  #define CPU_usage_Equal_to( _lhs, _rhs ) \
           equal_to_uint32_t( _lhs, _rhs )
 #endif
 
 #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-#define  _Thread_CPU_usage_Set_to_zero( _time ) \
+  #define CPU_usage_Set_to_zero( _time ) \
          _Timestamp_Set_to_zero( _time )
 #else
-#define  _Thread_CPU_usage_Set_to_zero( _time ) \
+  #define CPU_usage_Set_to_zero( _time ) \
        do { \
          *_time = 0; \
        } while (0)
 #endif
 
 #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-#define _Thread_CPU_usage_Less_than( _lhs, _rhs ) \
+  #define CPU_usage_Less_than( _lhs, _rhs ) \
         _Timestamp_Less_than( _lhs, _rhs )
 #else
-#define _Thread_CPU_usage_Less_than( _lhs, _rhs ) \
+  #define CPU_usage_Less_than( _lhs, _rhs ) \
          less_than_uint32_t( _lhs, _rhs )
 #endif
 
+static void
+print_memsize(rtems_cpu_usage_data* data, const uint32_t size, const char* label)
+{
+  if (size > (1024 * 1024))
+    (*data->plugin.print)(data->plugin.context, "%4" PRIu32 "M %s",
+                          size / (1024 * 1024), label);
+  else if (size > 1024)
+    (*data->plugin.print)(data->plugin.context, "%4" PRIu32 "K %s",
+                          size / 1024, label);
+  else
+    (*data->plugin.print)(data->plugin.context, "%4" PRIu32 " %s",
+                          size, label);
+}
+
+static int
+print_time(rtems_cpu_usage_data*    data,
+           const Timestamp_Control* time,
+           const int                length)
+{
+  uint32_t secs = _Timestamp_Get_seconds( time );
+  uint32_t usecs = _Timestamp_Get_nanoseconds( time ) / TOD_NANOSECONDS_PER_MICROSECOND;
+  int      len = 0;
+
+  if (secs > 60)
+  {
+    uint32_t mins = secs / 60;
+    if (mins > 60)
+    {
+      uint32_t hours = mins / 60;
+      if (hours > 24)
+      {
+        len += (*data->plugin.print)(data->plugin.context, "%" PRIu32 "d", hours / 24);
+        hours %= 24;
+      }
+      len += (*data->plugin.print)(data->plugin.context, "%" PRIu32 "hr", hours);
+      mins %= 60;
+    }
+    len += (*data->plugin.print)(data->plugin.context, "%" PRIu32 "m", mins);
+    secs %= 60;
+  }
+  len += (*data->plugin.print)(data->plugin.context, "%" PRIu32 ".%06" PRIu32, secs, usecs);
+
+  if (len < length)
+    (*data->plugin.print)(data->plugin.context, "%*c", length - len, ' ');
+
+  return len;
+}
+
+/*
+ * Count the number of tasks.
+ */
+static void
+task_counter(Thread_Control *thrad, void* arg)
+{
+  rtems_cpu_usage_data* data = (rtems_cpu_usage_data*) arg;
+  ++data->task_count;
+}
+
+/*
+ * Create the sorted table with the current and total usage.
+ */
+static void
+task_usage(Thread_Control* thread, void* arg)
+{
+  rtems_cpu_usage_data* data = (rtems_cpu_usage_data*) arg;
+  Thread_CPU_usage_t    usage = thread->cpu_time_used;
+  Thread_CPU_usage_t    current = data->zero;
+  int                   j;
+
+  data->stack_size += thread->Start.Initial_stack.size;
+
+  for (j = 0; j < data->last_task_count; j++)
+  {
+    if (thread == data->last_tasks[j])
+    {
+      _Timestamp_Subtract(&data->last_usage[j], &usage, &current);
+      break;
+    }
+  }
+
+  /*
+   * When not using nanosecond CPU usage resolution, we have to count the
+   * number of "ticks" we gave credit for to give the user a rough guideline as
+   * to what each number means proportionally.
+   */
+  _Timestamp_Add_to(&data->total, &usage);
+  _Timestamp_Add_to(&data->current, &current);
+
+  if (thread->Object.id == 0x09010001)
+  {
+    data->idle = usage;
+    data->current_idle = current;
+  }
+
+  /*
+   * Create the tasks to display soring as we create.
+   */
+  for (j = 0; j < data->task_count; j++)
+  {
+    if (data->tasks[j])
+    {
+      int k;
+
+      /*
+       * Sort on the current load.
+       */
+      switch (data->sort_order)
+      {
+        default:
+          data->sort_order = RTEMS_TOP_SORT_CURRENT;
+          /* drop through */
+        case RTEMS_TOP_SORT_CURRENT:
+          if (CPU_usage_Equal_to(&current, &data->zero) ||
+              CPU_usage_Less_than(&current, &data->current_usage[j]))
+            continue;
+        case RTEMS_TOP_SORT_TOTAL:
+          if (CPU_usage_Equal_to(&usage, &data->zero) ||
+              CPU_usage_Less_than(&usage, &data->usage[j]))
+            continue;
+        case RTEMS_TOP_SORT_REAL_PRI:
+          if (thread->real_priority > data->tasks[j]->real_priority)
+            continue;
+        case RTEMS_TOP_SORT_CURRENT_PRI:
+          if (thread->current_priority > data->tasks[j]->current_priority)
+            continue;
+        case RTEMS_TOP_SORT_ID:
+          if (thread->Object.id < data->tasks[j]->Object.id)
+            continue;
+      }
+
+      for (k = (data->task_count - 1); k >= j; k--)
+      {
+        data->tasks[k + 1] = data->tasks[k];
+        data->usage[k + 1]  = data->usage[k];
+        data->current_usage[k + 1]  = data->current_usage[k];
+      }
+    }
+    data->tasks[j] = thread;
+    data->usage[j] = usage;
+    data->current_usage[j] = current;
+    break;
+  }
+}
+
 /*
  * rtems_cpuusage_top_thread
  *
@@ -94,202 +323,257 @@ static inline bool less_than_uint32_t( uint32_t * lhs, uint32_t * rhs )
 static void
 rtems_cpuusage_top_thread (rtems_task_argument arg)
 {
-  uint32_t                  api_index;
-  Thread_Control*           the_thread;
-  int                       i;
-  int                       j;
-  int                       k;
-  Objects_Information*      information;
-  char                      name[13];
-  int                       task_count = 0;
-  uint32_t                  seconds, nanoseconds;
-  rtems_cpu_usage_plugin_t* plugin = (rtems_cpu_usage_plugin_t*)arg;
-  Thread_Control*           load_tasks[RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS + 1];
-  Thread_CPU_usage_t        load[RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS + 1];
-  Thread_CPU_usage_t        zero;
-  Timestamp_Control         uptime;
-  uint32_t                  ival, fval;
-
-  while (true) {
-    #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-      Timestamp_Control  total, ran, uptime_at_last_reset;
-    #else
-      uint32_t           total_units = 0;
-    #endif
+  rtems_cpu_usage_data*  data = (rtems_cpu_usage_data*) arg;
+  char                   name[13];
+  int                    i;
+  Heap_Information_block wksp;
+  uint32_t               ival, fval;
+  int                    task_count;
+  rtems_event_set        out;
+  rtems_status_code      sc;
+  bool                   first_time = true;
 
-    rtems_cpuusage_top_thread_active = 1;
+  data->thread_active = true;
 
-    _Thread_CPU_usage_Set_to_zero( &zero);
-    memset (load_tasks, 0, sizeof (load_tasks));
-    for (i=0; i< (RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS + 1); i++)
-      _Thread_CPU_usage_Set_to_zero( &load[i] );
+  _TOD_Get_uptime(&data->last_uptime);
 
-   /*
-     * Iterate over the tasks and sort the highest load tasks
-     * into our local arrays. We only handle a limited number of
-     * tasks.
-     */
-    for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
-      #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
-        if ( !_Objects_Information_table[ api_index ] )
-          continue;
-      #endif
-
-      information = _Objects_Information_table[ api_index ][ 1 ];
-      if ( information ) {
-        for ( i=1 ; i <= information->maximum ; i++ ) {
-          the_thread = (Thread_Control *)information->local_table[ i ];
-          if ( the_thread ) {
-            Thread_CPU_usage_t usage = the_thread->cpu_time_used;
-
-            /*
-             *  When not using nanosecond CPU usage resolution, we have to count
-             *  the number of "ticks" we gave credit for to give the user a rough
-             *  guideline as to what each number means proportionally.
-             */
-            #ifdef __RTEMS_USE_TICKS_FOR_STATISTICS__
-              total_units += usage;
-            #endif
-
-            /* Count the number of tasks and sort this load value */
-            task_count++;
-            for (j = 0; j < RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS; j++) {
-              if (load_tasks[j]) {
-                if ( _Thread_CPU_usage_Equal_to( &usage, &zero) || 
-                     _Thread_CPU_usage_Less_than( &usage, &load[j]))
-                  continue;
-                for (k = (RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS - 1); k >= j; k--){
-                  load_tasks[k + 1] = load_tasks[k];
-                  load[k + 1]  = load[k];
-                }
-              }
-              load_tasks[j] = the_thread;
-              load[j]  = usage;
-              break;
-            }
-          }
-        }
+  CPU_usage_Set_to_zero(&data->zero);
+
+  while (data->thread_run)
+  {
+    Timestamp_Control uptime_at_last_reset = CPU_usage_Uptime_at_last_reset;
+    size_t            tasks_size;
+    size_t            usage_size;
+    Timestamp_Control load;
+
+    data->task_count = 0;
+    rtems_iterate_over_all_threads_2(task_counter, data);
+
+    tasks_size = sizeof(Thread_Control*) * (data->task_count + 1);
+    usage_size = sizeof(Thread_CPU_usage_t) * (data->task_count + 1);
+
+    if (data->task_count > data->task_size)
+    {
+      data->tasks = realloc(data->tasks, tasks_size);
+      data->usage = realloc(data->usage, usage_size);
+      data->current_usage = realloc(data->current_usage, usage_size);
+      if ((data->tasks == NULL) || (data->usage == NULL) || (data->current_usage == NULL))
+      {
+        (*data->plugin.print)(data->plugin.context, "top worker: error: no memory\n");
+        data->thread_run = false;
+        break;
       }
     }
 
-    #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-      _Timestamp_Set_to_zero( &total );
-      uptime_at_last_reset = CPU_usage_Uptime_at_last_reset;
-    #endif
+    memset(data->tasks, 0, tasks_size);
+    memset(data->usage, 0, usage_size);
+    memset(data->current_usage, 0, usage_size);
 
-    _TOD_Get_uptime( &uptime );
-    seconds = _Timestamp_Get_seconds( &uptime );
-    nanoseconds = _Timestamp_Get_nanoseconds( &uptime ) /
-                  TOD_NANOSECONDS_PER_MICROSECOND;
-    (*plugin->print)(plugin->context, "\x1b[H\x1b[J Press ENTER to exit.\n\n");
-    (*plugin->print)(plugin->context, "uptime: ");
-    (*plugin->print)(plugin->context,
-      "%7" PRIu32 ".%06" PRIu32 "\n",  seconds, nanoseconds
-    );
+    _Timestamp_Set_to_zero(&data->total);
+    _Timestamp_Set_to_zero(&data->current);
+    data->stack_size = 0;
+
+    _TOD_Get_uptime(&data->uptime);
+    _Timestamp_Subtract(&uptime_at_last_reset, &data->uptime, &data->uptime);
+    _Timestamp_Subtract(&data->last_uptime, &data->uptime, &data->period);
+    data->last_uptime = data->uptime;
+
+    rtems_iterate_over_all_threads_2(task_usage, data);
+
+    if (data->task_count > data->task_size)
+    {
+      data->last_tasks = realloc(data->last_tasks, tasks_size);
+      data->last_usage = realloc(data->last_usage, usage_size);
+      if ((data->last_tasks == NULL) || (data->last_usage == NULL))
+      {
+        (*data->plugin.print)(data->plugin.context, "top worker: error: no memory\n");
+        data->thread_run = false;
+        break;
+      }
+      data->task_size = data->task_count;
+    }
+
+    memcpy(data->last_tasks, data->tasks, tasks_size);
+    memcpy(data->last_usage, data->usage, usage_size);
+    data->last_task_count = data->task_count;
+
+    /*
+     * We need to loop again to get suitable current usage values as we need a
+     * last sample to work.
+     */
+    if (first_time)
+    {
+      rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(500));
+      first_time = false;
+      continue;
+    }
+
+    _Protected_heap_Get_information(&_Workspace_Area, &wksp);
+
+    if (data->single_page)
+      (*data->plugin.print)(data->plugin.context,
+                            "\x1b[H\x1b[J"
+                            " ENTER:Exit  SPACE:Refresh"
+                            "  S:Scroll  A:All  <>:Order  +/-:Lines\n");
+    (*data->plugin.print)(data->plugin.context,"\n");
+
+    /*
+     * Uptime and period of this sample.
+     */
+    (*data->plugin.print)(data->plugin.context, "Uptime: ");
+    print_time(data, &data->uptime, 20);
+    (*data->plugin.print)(data->plugin.context, " Period: ");
+    print_time(data, &data->period, 20);
+
+    /*
+     * Task count, load and idle levels.
+     */
+    (*data->plugin.print)(data->plugin.context, "\nTasks: %4i  ", data->task_count);
+
+    _Timestamp_Subtract(&data->idle, &data->total, &load);
+    _Timestamp_Divide(&load, &data->uptime, &ival, &fval);
+    (*data->plugin.print)(data->plugin.context,
+                          "Load Average: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval);
+    _Timestamp_Subtract(&data->current_idle, &data->current, &load);
+    _Timestamp_Divide(&load, &data->period, &ival, &fval);
+    (*data->plugin.print)(data->plugin.context,
+                          "  Load: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval);
+    _Timestamp_Divide(&data->current_idle, &data->period, &ival, &fval);
+    (*data->plugin.print)(data->plugin.context,
+                          "  Idle: %4" PRIu32 ".%03" PRIu32 "%%", ival, fval);
+
+    /*
+     * Memory usage.
+     */
+    if (rtems_configuration_get_unified_work_area())
+    {
+      (*data->plugin.print)(data->plugin.context, "\nMem: ");
+      print_memsize(data, wksp.Free.total, "free");
+      print_memsize(data, wksp.Used.total, "used");
+    }
+    else
+    {
+      region_information_block libc_heap;
+      malloc_info(&libc_heap);
+      (*data->plugin.print)(data->plugin.context, "\nMem: Wksp: ");
+      print_memsize(data, wksp.Free.total, "free");
+      print_memsize(data, wksp.Used.total, "used  Heap: ");
+      print_memsize(data, libc_heap.Free.total, "free");
+      print_memsize(data, libc_heap.Used.total, "used");
+    }
 
-    (*plugin->print)(
-       plugin->context,
-       "-------------------------------------------------------------------------------\n"
-       "                              CPU USAGE BY THREAD\n"
-       "------------+---------------------+---------------+---------------+------------\n"
-       #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-        " ID         | NAME                | RPRI | CPRI   | SECONDS       | PERCENT\n"
-       #else
-        " ID         | NAME                | RPRI | CPRI   | TICKS         | PERCENT\n"
-       #endif
-       "------------+---------------------+---------------+---------------+------------\n"
+    print_memsize(data, data->stack_size, "stack\n");
+
+    (*data->plugin.print)(data->plugin.context,
+       "\n"
+        " ID         | NAME                | RPRI | CPRI   | TIME                | TOTAL   | CURRENT\n"
+        "-%s---------+---------------------+-%s-----%s-----+---------------------+-%s------+--%s----\n",
+       data->sort_order == RTEMS_TOP_SORT_ID ? "^^" : "--",
+       data->sort_order == RTEMS_TOP_SORT_REAL_PRI ? "^^" : "--",
+       data->sort_order == RTEMS_TOP_SORT_CURRENT_PRI ? "^^" : "--",
+                          data->sort_order == RTEMS_TOP_SORT_TOTAL ? "^^" : "--",
+       data->sort_order == RTEMS_TOP_SORT_CURRENT ? "^^" : "--"
     );
 
-    for (i = 0; i < RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS; i++) {
+    task_count = 0;
+
+    for (i = 0; i < data->task_count; i++)
+    {
+      Thread_Control*   thread = data->tasks[i];
+      Timestamp_Control last;
+      Timestamp_Control usage;
+      Timestamp_Control current_usage;
+
+      if (thread == NULL)
+        break;
 
-      if (!load_tasks[i])
+      if (data->single_page && (data->show != 0) && (i >= data->show))
         break;
 
       /*
-       * If this is the currently executing thread, account for time
-       * since the last context switch.
+       * We need to count the number displayed to clear the remainder of the
+       * the display.
        */
-      the_thread = load_tasks[i];
-
-      rtems_object_get_name( the_thread->Object.id, sizeof(name), name );
-      (*plugin->print)(
-        plugin->context,
-        " 0x%08" PRIx32 " | %-19s |  %3" PRId32 " |  %3" PRId32 "   |",
-        the_thread->Object.id,
-        name,
-        the_thread->real_priority,
-        the_thread->current_priority
-      );
-
-      #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
-      {
-        Timestamp_Control last;
+      ++task_count;
 
-        /*
-         * If this is the currently executing thread, account for time
-         * since the last context switch.
-         */
-        ran = load[i];
-        if ( _Thread_Get_time_of_last_context_switch( the_thread, &last ) ) {
-          Timestamp_Control used;
-          _TOD_Get_uptime( &uptime );
-          _Timestamp_Subtract( &last, &uptime, &used );
-          _Timestamp_Add_to( &ran, &used );
-        } else {
-          _TOD_Get_uptime( &uptime );
-        }
-        _Timestamp_Subtract( &uptime_at_last_reset, &uptime, &total );
-        _Timestamp_Divide( &ran, &total, &ival, &fval );
+      /*
+       * If the API os POSIX print the entry point.
+       */
+      rtems_object_get_name(thread->Object.id, sizeof(name), name);
+      if (name[0] == '\0')
+        snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.entry_point);
+
+      (*data->plugin.print)(data->plugin.context,
+                            " 0x%08" PRIx32 " | %-19s |  %3" PRId32 " |  %3" PRId32 "   | ",
+                            thread->Object.id,
+                            name,
+                            thread->real_priority,
+                            thread->current_priority);
+
+      usage = data->usage[i];
+      current_usage = data->current_usage[i];
+
+      /*
+       * If this is the currently executing thread, account for time since
+       * the last context switch.
+       */
+      if (_Thread_Get_time_of_last_context_switch(thread, &last))
+      {
+        Timestamp_Control used;
+        Timestamp_Control now;
 
         /*
-         * Print the information
+         * Get the current uptime and assume we are not pre-empted to
+         * measure the time from the last switch this thread and now.
          */
-
-        seconds = _Timestamp_Get_seconds( &ran );
-        nanoseconds = _Timestamp_Get_nanoseconds( &ran ) /
-          TOD_NANOSECONDS_PER_MICROSECOND;
-       (*plugin->print)( plugin->context,
-          "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
-          seconds, nanoseconds,
-            ival, fval
-        );
+        _TOD_Get_uptime(&now);
+        _Timestamp_Subtract(&last, &now, &used);
+        _Timestamp_Add_to(&usage, &used);
+        _Timestamp_Add_to(&current_usage, &used);
       }
-      #else
-        if (total_units) {
-          uint64_t ival_64;
-
-          ival_64 = load[i];
-          ival_64 *= 100000;
-          ival = ival_64 / total_units;
-        } else {
-          ival = 0;
-        }
-
-        fval = ival % 1000;
-        ival /= 1000;
-       (*plugin->print)( plugin->context,
-          "%14" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
-          load[i],
-          ival,
-          fval
-        );
-      #endif
+
+      /*
+       * Print the information
+       */
+      print_time(data, &usage, 19);
+      _Timestamp_Divide(&usage, &data->total, &ival, &fval);
+      (*data->plugin.print)(data->plugin.context,
+                            " |%4" PRIu32 ".%03" PRIu32, ival, fval);
+      _Timestamp_Divide(&current_usage, &data->period, &ival, &fval);
+      (*data->plugin.print)(data->plugin.context,
+                            " |%4" PRIu32 ".%03" PRIu32 "\n", ival, fval);
     }
 
-    if (task_count < RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS)
+    if (data->single_page && (data->show != 0) && (task_count < data->show))
     {
-      j = RTEMS_CPUUSAGE_TOP_MAX_LOAD_TASKS - task_count;
-      while (j > 0)
+      i = data->show - task_count;
+      while (i > 0)
       {
-       (*plugin->print)( plugin->context, "\x1b[K\n");
-        j--;
+        (*data->plugin.print)(data->plugin.context, "\x1b[K\n");
+        i--;
       }
     }
 
-    rtems_cpuusage_top_thread_active = 0;
-
-    rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (5000000));
+    sc = rtems_event_receive(RTEMS_EVENT_1,
+                             RTEMS_EVENT_ANY,
+                             RTEMS_MILLISECONDS_TO_TICKS (data->poll_rate_usecs),
+                             &out);
+    if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT))
+    {
+      (*data->plugin.print)(data->plugin.context,
+                            "error: event receive: %s\n", rtems_status_text(sc));
+      break;
+    }
   }
+
+  free(data->tasks);
+  free(data->last_tasks);
+  free(data->last_usage);
+  free(data->current_usage);
+
+  data->thread_active = false;
+
+  rtems_task_delete (RTEMS_SELF);
 }
 
 void rtems_cpu_usage_top_with_plugin(
@@ -297,17 +581,30 @@ void rtems_cpu_usage_top_with_plugin(
   rtems_printk_plugin_t  print
 )
 {
-  rtems_status_code   sc;
-  rtems_task_priority priority;
-  rtems_name          name;
-  rtems_id            id;
-  rtems_cpu_usage_plugin_t  plugin;
+#ifdef __RTEMS_USE_TICKS_FOR_STATISTICS__
+  if ( !print )
+    return;
+  (*print)(context, "error: tick kernels not supported\n");
+#else
+  rtems_status_code      sc;
+  rtems_task_priority    priority;
+  rtems_name             name;
+  rtems_id               id;
+  rtems_cpu_usage_data   data;
+  int                    show_lines = 25;
 
   if ( !print )
     return;
 
-  plugin.context = context;
-  plugin.print   = print;
+  memset(&data, 0, sizeof(data));
+
+  data.thread_run = true;
+  data.single_page = true;
+  data.sort_order = RTEMS_TOP_SORT_CURRENT;
+  data.poll_rate_usecs = 3000;
+  data.show = show_lines;
+  data.plugin.context = context;
+  data.plugin.print = print;
 
   sc = rtems_task_set_priority (RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority);
 
@@ -339,7 +636,7 @@ void rtems_cpu_usage_top_with_plugin(
   }
 
   sc = rtems_task_start (
-    id, rtems_cpuusage_top_thread, (rtems_task_argument)&plugin
+    id, rtems_cpuusage_top_thread, (rtems_task_argument) &data
   );
   if (sc != RTEMS_SUCCESSFUL)
   {
@@ -352,23 +649,72 @@ void rtems_cpu_usage_top_with_plugin(
     return;
   }
 
-  for (;;)
+  while (true)
   {
     int c = getchar ();
 
-    if ((c == '\r') || (c == '\n'))
+    if ((c == '\r') || (c == '\n') || (c == 'q') || (c == 'Q'))
     {
-      int loops = 20;
+      int loops = 50;
 
-      while (loops && rtems_cpuusage_top_thread_active)
-        rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (100000));
+      data.thread_run = false;
 
-      rtems_task_delete (id);
+      rtems_event_send(id, RTEMS_EVENT_1);
+
+      while (loops && data.thread_active)
+        rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (100000));
 
       (*print)(context, "load monitoring stopped.\n");
       return;
     }
+    else if (c == '<')
+    {
+      if (data.sort_order == 0)
+        data.sort_order = RTEMS_TOP_SORT_MAX;
+      else
+        --data.sort_order;
+      rtems_event_send(id, RTEMS_EVENT_1);
+    }
+    else if (c == '>')
+    {
+      if (data.sort_order >= RTEMS_TOP_SORT_MAX)
+        data.sort_order = 0;
+      else
+        ++data.sort_order;
+      rtems_event_send(id, RTEMS_EVENT_1);
+    }
+    else if ((c == 's') || (c == 'S'))
+    {
+      data.single_page = !data.single_page;
+      rtems_event_send(id, RTEMS_EVENT_1);
+    }
+    else if ((c == 'a') || (c == 'A'))
+    {
+      if (data.show == 0)
+        data.show = show_lines;
+      else
+        data.show = 0;
+      rtems_event_send(id, RTEMS_EVENT_1);
+    }
+    else if (c == '+')
+    {
+      ++show_lines;
+      if (data.show != 0)
+        data.show = show_lines;
+    }
+    else if (c == '-')
+    {
+      if (show_lines > 5)
+        --show_lines;
+      if (data.show != 0)
+        data.show = show_lines;
+    }
+    else if (c == ' ')
+    {
+      rtems_event_send(id, RTEMS_EVENT_1);
+    }
   }
+#endif
 }
 
 void rtems_cpu_usage_top( void )
diff --git a/cpukit/libmisc/monitor/mon-prmisc.c b/cpukit/libmisc/monitor/mon-prmisc.c
index ff54d79..9140f92 100644
--- a/cpukit/libmisc/monitor/mon-prmisc.c
+++ b/cpukit/libmisc/monitor/mon-prmisc.c
@@ -127,6 +127,7 @@ static const rtems_assoc_t rtems_monitor_state_assoc[] = {
     { "Wmutex", STATES_WAITING_FOR_MUTEX, 0 },
     { "Wcvar",  STATES_WAITING_FOR_CONDITION_VARIABLE, 0 },
     { "Wjatx",  STATES_WAITING_FOR_JOIN_AT_EXIT, 0 },
+    { "Wjoin",  STATES_WAITING_FOR_JOIN, 0 },
     { "Wrpc",   STATES_WAITING_FOR_RPC_REPLY, 0 },
     { "WRATE",  STATES_WAITING_FOR_PERIOD, 0 },
     { "Wsig",   STATES_WAITING_FOR_SIGNAL, 0 },
diff --git a/cpukit/posix/src/mutexlocksupp.c b/cpukit/posix/src/mutexlocksupp.c
index 92c6556..9b20f58 100644
--- a/cpukit/posix/src/mutexlocksupp.c
+++ b/cpukit/posix/src/mutexlocksupp.c
@@ -55,7 +55,7 @@ int _POSIX_Mutex_Lock_support(
 
     case OBJECTS_LOCAL:
 #if defined(RTEMS_SMP)
-      _Thread_Dispatch_disable();
+      _Thread_Disable_dispatch();
 #endif
       executing = _Thread_Executing;
       _CORE_mutex_Seize(
diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c
index 99cc4d3..e2b1664 100644
--- a/cpukit/posix/src/pthreadjoin.c
+++ b/cpukit/posix/src/pthreadjoin.c
@@ -71,7 +71,7 @@ on_EINTR:
         _Thread_queue_Enqueue(
           &api->Join_List,
           executing,
-          STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_INTERRUPTIBLE_BY_SIGNAL,
+          STATES_WAITING_FOR_JOIN | STATES_INTERRUPTIBLE_BY_SIGNAL,
           WATCHDOG_NO_TIMEOUT
         );
       }
diff --git a/cpukit/preinstall.am b/cpukit/preinstall.am
index 0758ec5..4a58fe7 100644
--- a/cpukit/preinstall.am
+++ b/cpukit/preinstall.am
@@ -261,6 +261,10 @@ $(PROJECT_INCLUDE)/rtems/irq-extension.h: include/rtems/irq-extension.h $(PROJEC
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/irq-extension.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/irq-extension.h
 
+$(PROJECT_INCLUDE)/rtems/gpio.h: include/rtems/gpio.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/gpio.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/gpio.h
+
 $(PROJECT_INCLUDE)/rtems/imfs.h: libfs/src/imfs/imfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/imfs.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/imfs.h
diff --git a/cpukit/score/include/rtems/score/statesimpl.h b/cpukit/score/include/rtems/score/statesimpl.h
index 074b352..9f94675 100644
--- a/cpukit/score/include/rtems/score/statesimpl.h
+++ b/cpukit/score/include/rtems/score/statesimpl.h
@@ -84,6 +84,8 @@ extern "C" {
 #define STATES_MIGRATING                       0x400000
 /** This macro corresponds to a task restarting. */
 #define STATES_RESTARTING                      0x800000
+/** This macro corresponds to a task waiting for a join. */
+#define STATES_WAITING_FOR_JOIN                0x1000000
 
 /** This macro corresponds to a task which is in an interruptible
  *  blocking state.
@@ -97,7 +99,7 @@ extern "C" {
                                  STATES_WAITING_FOR_SEMAPHORE          | \
                                  STATES_WAITING_FOR_MUTEX              | \
                                  STATES_WAITING_FOR_CONDITION_VARIABLE | \
-                                 STATES_WAITING_FOR_JOIN_AT_EXIT       | \
+                                 STATES_WAITING_FOR_JOIN               | \
                                  STATES_WAITING_FOR_SIGNAL             | \
                                  STATES_WAITING_FOR_BARRIER            | \
                                  STATES_WAITING_FOR_BSD_WAKEUP         | \
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index f5c59d3..6eac364 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -40,15 +40,6 @@ typedef void ( *Thread_queue_Flush_callout )(
              );
 
 /**
- *  The following type defines the callout used for timeout processing
- *  methods.
- */
-typedef void ( *Thread_queue_Timeout_callout )(
-                 Objects_Id,
-                 void *
-             );
-
-/**
  *  @brief Gets a pointer to a thread waiting on the_thread_queue.
  *
  *  This function returns a pointer to a thread waiting on
diff --git a/testsuites/samples/Makefile.am b/testsuites/samples/Makefile.am
index 08455d3..de4f351 100644
--- a/testsuites/samples/Makefile.am
+++ b/testsuites/samples/Makefile.am
@@ -1,6 +1,6 @@
 ACLOCAL_AMFLAGS = -I ../aclocal
 
-_SUBDIRS = hello capture ticker base_sp unlimited minimum fileio
+_SUBDIRS = hello capture ticker base_sp unlimited minimum fileio gpio
 
 if MPTESTS
 ## base_mp is a sample multiprocessing test
diff --git a/testsuites/samples/configure.ac b/testsuites/samples/configure.ac
index e6f12d0..ac32583 100644
--- a/testsuites/samples/configure.ac
+++ b/testsuites/samples/configure.ac
@@ -60,6 +60,7 @@ AC_CHECK_SIZEOF([time_t])
 AC_CONFIG_FILES([Makefile
 base_sp/Makefile
 hello/Makefile
+gpio/Makefile
 loopback/Makefile
 minimum/Makefile
 fileio/Makefile
diff --git a/testsuites/samples/gpio/Makefile.am b/testsuites/samples/gpio/Makefile.am
new file mode 100644
index 0000000..5f06584
--- /dev/null
+++ b/testsuites/samples/gpio/Makefile.am
@@ -0,0 +1,20 @@
+
+rtems_tests_PROGRAMS = gpio
+gpio_SOURCES = init.c
+
+dist_rtems_tests_DATA = gpio.scn
+dist_rtems_tests_DATA += gpio.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+
+LINK_OBJS = $(gpio_OBJECTS)
+LINK_LIBS = $(gpio_LDLIBS)
+
+hello$(EXEEXT): $(gpio_OBJECTS) $(gpio_DEPENDENCIES)
+	@rm -f gpio$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/samples/gpio/gpio.doc b/testsuites/samples/gpio/gpio.doc
new file mode 100644
index 0000000..9812864
--- /dev/null
+++ b/testsuites/samples/gpio/gpio.doc
@@ -0,0 +1,9 @@
+#  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.org/license/LICENSE.
+#
+
+
diff --git a/testsuites/samples/gpio/gpio.scn b/testsuites/samples/gpio/gpio.scn
new file mode 100644
index 0000000..057ab6e
--- /dev/null
+++ b/testsuites/samples/gpio/gpio.scn
@@ -0,0 +1,3 @@
+*** GPIO TEST ***
+Gpio Testing
+*** END OF GPIO TEST ***
diff --git a/testsuites/samples/gpio/init.c b/testsuites/samples/gpio/init.c
new file mode 100644
index 0000000..90ab0b0
--- /dev/null
+++ b/testsuites/samples/gpio/init.c
@@ -0,0 +1,91 @@
+/*
+ *  Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+#include <bsp/beagleboneblack.h> /* Calls the BBB specific library */
+#include <rtems/gpio.h> /* Calls the BSP gpio library */
+#include <stdio.h>
+#include <stdlib.h>
+
+static void inline delay_sec(int sec)
+{
+ rtems_task_wake_after(sec*rtems_clock_get_ticks_per_second());
+}
+/* forward declarations to avoid warnings */
+rtems_task Init(rtems_task_argument argument);
+
+const char rtems_test_name[] = "Gpio Test";
+
+rtems_task Init(
+  rtems_task_argument ignored
+)
+{
+ rtems_test_begin();
+ printf("Starting Gpio Testing\n");
+ 
+ rtems_gpio_initialize();
+
+ static gpio_pin_handle led_usr0_handle,led_usr1_handle,led_usr2_handle,led_usr3_handle;
+  /*Generation of USR LED pattern*/
+ if (rtems_gpio_configure_pin_digital_out(&led_usr0_handle, BBB_LED_USR0) == GPIO_SUCCESSFUL) {
+    rtems_gpio_digital_set(&led_usr0_handle);
+    delay_sec(1);
+    rtems_gpio_digital_clear(&led_usr0_handle);
+    delay_sec(1);
+    rtems_gpio_release_pin(&led_usr0_handle);
+ }
+ if (rtems_gpio_configure_pin_digital_out(&led_usr1_handle, BBB_LED_USR1) == GPIO_SUCCESSFUL) {
+    rtems_gpio_digital_set(&led_usr1_handle);
+    delay_sec(1);
+    rtems_gpio_digital_clear(&led_usr1_handle);
+    delay_sec(1);
+    rtems_gpio_release_pin(&led_usr1_handle);
+
+ }
+ if (rtems_gpio_configure_pin_digital_out(&led_usr2_handle, BBB_LED_USR2) == GPIO_SUCCESSFUL) {
+    rtems_gpio_digital_set(&led_usr2_handle);
+    delay_sec(1);
+    rtems_gpio_digital_clear(&led_usr2_handle);
+    delay_sec(1);
+    rtems_gpio_release_pin(&led_usr2_handle);
+
+ }
+ if (rtems_gpio_configure_pin_digital_out(&led_usr3_handle, BBB_LED_USR3) == GPIO_SUCCESSFUL) {
+    rtems_gpio_digital_set(&led_usr3_handle);
+    delay_sec(1);
+    rtems_gpio_digital_clear(&led_usr3_handle);
+    delay_sec(1);
+    rtems_gpio_release_pin(&led_usr3_handle);
+
+ }
+ printf("Gpio Test Completed\n");
+ rtems_test_end();
+ exit( 0 );
+}
+
+/* NOTICE: the clock driver is enabled */
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ 
+#define CONFIGURE_MAXIMUM_TASKS            1
+#define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES    1
+ 
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE 
+
+#define CONFIGURE_EXTRA_TASK_STACKS         (2 * RTEMS_MINIMUM_STACK_SIZE)
+ 
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+ 
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
\ No newline at end of file
diff --git a/testsuites/sptests/spstkalloc02/init.c b/testsuites/sptests/spstkalloc02/init.c
index a01bc5c..9ea5db7 100644
--- a/testsuites/sptests/spstkalloc02/init.c
+++ b/testsuites/sptests/spstkalloc02/init.c
@@ -35,7 +35,7 @@ const char rtems_test_name[] = "SPSTKALLOC 2";
 
 #define TASK_COUNT 5
 
-#define PAGE_SIZE 1024
+#define STACK_HEAP_PAGE_SIZE 1024
 
 static Heap_Control task_stack_heap;
 
@@ -127,7 +127,7 @@ static rtems_task Init(rtems_task_argument argument)
 #define CONFIGURE_TASK_STACK_DEALLOCATOR task_stack_free
 #define CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
 #define CONFIGURE_TASK_STACK_FROM_ALLOCATOR(stack_size) \
-  ((stack_size) + HEAP_BLOCK_HEADER_SIZE + PAGE_SIZE - 1)
+  ((stack_size) + HEAP_BLOCK_HEADER_SIZE + STACK_HEAP_PAGE_SIZE - 1)
 
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
@@ -146,7 +146,7 @@ static void task_stack_init(size_t stack_space_size)
     &task_stack_heap,
     task_stack_space,
     sizeof(task_stack_space),
-    PAGE_SIZE
+    STACK_HEAP_PAGE_SIZE
   );
 
   rtems_test_assert(stack_space_size == CONFIGURE_STACK_SPACE_SIZE);


More information about the devel mailing list