Increasing RTOS Tick Rate, >1000Hz

spanky
Posts: 13
Joined: Thu Nov 30, 2017 6:35 pm

Re: Increasing RTOS Tick Rate, >1000Hz

Postby spanky » Fri Dec 15, 2017 4:01 am

One of the I2C devices is an MPU9250 that I'm trying to read very frequently, so this seems like an appropriate thread, although I'm happy to create a new one.

I tried implementing the new timer method from that documentation link and that is considerably simpler (thanks).

The main issue here is that although I can trigger a block of code to run regularly at 1ms intervals, I cant quite read the sensor in that time (although I certainly should be able to do that)

The timeout errors are a sort of side effect of this fast/intensive reading. I can split this off to another thread, but I think its all related.

Apparently the i2c timeout errors only happen when the display task is run on CORE_0. This has me baffled. This behavior is similar if I am running in a standard task or with the above timer implementations.
Display>>>CORE_0, Sensor/timer>>>CORE_0 ==> timeouts
Display>>>CORE_0, Sensor/timer>>>CORE_1 ==> timeouts
Display>>>CORE_1, Sensor/timer>>>CORE_0 ==> works
Display>>>CORE_1, Sensor/timer>>>CORE_1 ==> works


If you run either one of the two I2C buses only, do you still get timeouts?
No errors when only running one or the other. See the table above for more specifics when running both tasks.
If you run the I2C operations from a normal priority task (ie slower and with less accurate timing), do you still get timeouts?
Similar issues if I run the tasks without delays (see above). It appears that i2c_master_cmd_begin() allows a task switch, so my sensor loop is basically running as fast as it can:

Code: Select all

while(true) {
    value = readSensor(); //read from the I2C device on I2C_NUM_1
}
or, if its run as a timer, that read line is just wrapped in the callback:

Code: Select all

void timer_cb(void* arg) {
    value = readSensor(); //read from the I2C device on I2C_NUM_1
}
likewise, my display loop is pretty simple, but I can add a delay to slow it down (still with errors):

Code: Select all

while(true) {
    //This I2C write is generating most of the timeouts, but there are occasional timeouts on the sensor read
    UpdateDisplay(value); //write on I2C_NUM_0
    vTaskDelay(100 / portTICK_PERIOD_MS);
}
What IDF versions are you using?
The latest from github

spanky
Posts: 13
Joined: Thu Nov 30, 2017 6:35 pm

Re: Increasing RTOS Tick Rate, >1000Hz

Postby spanky » Tue Sep 01, 2020 7:08 pm

I am doing something very similar and am noticing some significant variance in the timing. Here's my scenario:
  • My sensor task is pinned to the last core (and to my knowledge, the only thing running on that core)
  • I use a periodic timer set to 10ms (I'm looking to achieve a stable sample rate of 100Hz)
  • That timer uses a semaphore to wakeup the sensor task loop
  • When woken, I read esp_timer_get_time() to get a nanosecond timestamp
  • I shove that timestamp and some other data into a queue (via xQueueSendToBack())
  • My logger task runs on the first core and drains that queue to an SD card
Assumptions:
  • The sensor task should be independent of the stuff running on the first core
  • esp_timer_get_time() is an appropriate timestamp value
  • I also turned off any additional sensor code so its literally only generating timestamps and sticking them in the queue
That mostly works and I'm logging at ~100Hz. When I look at the timestamps in more detail the variation becomes apparent.

These plots are the difference in adjacent timestamps. The ideal target is 10000ns (10ms.... 100Hz, which is what my periodic timer is set to). Each dot represents the time delta from the last sample on the Y axis. Sample # (cnt) is on the X axis.

This plot is with the RTOS tick rate at 100Hz. You can see most of the samples are very close to the target, but some regular patterns seem to compound. It seems reasonable that my timer rate matching the tick rate would cause this (?).
****see next post****

This plot is with the RTOS tick rate at 1000Hz. My hope was increasing the tick rate (beyond my sample rate) would address those compounding differences.That appears to have made things worse with regards to hitting the target of 10ms.
****see next post****

My next step will be to try reducing the RTOS tick rate.

In both cases the variation seems bounded by +/-1.5ms, which is pretty significant. I don't have a specific question, but am looking to understand that variation. Having the timer fire later makes sense (points above 10000 in the plots), but firing earlier has me confused.
Last edited by spanky on Wed Sep 02, 2020 4:36 am, edited 2 times in total.

spanky
Posts: 13
Joined: Thu Nov 30, 2017 6:35 pm

Re: Increasing RTOS Tick Rate, >1000Hz

Postby spanky » Wed Sep 02, 2020 4:29 am

So I screwed up the X axis (damn lies and statistics, and whatnot)

Still logging at 100Hz, here's the timestamp variation at the various tick rates with the proper/normalized X axis

CONFIG_FREERTOS_HZ=50
50hz.png
50hz.png (36.22 KiB) Viewed 4629 times
CONFIG_FREERTOS_HZ=100
100hz.png
100hz.png (37.19 KiB) Viewed 4629 times
CONFIG_FREERTOS_HZ=1000
1000hz.png
1000hz.png (35.41 KiB) Viewed 4629 times

spanky
Posts: 13
Joined: Thu Nov 30, 2017 6:35 pm

Re: Increasing RTOS Tick Rate, >1000Hz

Postby spanky » Wed Sep 02, 2020 11:03 pm

Did some more investigating and it looks like the BLE stack is the culprit. I'm not sure why, as that and the SD logger task are pinned to the first core and the sensor task (where the critical 10ms timer should be isolated) is on the 2nd core.

At this point, I'm probably thoroughly off topic from this post. The timing plots at the different tick rates should be of interest to someone though.

spanky
Posts: 13
Joined: Thu Nov 30, 2017 6:35 pm

Re: Increasing RTOS Tick Rate, >1000Hz

Postby spanky » Sat Sep 12, 2020 5:58 pm

In the interest of tying these two together, here's the continuation of this thread:
viewtopic.php?f=13&t=17235

Who is online

Users browsing this forum: Google [Bot] and 214 guests