Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent to Arduino millis()

Tags:

c

arm

I am currently working on the integration of a "shunt" type sensor on an electronic board. My choice was on a Linear (LTC2947), unfortunately it only has an Arduino driver. I have to translate everything in C under Linux to be compatible with my microprocessor (APQ8009 ARM Cortex-A7). I have a small question about one of the functions:

int16_t LTC2947_wake_up() //Wake up LTC2947 from shutdown mode and measure the wakeup time
{
   byte data[1];
   unsigned long wakeupStart = millis(), wakeupTime;
   LTC2947_WR_BYTE(LTC2947_REG_OPCTL, 0);
   do
   {
      delay(1);
      LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data); 
      wakeupTime = millis() - wakeupStart;
      if (data[0] == 0) //! check if we are in idle mode
      {
         return wakeupTime;
      }
     if (wakeupTime > 200)
     {
  //! failed to wake up due to timeout, return -1
        return -1;
     }
   }
   while (true);
}

After finding usleep() as equivalent for delay(), I can not find it for millis() in C. Can you help me translate this function please?

like image 257
Lauraaaaaaaaa Avatar asked Oct 15 '25 07:10

Lauraaaaaaaaa


1 Answers

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.

like image 151
TomServo Avatar answered Oct 16 '25 23:10

TomServo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!