CPU: Altera FPGA with NIOSII built in.
Compiler: NIOS2 GCC
In my system, I really care about the accuracy of Systick counted by system timer. But in FreeRTOS, some APIs will call taskENTER_CRITICAL from time to time, which causes the system timer interrupt stops counting systick.
My question is if I set all the tasks at the same priority and** just enable the system timer interrupt** may I keep the interrupt enable when taskENTER_CRITICAL is called. Will this cause the system crashed?
In my code, I do some experiments like: #define portDISABLE_INTERRUPTS() //alt_irq_disable_all() #define portENABLE_INTERRUPTS() //alt_irq_enable_all( 0x01 )
The system keeps running well and no Systick lost, but I am afraid whether there are any potential issues.
Critical sections should be short enough that you won’t lose Systick interrupts. If the interrut occurs during the critical section, then it will happen as soon as the critical section is exited. If your critical sections are too long, then you can run into the accuracy issue of the Systick, but they shouldn’t be that long. No critical section in the FreeRTOS code should be anywhere near long enough to cause an issue with any reasonable Systick frequency. If you need something longer, then what FreeRTOS uses in these cases is disabling the scheduler for the interval. If you need protection from a given interrupt, you would disable that one seperately.
Also, one of the primary purposes of a critical section is to prevent the switching to another task in the middle of the critical section, and enabling the Systick interrupt defeat this. For the calls inside FreeRTOS, they also need to protect the access to critical control variable while things are being updated, and one place that also accesses them that the protection is needed for is in the Systick handler.
So is there really no way in FreeRTOS to keep interrupt on during all the running time?
Even if I do not use any other interrupt except system timer, even if I make all tasks with equal priorty, I still need to keep the DISABLE interupt function in FreeRTOS API?
My understanding is the error of the Systick, which is caused by disabling interrupt, will accumulate when the time passes by.
Some FreeRTOS ports only disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY, not sure about NIOS, but if not you could probably update the port so some interrupts are always enabled. You can also use vTaskSuspendAll()/xTaskResumeAll() instead of taskENTER_CRITICAL()/taskEXIT_CRITICAL() so interrupts remain on.
A short disabling of interrupts should NOT cause errors to accumulate, as it doesn’t cause the timer to stop, just delaying the interrupt by a tiny amount, and the interrupt does NOT reset the timer. Only disabling interrupts for long enough that two interrupts get generated (so one is lost) during the interrupt disable period will cause a slip. (I am assuming that the NIOS processor works like most processors).
Using the ‘tickless idle’ mode will cause some shifting of the time base, as it restarts the Systick, so you would not want to use that mide (if it is available for NIOS).
If the NIOS design requires the Systick interrupt routine to restart the timer (and doesn’t provide an indication of how long it has been since the last overflow) then that timer is unusable a stable long term timebase, as even if you don’t ever disable the interrupts yourself, there will be short periods when the processor will need to delay the interrupt processing (like when in the middle of processing another interupt).