I’m still trying to figure out if FreeRTOS (if any RTOS at all) is the right choice for our project. The circuit board collects/outputs data from a bunch of sensor and inputs, once per millisecond. I was thinking that using an RTOS might make it easier to manage some of the more annoying, time related things (such as fixing stuck I2C bus, or managing communications to a sensor that takes multiple read/write/delays to get data from). Anyways, the 1 ms update period of the communications means that the RTOS would need tick much faster than 1 ms. When I try to set it faster, I get divide by zero errors because the portTICKPERIODMS is defined as an integer division of 1000 / configTICKRATEHZ. This means you get zero for anything faster than 1 kHz. So is 1 kHz the maximum speed that FreeRTOS is meant to run?
First, you CAN use a configTICKRATEHZ higher than 1000, you just can’t then divide by portTICKPERIODMS (and I don’t think the FreeRTOS code ever does this itself). In fact, if your Tick Rate doesn’t divide into 1000 evenly, it is a bit wrong to divide by portTICKPERIODMS as you will get a slightly wrong value. (For example 300 Hz will give you 3ms instead of the correct 3.3333ms) That said, why do you say that you need a tick MUCH faster than 1 ms? If the issue is that some of the sensors need delays on the 10-100us interval, then yes, those sorts of delays do NOT work well being generated with the tick interrupt of a RTOS. That period of timing normally requires either just doing a spin wait (maybe checking a timer/counter) or a higher frequency timer interrupt to sequence the I/O operation. This still could be part of an application using an RTOS, with the data collection being done in the highest priority task (and/or in interrupts service routines), and passing off to lower priority tasks less “time critical” operations that can benefit from the RTOS.
Thanks for your suggestions! Basically you are saying I could keep my code running the way it already is in one task, and then add in the non-critical stuff (which is really what I want to use the scheduler for) into their own tasks. That way the time critical stuff is still running fast like it currently does, and the housekeeping tasks can just be run when there is time to do so. I was also wondering about the accuracy of portTICKPERIODMS if it didn’t divide nice, so you also answered that question as well!
Also, you can write your own macros and make provisions for faster ticks. I used 3kHz ticks so that I could use integer timing for 50 and 60 Hz. (Yes, I could have used 300 Hz.) I did it in a hurry to test something, so it was a bit of a one-off, ugly hack. Still, it can be done elegantly if you have the time to track where the macros are used. That said, the use of interrupts (e.g. critical byte to byte timing of RS485, etc.), spin counters in a dedicated, low priority thread (loose timing of I2C) and DMA (CAN bus packets) are all used in my PIC16 projects with 1KHz clock for the business logic.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.