diff --git a/libraries/AP_HAL/Scheduler.h b/libraries/AP_HAL/Scheduler.h
index 8606a31cdbebe02b6494ef86a5bda153f06f9e3c..7238370da659670f6ae6632f9a35932b2af89047 100644
--- a/libraries/AP_HAL/Scheduler.h
+++ b/libraries/AP_HAL/Scheduler.h
@@ -3,6 +3,7 @@
 #define __AP_HAL_SCHEDULER_H__
 
 #include "AP_HAL_Namespace.h"
+#include "AP_HAL_Boards.h"
 
 #include <stdint.h>
 #include <AP_Progmem.h>
@@ -14,6 +15,11 @@ public:
     virtual void     delay(uint16_t ms) = 0;
     virtual uint32_t millis() = 0;
     virtual uint32_t micros() = 0;
+#if HAL_CPU_CLASS >= HAL_CPU_CLASS_150
+    // offer non-wrapping 64 bit versions on faster CPUs
+    virtual uint64_t millis64() = 0;
+    virtual uint64_t micros64() = 0;
+#endif
     virtual void     delay_microseconds(uint16_t us) = 0;
     virtual void     register_delay_callback(AP_HAL::Proc,
                                              uint16_t min_time_ms) = 0;
diff --git a/libraries/AP_HAL_AVR_SITL/Scheduler.cpp b/libraries/AP_HAL_AVR_SITL/Scheduler.cpp
index db0d172824942e03009f7024eaed750661a811fc..5fa731f58a9e793366fc0141ec4ed21965b73451 100644
--- a/libraries/AP_HAL_AVR_SITL/Scheduler.cpp
+++ b/libraries/AP_HAL_AVR_SITL/Scheduler.cpp
@@ -70,52 +70,64 @@ double SITLScheduler::_cyg_sec()
 }
 #endif
 
