You could also use a 1kHz ticker interrupt, during which either the measurement is done, or a signal is set for a high priority RTOS thread which then does the measurements. I would have no idea where your new delay is coming from, but I doubt it is garbage collection.
The RTOS back-end is precompiled, you cannot see the source. The mbed-src library is complete: it is all open source and contains all source code, nothing precompiled there.
Ran a quick test using:
#include "mbed.h"
#include "rtos.h"
Timer timey;
volatile int previous;
void blink(void const *n) {
int cur_time = timey.read_us();
printf("Took %dus\r\n", cur_time - previous);
previous = cur_time;
}
int main(void) {
RtosTimer led_1_timer(blink, osTimerPeriodic, (void *)0);
timey.start();
led_1_timer.start(400);
Thread::wait(osWaitForever);
}
Not 1 ms, I tried that first, but that wasn't one of my smarter ideas, trying to output at 1kHz to serial terminal. The first one is 3us too long, the second 1us too short, after that all exactly correct.
Since it might be compensating each other (some 20us too long, others 20us too short, I also ran a simple check where it only prints errors:
#include "mbed.h"
#include "rtos.h"
Timer timey;
volatile int previous;
Serial PC(USBTX, USBRX);
void blink(void const *n) {
int cur_time = timey.read_us();
if ((cur_time - previous > 1001) || (cur_time-previous < 999))
PC.putc('E');
previous = cur_time;
}
int main(void) {
printf("Start\r\n\n");
RtosTimer led_1_timer(blink, osTimerPeriodic, (void *)0);
timey.start();
led_1_timer.start(1);
Thread::wait(osWaitForever);
}
Since the LPC1768 has a FIFO on its serial (without the proper registers to really use it correctly though), this goes fine as long as the number of errors is limitted, if it runs out of space on the FIFO it will need to wait until the character is sent, resulting in a too long period, etc. This prints a single 'E' for me. If I check if it is larger or smaller than 1000 (ie, not exactly 1000), it does write alot of 'E's. But that is really nitpicking. So to me it looks like the basic functionality of the timer works fine. So then it looks to be related to your other code. (That the first ones aren't exaclty what is expected is correct btw, since it starts the timer first, and then the RTOS timer, so the first measurement includes overhead from the RTOS times start. And not to mention that the previous time is unitialized, so it might be 0, might be something else).
Hello there,
we are using a mbed 1768 module for a data processing application where we need a precise cycle of 1 ms. So we used an RtosTimer to call our routine in 1 ms cycles. We checked the accuracy using a scope and by reading a µs-timer, so far without problems.
In our RtosTimer-callback-routine we read a Timer.read_us() value and check the time difference to the previous call, since our software usually needs 13 or 14 cycles to compute final data, we usually read values of 13000 or 14000 µs, with a deviation of only 5 to 10 µs - which is good.
Now we were collecting these time differences over a period of a few minutes and found strange deviations: some every 23 seconds, our time stamps - which should be a factor of 1000 µs - shows a random deviation, like 14325 µs, the next cycle with 14625 µs etc. and after that, the time diff is again precisely 13000 or 14000.
We were trying to find details on how RtosTimer... and Timer... work in detail, but we were not able to find anything. I assume that these routine utilize the 1768 timers, but how ?
The behaviour looks a bit like a frequency sweep : it looks like the "sweep" - or whatever it is - occurs every 23 sec, then the "other" frequency would be off by 0.0435 Hz
Now we have two assumptions: 1. if the RtosTimer is accurate 1ms, then the Timer.read_us() reads sometime wrong data 2. if the Timer.read_us() works accurate, then our Rtos callback is sometimes delays
Can anyone help us to understand the details of how these timers work ? thanks in advance Matthias