Arduino millis() is based on a timer that trips an overflow interrupt at very close to 1 KHz, or 1 millisecond. To achieve the same thing, I suggest you setup a timer on the ARM platform and update a volatile unsigned long variable with a counter. That will be the equivalent of millis().
Here is what millis() is doing behind the scenes:
SIGNAL(TIMER0_OVF_vect)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}
unsigned long millis()
{
unsigned long m;
uint8_t oldSREG = SREG;
// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;
return m;
}
Coming from the embedded world, arguably the first thing you should do when starting a project on a new platform is establish clocks and get a timer interrupt going at a prescribed rate. That is the "Hello World" of embedded systems. ;) If you choose to do this at 1 KHz, you're most of the way there.
Answer from TomServo on Stack Overflowc - Equivalent to Arduino millis() - Stack Overflow
How to Code Millis
Using millis() for timing. A beginners guide
Help with code - using millis() instead of a delay
Videos
Arduino millis() is based on a timer that trips an overflow interrupt at very close to 1 KHz, or 1 millisecond. To achieve the same thing, I suggest you setup a timer on the ARM platform and update a volatile unsigned long variable with a counter. That will be the equivalent of millis().
Here is what millis() is doing behind the scenes:
SIGNAL(TIMER0_OVF_vect)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}
unsigned long millis()
{
unsigned long m;
uint8_t oldSREG = SREG;
// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;
return m;
}
Coming from the embedded world, arguably the first thing you should do when starting a project on a new platform is establish clocks and get a timer interrupt going at a prescribed rate. That is the "Hello World" of embedded systems. ;) If you choose to do this at 1 KHz, you're most of the way there.
#include <time.h>
unsigned int millis () {
struct timespec t ;
clock_gettime ( CLOCK_MONOTONIC_RAW , & t ) ; // change CLOCK_MONOTONIC_RAW to CLOCK_MONOTONIC on non linux computers
return t.tv_sec * 1000 + ( t.tv_nsec + 500000 ) / 1000000 ;
}
or
#include <sys/time.h>
unsigned int millis () {
struct timeval t ;
gettimeofday ( & t , NULL ) ;
return t.tv_sec * 1000 + ( t.tv_usec + 500 ) / 1000 ;
}
The gettimeofday() version probably does not work on non linux computers.
The clock_gettime() version probably does not work with old C compilers.
The arduino millis() returns unsigned long, 32 bit unsigned integer. Most computers are 32 bit or 64 bit, so there is no need to use long except on 16 bit computers like arduino, so these versions return unsigned int. If you want to measure a time period longer than 50 days in milliseconds, or if you want the number of milliseconds since the beginning of unix in 1970, you need a long long (64 bit) integer.
If a computer clock has the incorrect time, the operating system or system administrator or program which synchonizes the computer clock with internet clocks may change the computer clock to the correct time. This will affect these functions, especially the gettimeofday() version. Usually there is a big change in the computer clock when the computer boots, connects to the network, and synchonizes the computer clock with the network time server. But most programs are not running this early in the boot process, and thus are not affected. Usually other changes to the computer clock are very small, and the effect on other programs is very small. So usually changes to the computer clock are not a problem.
The clock_gettime() requires a clock id.
CLOCK_MONOTONIC is not affected by discontinuous jumps in the system time, but is affected by incremental adjustments, and does not count time computer is suspended.
CLOCK_MONOTONIC_RAW is linux only, not affected by discontinuous jumps in the system time, not affected by incremental adjustments, does not count time computer is suspended.
CLOCK_BOOTTIME is linux only, not affected by discontinuous jumps in the system time, but is affected by incremental adjustments, does count time computer is suspended. It counts the time since the computer booted.
CLOCK_REALTIME is affected by discontinuous jumps in the system time, and by incremental adjustments. It does count the time the computer is suspended. It counts standard unix time (time since the beginning of unix in 1970).
I think CLOCK_MONOTONIC_RAW is the best choice for linux, and CLOCK_MONOTONIC is the best choice for non linux. Usually millisecond time is used to measure short periods of time, like how long it takes for part of a computer program to run. In a short period of time, there will probably be no changes to the computer clock, and the computer will probably not be suspended, so any clock id will work, so the choice of clock id is not important.
Precise time measurements are unreliable on multitasking computers because the time measurement might be interrupted. Errors are usually small. Sometimes this is a problem, and sometimes it isn't. If you need more precise time measurements, you need dedicated hardware which cannot be interrupted. Some computers have such hardware built in. For example, if a program uses software pwm, changes to the output will be delayed if the computer is interrupted at the time the computer needs to change the output. But if the program uses hardware pwm, the hardware pwm controller cannot be interrupted, and will change the output at the correct time.
Tested on a raspberry pi.