-uint32_t SITLScheduler::_micros() 
+uint64_t SITLScheduler::_micros64() 
 {
 #ifdef __CYGWIN__
-	return (uint32_t)(_cyg_sec() * 1.0e6);
+	return (uint64_t)(_cyg_sec() * 1.0e6);
 #else   
 	struct timeval tp;
 	gettimeofday(&tp,NULL);
-	return 1.0e6*((tp.tv_sec + (tp.tv_usec*1.0e-6)) - 
+	uint64_t ret = 1.0e6*((tp.tv_sec + (tp.tv_usec*1.0e-6)) - 
 		      (_sketch_start_time.tv_sec +
 		       (_sketch_start_time.tv_usec*1.0e-6)));
+    return ret;
 #endif
 }
 
+uint64_t SITLScheduler::micros64() 
+{
+    return _micros64();
+}
+
 uint32_t SITLScheduler::micros() 
 {
-    return _micros();
+    return micros64() & 0xFFFFFFFF;
 }
 
-uint32_t SITLScheduler::millis() 
+uint64_t SITLScheduler::millis64() 
 {
 #ifdef __CYGWIN__
 	// 1000 ms in a second
-	return (uint32_t)(_cyg_sec() * 1000);
+	return (uint64_t)(_cyg_sec() * 1000);
 #else
 	struct timeval tp;
 	gettimeofday(&tp,NULL);
-	return 1.0e3*((tp.tv_sec + (tp.tv_usec*1.0e-6)) - 
+	uint64_t ret = 1.0e3*((tp.tv_sec + (tp.tv_usec*1.0e-6)) - 
 		      (_sketch_start_time.tv_sec +
 		       (_sketch_start_time.tv_usec*1.0e-6)));
+    return ret;
 #endif
 }
 
+uint32_t SITLScheduler::millis() 
+{
+    return millis64() & 0xFFFFFFFF;
+}
+
 void SITLScheduler::delay_microseconds(uint16_t usec) 
 {
-	uint32_t start = micros();
-	while (micros() - start < usec) {
-		usleep(usec - (micros() - start));
+	uint64_t start = micros64();
+	while (micros64() - start < usec) {
+		usleep(usec - (micros64() - start));
 	}
 }
 
 void SITLScheduler::delay(uint16_t ms)
 {
-	uint32_t start = micros();
+	uint64_t start = micros64();
     
     while (ms > 0) {
-        while ((micros() - start) >= 1000) {
+        while ((micros64() - start) >= 1000) {
             ms--;
             if (ms == 0) break;
             start += 1000;
diff --git a/libraries/AP_HAL_AVR_SITL/Scheduler.h b/libraries/AP_HAL_AVR_SITL/Scheduler.h
index bd6e33aba9a4d161a44a7261594169d9587c9687..8719e723e02e5d464815ade9d7a7ef4f9869c96b 100644
--- a/libraries/AP_HAL_AVR_SITL/Scheduler.h
+++ b/libraries/AP_HAL_AVR_SITL/Scheduler.h
@@ -19,6 +19,8 @@ public:
     void     delay(uint16_t ms);
     uint32_t millis();
     uint32_t micros();
+    uint64_t millis64();
+    uint64_t micros64();
     void     delay_microseconds(uint16_t us);
     void     register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms);
 
@@ -43,7 +45,7 @@ public:
     void     sitl_end_atomic();
 
     // callable from interrupt handler
-    static uint32_t _micros();
+    static uint64_t _micros64();
     static void timer_event() { _run_timer_procs(true); _run_io_procs(true); }
 
 private:
diff --git a/libraries/AP_HAL_AVR_SITL/sitl_ins.cpp b/libraries/AP_HAL_AVR_SITL/sitl_ins.cpp
index 06714a84c1592e41e24ca491f3cba60d9b4cf8f9..6792b00540d4ff954e339974382cfc929e00122c 100644
--- a/libraries/AP_HAL_AVR_SITL/sitl_ins.cpp
+++ b/libraries/AP_HAL_AVR_SITL/sitl_ins.cpp
@@ -52,7 +52,7 @@ float SITL_State::_gyro_drift(void)
 		return 0;
 	}
 	double period  = _sitl->drift_time * 2;
-	double minutes = fmod(_scheduler->_micros() / 60.0e6, period);
+	double minutes = fmod(_scheduler->micros64() / 60.0e6, period);
 	if (minutes < period/2) {
 		return minutes * ToRad(_sitl->drift_speed);
 	}
diff --git a/libraries/AP_HAL_Empty/Scheduler.cpp b/libraries/AP_HAL_Empty/Scheduler.cpp
index f2a4e16f56aa7c16305fe0e1009b09eb5cd5b095..c12026c4883c83829237b0bdf779a9329087310d 100644
--- a/libraries/AP_HAL_Empty/Scheduler.cpp
+++ b/libraries/AP_HAL_Empty/Scheduler.cpp
@@ -14,14 +14,22 @@ void EmptyScheduler::init(void* machtnichts)
 void EmptyScheduler::delay(uint16_t ms)
 {}
 
-uint32_t EmptyScheduler::millis() {
+uint64_t EmptyScheduler::millis64() {
     return 10000;
 }
 
-uint32_t EmptyScheduler::micros() {
+uint64_t EmptyScheduler::micros64() {
     return 200000;
 }
 
+uint32_t EmptyScheduler::millis() {
+    return millis64();
+}
+
+uint32_t EmptyScheduler::micros() {
+    return micros64();
+}
+
 void EmptyScheduler::delay_microseconds(uint16_t us)
 {}
 
diff --git a/libraries/AP_HAL_Empty/Scheduler.h b/libraries/AP_HAL_Empty/Scheduler.h
index 75df768dc834282b0b19a605d426bbceb3dde72a..2afcbf460a141859c9e1553c22235ecf999a363c 100644
--- a/libraries/AP_HAL_Empty/Scheduler.h
+++ b/libraries/AP_HAL_Empty/Scheduler.h
@@ -11,6 +11,8 @@ public:
     void     delay(uint16_t ms);
     uint32_t millis();
     uint32_t micros();
+    uint64_t millis64();
+    uint64_t micros64();
     void     delay_microseconds(uint16_t us);
     void     register_delay_callback(AP_HAL::Proc,
                 uint16_t min_time_ms);
diff --git a/libraries/AP_HAL_PX4/Scheduler.cpp b/libraries/AP_HAL_PX4/Scheduler.cpp
index b097ba04690755498b38013d13626ca139d388b2..856d684ef48bb6b7beea9f92f3f8d3418c390b17 100644
--- a/libraries/AP_HAL_PX4/Scheduler.cpp
+++ b/libraries/AP_HAL_PX4/Scheduler.cpp
@@ -76,6 +76,16 @@ void PX4Scheduler::init(void *unused)
 	pthread_create(&_io_thread_ctx, &thread_attr, (pthread_startroutine_t)&PX4::PX4Scheduler::_io_thread, this);
 }
 
+uint64_t PX4Scheduler::micros64() 
+{
+    return hrt_absolute_time();
+}
+
+uint64_t PX4Scheduler::millis64() 
+{
+    return micros64() / 1000;
+}
+
 uint32_t PX4Scheduler::micros() 
 {
     return (uint32_t)(hrt_absolute_time() - _sketch_start_time);
@@ -83,7 +93,7 @@ uint32_t PX4Scheduler::micros()
 
 uint32_t PX4Scheduler::millis() 
 {
-    return hrt_absolute_time() / 1000;
+    return millis64() & 0xFFFFFFFF;
 }
 
 /**
@@ -106,9 +116,9 @@ void PX4Scheduler::delay_microseconds(uint16_t usec)
         perf_end(_perf_delay);
         return;
     }
-	uint32_t start = micros();
-    uint32_t dt;
-	while ((dt=(micros() - start)) < usec) {
+	uint64_t start = micros64();
+    uint64_t dt;
+	while ((dt=(micros64() - start)) < usec) {
 		up_udelay(usec - dt);
 	}
     perf_end(_perf_delay);
@@ -121,9 +131,9 @@ void PX4Scheduler::delay(uint16_t ms)
         return;
     }
     perf_begin(_perf_delay);
-	uint64_t start = hrt_absolute_time();
+	uint64_t start = micros64();
     
-    while ((hrt_absolute_time() - start)/1000 < ms && 
+    while ((micros64() - start)/1000 < ms && 
            !_px4_thread_should_exit) {
         delay_microseconds_semaphore(1000);
         if (_min_delay_cb_ms <= ms) {
diff --git a/libraries/AP_HAL_PX4/Scheduler.h b/libraries/AP_HAL_PX4/Scheduler.h
index b88b997dd15c8e2b2ddafe64bfca5891da718293..891eeb345672ec51f19715b77b9766559fc6d32f 100644
--- a/libraries/AP_HAL_PX4/Scheduler.h
+++ b/libraries/AP_HAL_PX4/Scheduler.h
@@ -29,6 +29,8 @@ public:
     void     delay(uint16_t ms);
     uint32_t millis();
     uint32_t micros();
+    uint64_t millis64();
+    uint64_t micros64();
     void     delay_microseconds(uint16_t us);
     void     register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms);
     void     register_timer_process(AP_HAL::MemberProc);