diff --git a/core/include/sched.h b/core/include/sched.h
index ee3b650cccbcd78a65017157608ea0a50e08cad4..f9d37a280388c0119101afca6463866c70aadd59 100644
--- a/core/include/sched.h
+++ b/core/include/sched.h
@@ -96,6 +96,35 @@
  */
 typedef struct _thread thread_t;
 
+/**
+ * @name Thread states supported by RIOT
+ * @{
+ */
+typedef enum {
+    STATUS_STOPPED,                 /**< has terminated                       */
+    STATUS_SLEEPING,                /**< sleeping                             */
+    STATUS_MUTEX_BLOCKED,           /**< waiting for a locked mutex           */
+    STATUS_RECEIVE_BLOCKED,         /**< waiting for a message                */
+    STATUS_SEND_BLOCKED,            /**< waiting for message to be delivered  */
+    STATUS_REPLY_BLOCKED,           /**< waiting for a message response       */
+    STATUS_FLAG_BLOCKED_ANY,        /**< waiting for any flag from flag_mask  */
+    STATUS_FLAG_BLOCKED_ALL,        /**< waiting for all flags in flag_mask   */
+    STATUS_MBOX_BLOCKED,            /**< waiting for get/put on mbox          */
+    STATUS_COND_BLOCKED,            /**< waiting for a condition variable     */
+    STATUS_RUNNING,                 /**< currently running                    */
+    STATUS_PENDING,                 /**< waiting to be scheduled to run       */
+    STATUS_NUMOF                    /**< number of supported thread states    */
+} thread_state_t;
+/** @} */
+
+/**
+ * @name Helpers to work with thread states
+ * @{
+ */
+#define STATUS_ON_RUNQUEUE      STATUS_RUNNING  /**< to check if on run queue:
+                                                 `st >= STATUS_ON_RUNQUEUE`   */
+#define STATUS_NOT_FOUND ((thread_state_t)-1)   /**< Describes an illegal thread status */
+/** @} */
 /**
  * @def SCHED_PRIO_LEVELS
  * @brief The number of thread priority levels
@@ -117,7 +146,7 @@ int sched_run(void);
  *                          targeted process
  * @param[in]   status      The new status of this thread
  */
-void sched_set_status(thread_t *process, unsigned int status);
+void sched_set_status(thread_t *process, thread_state_t status);
 
 /**
  * @brief       Yield if approriate.
diff --git a/core/include/thread.h b/core/include/thread.h
index 5d5ebaa558c3b730089b9fe2326695aa1ec390e6..418b885cff867f0601d305d6819890f3dee251ce 100644
--- a/core/include/thread.h
+++ b/core/include/thread.h
@@ -133,40 +133,6 @@
  extern "C" {
 #endif
 
-/* Thread states */
-/**
- * @name Special meaning thread states
- * @{
- */
-#define STATUS_NOT_FOUND        (-1)    /**< Describes an illegal thread status */
-/** @} */
-
-/**
- * @name Blocked thread states
- * @{
- */
-#define STATUS_STOPPED              0   /**< has terminated                     */
-#define STATUS_SLEEPING             1   /**< sleeping                           */
-#define STATUS_MUTEX_BLOCKED        2   /**< waiting for a locked mutex         */
-#define STATUS_RECEIVE_BLOCKED      3   /**< waiting for a message              */
-#define STATUS_SEND_BLOCKED         4   /**< waiting for message to be delivered*/
-#define STATUS_REPLY_BLOCKED        5   /**< waiting for a message response     */
-#define STATUS_FLAG_BLOCKED_ANY     6   /**< waiting for any flag from flag_mask*/
-#define STATUS_FLAG_BLOCKED_ALL     7   /**< waiting for all flags in flag_mask */
-#define STATUS_MBOX_BLOCKED         8   /**< waiting for get/put on mbox        */
-#define STATUS_COND_BLOCKED         9   /**< waiting for a condition variable   */
-/** @} */
-
-/**
- * @name Queued thread states
- * @{
- */
-#define STATUS_ON_RUNQUEUE      STATUS_RUNNING  /**< to check if on run queue:
-                                                 `st >= STATUS_ON_RUNQUEUE`             */
-#define STATUS_RUNNING         10               /**< currently running                  */
-#define STATUS_PENDING         11               /**< waiting to be scheduled to run     */
-/** @} */
-
 /**
  * @brief Prototype for a thread entry function
  */
