Synchronizing UART TX

You know the rules… if your uart isr interacts with the os in any way, it must by definition run below or equal max syscall. And yes, that includes the possibility that extended periods of CS ownership cause uart transmission overflows or underflows. Preventing that is one of the jobs of the system designer.

Critical sections need to be kept short. Note, an interrupt that is raised during a critical section is normally not lost, but just delayed until the critical section ends.

so why not allow tasks to be interrupted by an interrupt i.e, interrupt having a higher priority than a task to minimize any delays?

Please rephrase your question. Interrupts always have a higher execution priority than tasks by definition.

They do but I am referring to how them having a lower priority than max syscall would disable them. I am just asking when would you want to disable them (lower interrupt prio than max syscall) VS keeping them enabled so the task gets context-swtiched rightaway it fires? (higher interrupt prio than max syscall).

Your question is still unclear. The max sycall pri is a mechanism to ensure That FreeRTOS itself does not run into concurrency problems, ie the sytem maintained data structures remain coherent. Any call to claim a critical section will disable isr up to max syscall so that no isr that uses FreeRTOS sys calls can fire while the critical section is claimed. That mechanism is well documented and ensures OS data structure integrity.

They get disabled only during “Critical Sections” which the FreeRTOS kernel only uses for very short periods when it is manipulating “global” data that could get corrupted if an ISR calls a FreeRTOS function.

User code can also use these critical sections, and should follow similar rules of being very short to avoid issues. The User Code does have the advantage that it should know how much delay is allowed, and could delay longer if it knows that is ok. If it isn’t, then it shouldn’t.

If you need faster response than what can be achieved in the presence of those critical sections, then you can put your ISR above the max syscall priority level, but that ISR can not interact with FreeRTOS at all, so can’t signal a task to be switched in.

“Right Away” is impossible for the extreme definition of “Right Away”, because the context switch takes time, and there are points in time when it just isn’t allowed. “Promptly” is possible, and that could be to start the switch just after the critical section ends and the ISR that fires at that point schedules it.

I see. So during critical section, the UART ISR will get delayed and not lost you said. Curious how does it work under the hood when an interrupt can’t be fired rightaway? the pending bit remains set and only resets once after the ISR has begun running?

Lastly, could task notifications be used instead of semaphores here for synchronization/blocking as they’re known to be lightweight?

yes to both questions.

To the Task Notification question, since Task Notifications have come out, I use them extensively. They can be used when you know, or can easily be able to know, who you want to signal. A Semaphore works better when you don’t know which task to activate.

I do currently use semaphores for I/O completion signaling from possibly shared devices as these try to be kept general, and the driver doesn’t know what other uses the task is using Task Notifications, so doesn’t know what notification is “safe” to use. This IS solvable, I just haven’t seen enough need to make it worth changing working code.