Software timer callback function cannot call taskENTER_CRITICAL()?

taskENTER_CRITICAL is blocking API? I call taskENTER_CRITICAL and taskEXIT_CRITICAL in my timer callback function, as a result, my program runs wrongly. How can I do to get the same effect as taskENTER_CRITICAL?

No, it is not.

What do you mean by your program runs wrongly? How did you conclude that taskENTER_CRITICAL is responsible for that?

The golden rule is to remember that, among other things, claiming the critical section will suspend the scheduler, so you can not suspend the caller while owning the critical section, or you will “deadlock” everything.

Many people believe that the crit sect can be used to enforce mutual exclusion. Well, yes, it will do that, but also brake the entire sytem to a grinding halt.

In 99% of all cases where application code claims the crit section, it’'s useless and dangerous overkill.

I would ‘object’ to that value, as I frequently use a critical section, and I use it to make a non-atomic operation atomic. Something like:

    taskENTER_CRITICAL();
    table[count] = value;
    count = count+1;
    taskEXIT_CRITICAL();

This is exactly what critical sections were designed for.

Note, key feature, there is VERY little code inside the critical section. The key is that switching to a Mutex would have more code executed. This form only makes sense if the code is shorter than a call to take and give a Mutex, or it needs isolation from ISRs.

1 Like

We also discussed a few times that there are more fine granularity mechanisms to accomplish mutual exclusion - for example, if the exclusion is only against one single thread of execution, then a mutex (if the other thread is a task) or a “surgical” diasable of a particular interrupt (if the other htread is an ISR; very frequent use case, eg in device drivers) is preferrable.

Agreed, with the addition that the code running while the CS is claimed may never under any circumstance suspend the caller.

I think the key here is that the ‘surgical’ operations tend to be somewhat heavy, perhaps even close to 100 instructions. A critical section is generally just a couple. This means a very short critical section has LESS impact on the rest of the system then a more directed interlock. Once the block of ‘protected’ code gets to be close to the size of the interlock, then the more directed interlock makes sense.

Also note that any operation that suspends the caller is by definition bigger than that point, as that is calling the scheduler which is ‘big’. You can almost say that almost ANY call inside the critical section is likely to make the operation ‘big’ unless you actually KNOW it isn’t.

Hi,
I have one function which containing taskXXX_CRITICAL pairs to protect short data section, this function can work well in tasks to share data, however, there have corrupted data when called in timer callback function .

There is no different between the timer callback task and other FreeRTOS tasks. You should not call blocking functions from a timer callback because it blocks the timer task, which prevents any timer callback executing. The enter and exit critical functions are not blocking functions in the FreeRTOS sense though because they don’t prevet the timer task from running.

Thanks for your explanation. I think I have located the problem,that is this timer’period is 1ms. This problem has
not occured again if timer runs at 100ms periodically.

You might just be masking the real problem. If you are not seeing data corruption after changing the timer period, that most likely means that you are able to avoid some race condition just out of pure luck. I’d recommend to debug the original issue and fix it.

1 Like

OK, Thank you. Do you know how Soft timer works , is timer attached to any os-task? I set 1ms periodic timer works with highest priority.

Yes - timer task.

That should be fine. You need to determine the cause of data corruption.