@@ -177,7 +143,7 @@ typedef void *(*thread_task_func_t)(void *arg);
  */
 struct _thread {
     char *sp;                       /**< thread's stack pointer         */
-    uint8_t status;                 /**< thread's status                */
+    thread_state_t status;          /**< thread's status                */
     uint8_t priority;               /**< thread's priority              */
 
     kernel_pid_t pid;               /**< thread's process id            */
diff --git a/core/sched.c b/core/sched.c
index d78f1e0dcafb51c9f5a3c6001a6a763124685f62..a5a8d38fb558749c75247d5f19f42a1c8aff3188 100644
--- a/core/sched.c
+++ b/core/sched.c
@@ -158,7 +158,7 @@ void sched_register_cb(void (*callback)(uint32_t, uint32_t))
 }
 #endif
 
-void sched_set_status(thread_t *process, unsigned int status)
+void sched_set_status(thread_t *process, thread_state_t status)
 {
     if (status >= STATUS_ON_RUNQUEUE) {
         if (!(process->status >= STATUS_ON_RUNQUEUE)) {
diff --git a/core/thread.c b/core/thread.c
index 6f7a71362e906a6cb9992e7a66d817b16380334e..efc2dd56d67d1b56f9aa17f754d252d23f984434 100644
--- a/core/thread.c
+++ b/core/thread.c
@@ -41,7 +41,7 @@ volatile thread_t *thread_get(kernel_pid_t pid)
 int thread_getstatus(kernel_pid_t pid)
 {
     volatile thread_t *t = thread_get(pid);
-    return t ? (int) t->status : STATUS_NOT_FOUND;
+    return t ? (int)t->status : (int)STATUS_NOT_FOUND;
 }
 
 const char *thread_getname(kernel_pid_t pid)
@@ -93,7 +93,7 @@ int thread_wakeup(kernel_pid_t pid)
     }
 
     irq_restore(old_state);
-    return STATUS_NOT_FOUND;
+    return (int)STATUS_NOT_FOUND;
 }
 
 void thread_yield(void)
@@ -224,7 +224,7 @@ kernel_pid_t thread_create(char *stack, int stacksize, char priority, int flags,
 #endif
 
     cb->priority = priority;
-    cb->status = 0;
+    cb->status = STATUS_STOPPED;
 
     cb->rq_entry.next = NULL;
 
diff --git a/core/thread_flags.c b/core/thread_flags.c
index 314b77a29e4c5187fda6dd17c3b2ed6b212be870..0143a91341dcab7a2a475958fcc6ce91c7d4cf5e 100644
--- a/core/thread_flags.c
+++ b/core/thread_flags.c
@@ -100,7 +100,7 @@ thread_flags_t thread_flags_wait_all(thread_flags_t mask)
 
 inline int __attribute__((always_inline)) thread_flags_wake(thread_t *thread)
 {
-    unsigned wakeup = 0;
+    unsigned wakeup;
     thread_flags_t mask = (uint16_t)(unsigned)thread->wait_data;
     switch(thread->status) {
         case STATUS_FLAG_BLOCKED_ANY:
@@ -109,6 +109,9 @@ inline int __attribute__((always_inline)) thread_flags_wake(thread_t *thread)
         case STATUS_FLAG_BLOCKED_ALL:
             wakeup = ((thread->flags & mask) == mask);
             break;
+        default:
+            wakeup = 0;
+            break;
     }
 
     if (wakeup) {
diff --git a/sys/cpp11-compat/thread.cpp b/sys/cpp11-compat/thread.cpp
index 6fba13af13ffeab6992abc677cd6b9dccffbc8b6..1d8046398151718d4d22cefb1b2971063cf9b168 100644
--- a/sys/cpp11-compat/thread.cpp
+++ b/sys/cpp11-compat/thread.cpp
@@ -42,7 +42,7 @@ void thread::join() {
   }
   if (joinable()) {
     auto status = thread_getstatus(m_handle);
-    if (status != STATUS_NOT_FOUND && status != STATUS_STOPPED) {
+    if (status != (int)STATUS_NOT_FOUND && status != STATUS_STOPPED) {
       m_data->joining_thread = sched_active_pid;
       thread_sleep();
     }
diff --git a/sys/ps/ps.c b/sys/ps/ps.c
index 4da82ea97e91313e0893b929b5048a8ace98786f..0fd47be49c14748d8a717c455501eaf348ab8a21 100644
--- a/sys/ps/ps.c
+++ b/sys/ps/ps.c
@@ -96,7 +96,7 @@ void ps(void)
         thread_t *p = (thread_t *)sched_threads[i];
 
         if (p != NULL) {
-            int state = p->status;                                                 /* copy state */
+            thread_state_t state = p->status;                                      /* copy state */
             const char *sname = state_names[state];                                /* get state name */
             const char *queued = &queued_name[(int)(state >= STATUS_ON_RUNQUEUE)]; /* get queued flag */
 #ifdef DEVELHELP