diff --git a/GPIO/gpiolib/ring.gpiolib.c b/GPIO/gpiolib/ring.gpiolib.c
new file mode 100644
index 0000000000000000000000000000000000000000..59e3fd22d5eba859948f8996672d85bc1864509c
--- /dev/null
+++ b/GPIO/gpiolib/ring.gpiolib.c
@@ -0,0 +1,51 @@
+//
+// ring.gpiolib.c
+//
+// gpiolib ring oscillator test
+//    gcc ring.gpiolib.c -o ring.gpiolib
+//
+// Neil Gershenfeld 12/19/20
+//
+// This work may be reproduced, modified, distributed,
+// performed, and displayed for any purpose, but must
+// acknowledge this project. Copyright is retained and
+// must be preserved. The work is provided as is; no
+// warranty is provided, and users accept all liability.
+//
+//
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <linux/gpio.h>
+#include <sys/ioctl.h>
+int main(int argc,char *argv[]) {
+   int gpio;
+   struct gpiochip_info chip_info;
+   struct gpiohandle_request request_in,request_out;
+   struct gpiohandle_data data_in,data_out;
+   gpio = open("/dev/gpiochip0",0);
+   ioctl(gpio,GPIO_GET_CHIPINFO_IOCTL,&chip_info);
+   printf("name: %s, label: %s, lines: %u\n",
+      chip_info.name,chip_info.label,chip_info.lines);
+   request_out.lineoffsets[0] = 23;
+   request_out.lines = 1;
+   request_out.flags = GPIOHANDLE_REQUEST_OUTPUT;
+   strcpy(request_out.consumer_label,"ring.gpiolib out");
+   ioctl(gpio,GPIO_GET_LINEHANDLE_IOCTL,&request_out);
+   request_in.lineoffsets[0] = 24;
+   request_in.lines = 1;
+   request_in.flags = GPIOHANDLE_REQUEST_INPUT;
+   strcpy(request_in.consumer_label,"ring.gpiolib in");
+   ioctl(gpio,GPIO_GET_LINEHANDLE_IOCTL,&request_in);
+   while (1) {
+      ioctl(request_in.fd,GPIOHANDLE_GET_LINE_VALUES_IOCTL,&data_in);
+      if (data_in.values[0] == 0) {
+         data_out.values[0] = 1;
+         ioctl(request_out.fd,GPIOHANDLE_SET_LINE_VALUES_IOCTL,&data_out);
+         }
+      else {
+         data_out.values[0] = 0;
+         ioctl(request_out.fd,GPIOHANDLE_SET_LINE_VALUES_IOCTL,&data_out);
+         }
+      }
+   }