arduino millis() and micros() equivalent

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

jschall
Posts: 31
Joined: Wed Sep 06, 2017 4:29 am
Has thanked: 2 times

arduino millis() and micros() equivalent

Postby jschall » Fri Sep 15, 2017 2:28 am

Hello, I need to provide an equivalent to the arduino millis() and micros() for a project. They need to be accurate and monotonically increasing until they wrap, and usable from any context.

I was thinking something like the following (NOTE: does not necessarily even build) - there is a low-priority thread that updates a double-buffered structure with a 64-bit representation of the system time. When millis() or micros() are called, the 64-bit representation of system time is converted to millis or micros and then truncated to 32 bits.

Any suggestions on how to avoid the 64-bit arithmetic, while retaining the guarantee that the values will increase monotonically?

Code: Select all

/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <common/timing.h>
#include <ch.h>

static thread_t* worker_thread;
static THD_WORKING_AREA(waTimingThread, 128);
static THD_FUNCTION(TimingThread, arg);

static {
    uint64_t time_ticks;
    systime_t update_systime;
} timing_state[2];

static volatile uint8_t timing_state_idx;

void timing_init(void)
{
    if (!worker_thread) {
        worker_thread = chThdCreateStatic(waTimingThread, sizeof(waTimingThread), LOWPRIO, TimingThread, NULL);
    }
}

uint32_t millis(void) {
    uint8_t idx = timing_state_idx;
    return (uint32_t)ST2MS(timing_state[idx].time_ticks + chVTTimeElapsedSinceX(timing_state[idx].update_systime));
}

uint32_t micros(void) {
    uint8_t idx = timing_state_idx;
    return (uint32_t)ST2US(timing_state[idx].time_ticks + chVTTimeElapsedSinceX(timing_state[idx].update_systime));
}

void usleep(uint32_t delay) {
    uint32_t tbegin = micros();
    while (micros()-tbegin < delay);
}

static THD_FUNCTION(TimingThread, arg)
{
    (void)arg;
    while (true) {
        uint8_t next_timing_state_idx = (timing_state_idx+1) % 2;

        systime_t systime_now = chVTGetSystemTime();
        uint32_t dt_ticks = systime_now-timing_state[timing_state_idx].update_systime;

        timing_state[next_timing_state_idx].update_systime = systime_now;
        timing_state[next_timing_state_idx].time_ticks = timing_state[timing_state_idx].time_ticks + dt_ticks;
        timing_state_idx = next_timing_state_idx;

        chThdSleepMilliseconds(1000);
    }
}

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: arduino millis() and micros() equivalent

Postby Giovanni » Sun Sep 17, 2017 8:19 pm

Hi,

System time is a monotonic counter, just make the system tick equal to 1mS.

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 45 guests