Hi all, while taskENTER_CRITICAL() suspends (blocks) all the tasks, whatever their priority, I’ll need instead a function to leave running the tasks with a priority above a specified level, blocking the ones with a lower prio (like, i a non-rtos scenario, you can do – for ISRs – on old Motorola dsps changing the IPL). There is some way? thank you. Alberto
The way I can think of is for the task to change its priority to the level above the one you want to block and then not block itself (but you can’t block inside a critical section). Since the task is running, no lower priority tasks will every become the highest priority ready task. If you disable round robin scheduling/Time Slicing, it could go to the priority you want to block.
Hi Richard, thank you, I like your idea :), I think it can fit my application. I’ll make a try and let you know. thank you
Thinking about your question, and making sure you understand some nuances. taskENTER_CRITICAL is designed to block ISRs (and as a side effect of that, task switches). This type of critical section needs to be kept very short or ISR latency can be impacted. Longer periods, that only need to protect against other tasks, can use the vTaskSuspendAll to block all task changes, while not blocking ISRs at all (unless they defer to a task, then that defered part gets delayed). More focused protection can be obtained with a Mutex or a Semaphore, which provides exclusivity of the resource controlled by the item, as long as all users use that control method. Tasks never have to worry about lower priority tasks interrupting their operation (but do watchout for tasks whose priority might be adjusted by the use of a Mutex and Priority Inheritance), so priority can sort of be a soft way of getting exclusion, but you need to be careful about it. I do wonder a bit if your application isn’t worrying about normal resource/variable sharing as implide by the thought of critical sections, but more about general CPU Resource allocation (this task has just become a hot ticket and needs to get done now), in which case priority is exactly the right method to use.
Hi Richard, thanks for the clarification. Yes, i’m aware of the fact that, really, taskENTER_CRITICAL disables ISR. Let me explain the point where I need that feature, and why your idea could fit my purpose. My code is a controller that runs a custom EtherCAT master to communicate with slave devices. Once started, the tasks used to handle the EtherCAT master should never been stopped, because they also run a PLL to keep the master time locked with the slaves, using the Distributed Clock, a feature of EtherCAT. These tasks are at a very high priority – they should preempt all the others, fired by a signal sent by an ISR. But in some conditions the main application needs to block its own tasks for a period of time, too long for the EtherCAT tasks; and this will be done in a task with a “natural” priority that is below the prio of the EtherCAT tasks. Following your suggestion, in that condition i can read the current task prio, then raise the prio of that task to a value that’s higher than any other tasks – except the EtherCAT ones, and then restore it.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.