diff --git a/make/source.mk b/make/source.mk
index ed430360b1..4a28c95c0b 100644
--- a/make/source.mk
+++ b/make/source.mk
@@ -15,6 +15,7 @@ COMMON_SRC = \
common/printf.c \
common/streambuf.c \
common/string_light.c \
+ common/strtol.c \
common/time.c \
common/typeconversion.c \
config/config_eeprom.c \
diff --git a/src/main/common/strtol.c b/src/main/common/strtol.c
new file mode 100644
index 0000000000..18300d5623
--- /dev/null
+++ b/src/main/common/strtol.c
@@ -0,0 +1,131 @@
+/* Copyright (C) 2002 Manuel Novoa III
+ * From my (incomplete) stdlib library for linux and (soon) elks.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see
+ * .
+
+ * Adapted for Betaflight by Petr Ledvina, 2018
+
+ */
+
+
+#include
+#include
+
+#include "common/utils.h"
+
+#define _STRTO_ENDPTR 1
+
+unsigned long _strto_l(const char * str, char ** endptr, int base, int sflag)
+{
+ unsigned long number, cutoff;
+#if _STRTO_ENDPTR
+ const char *fail_char;
+#define SET_FAIL(X) fail_char = (X)
+#else
+#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
+#endif
+ unsigned char negative, digit, cutoff_digit;
+
+ SET_FAIL(str);
+
+ while (isspace(*str)) { /* Skip leading whitespace. */
+ ++str;
+ }
+
+ /* Handle optional sign. */
+ negative = 0;
+ switch (*str) {
+ case '-':
+ negative = 1; /* Fall through to increment str. */
+ FALLTHROUGH;
+ case '+':
+ ++str;
+ }
+
+ if (!base || base == 16 || base == 2) { /* Either dynamic (base = 0) or base with 0[xb] prefix. */
+ if (*str == '0') {
+ SET_FAIL(++str);
+ if ((!base || base == 16) && tolower(*str) == 'x') {
+ ++str;
+ base = 16;
+ } else if ((!base || base == 2) && tolower(*str) == 'b') {
+ ++str;
+ base = 2;
+ } else if(!base) {
+ base = 8;
+ }
+ }
+ }
+
+ number = 0;
+
+ if (((unsigned)(base - 2)) < 35) { /* Legal base. */
+ cutoff_digit = ULONG_MAX % base;
+ cutoff = ULONG_MAX / base;
+ do {
+ digit = ( (*str - '0') <= 9)
+ ? /* 0..9 */ (*str - '0')
+ : /* else */ (((0x20 | *str) >= 'a') /* WARNING: assumes ascii. */
+ ? /* >= A/a */ ((0x20 | *str) - ('a' - 10))
+ : /* else */ 40 /* bad value */);
+
+ if (digit >= base) {
+ break;
+ }
+
+ SET_FAIL(++str);
+
+ if ((number > cutoff)
+ || ((number == cutoff) && (digit > cutoff_digit))) {
+ number = ULONG_MAX;
+ negative &= sflag;
+ } else {
+ number = number * base + digit;
+ }
+ } while (1);
+ }
+
+#if _STRTO_ENDPTR
+ if (endptr) {
+ *endptr = (char *) fail_char;
+ }
+#endif
+
+ {
+ unsigned long tmp = (negative
+ ? ((unsigned long)(-(1+LONG_MIN)))+1
+ : LONG_MAX);
+ if (sflag && (number > tmp)) {
+ number = tmp;
+ }
+ }
+
+ return negative ? (unsigned long)(-((long)number)) : number;
+}
+
+long strtol(const char * str, char ** endptr, int base)
+{
+ return _strto_l(str, endptr, base, 1);
+}
+
+unsigned long strtoul(const char * str, char ** endptr, int base)
+{
+ return _strto_l(str, endptr, base, 0);
+}
+
+int atoi(const char *str)
+{
+ return strtol(str, NULL, 10);
+}