diff --git a/sys/rtt_stdio/rtt_stdio.c b/sys/rtt_stdio/rtt_stdio.c
index dec511a70a9ca41e9000859d234ed43a400a12f6..d829f77580dbab1edbeb664b7e8daff78de8dc44 100644
--- a/sys/rtt_stdio/rtt_stdio.c
+++ b/sys/rtt_stdio/rtt_stdio.c
@@ -78,6 +78,11 @@
  */
 
 #include <stdio.h>
+#if MODULE_VFS
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#endif
 #include <string.h>
 #include <rtt_stdio.h>
 
@@ -85,6 +90,10 @@
 #include "mutex.h"
 #include "xtimer.h"
 
+#if MODULE_VFS
+#include "vfs.h"
+#endif
+
 /* This parameter affects the bandwidth of both input and output. Decreasing
    it will significantly improve bandwidth at the cost of CPU time. */
 #ifndef STDIO_POLL_INTERVAL
@@ -277,6 +286,39 @@ int rtt_write(const char* buf_ptr, unsigned num_bytes) {
     return num_bytes_written;
 }
 
+#if MODULE_VFS
+
+static ssize_t rtt_stdio_vfs_read(vfs_file_t *filp, void *dest, size_t nbytes);
+static ssize_t rtt_stdio_vfs_write(vfs_file_t *filp, const void *src, size_t nbytes);
+
+/**
+ * @brief VFS file operation table for stdin/stdout/stderr
+ */
+static vfs_file_ops_t rtt_stdio_vfs_ops = {
+    .read = rtt_stdio_vfs_read,
+    .write = rtt_stdio_vfs_write,
+};
+
+static ssize_t rtt_stdio_vfs_read(vfs_file_t *filp, void *dest, size_t nbytes)
+{
+    int fd = filp->private_data.value;
+    if (fd != STDIN_FILENO) {
+        return -EBADF;
+    }
+    return rtt_read(dest, nbytes);
+}
+
+static ssize_t rtt_stdio_vfs_write(vfs_file_t *filp, const void *src, size_t nbytes)
+{
+    int fd = filp->private_data.value;
+    if (fd == STDIN_FILENO) {
+        return -EBADF;
+    }
+    return rtt_write(src, nbytes);
+}
+
+#endif
+
 void uart_stdio_init(void) {
     #ifndef RTT_STDIO_DISABLE_STDIN
     stdin_enabled = 1;
@@ -286,6 +328,22 @@ void uart_stdio_init(void) {
     blocking_stdout = 1;
     #endif
 
+#if MODULE_VFS
+    int fd;
+    fd = vfs_bind(STDIN_FILENO, O_RDONLY, &rtt_stdio_vfs_ops, (void *)STDIN_FILENO);
+    if (fd < 0) {
+        /* How to handle errors on init? */
+    }
+    fd = vfs_bind(STDOUT_FILENO, O_WRONLY, &rtt_stdio_vfs_ops, (void *)STDOUT_FILENO);
+    if (fd < 0) {
+        /* How to handle errors on init? */
+    }
+    fd = vfs_bind(STDERR_FILENO, O_WRONLY, &rtt_stdio_vfs_ops, (void *)STDERR_FILENO);
+    if (fd < 0) {
+        /* How to handle errors on init? */
+    }
+#endif
+
     /* the mutex should start locked */
     mutex_lock(&_rx_mutex);
 }