скрытое меню

Разделяемые общие ресурсы

Что может быть лучше простого примера . Например надо выводить отладочную информацию через printf в SWO из разных потоков и прерываний freeRTOS.

Как известно printf выводи данные побайтово вызывая функцию _write . Но не в этом дело. Дело просто в том , что потоки могут прерывать аппаратные прерывания или другие потоки и тоже выводить через printf свою отладочную информацию . Таким образом может вполне получиться каша , в которой непонятно ничего.

Все это называется доступ к общему ресурсу. И нам надо сделать как-то разделение доступа к общему ресурсу. Общий ресурс это участок кода , который не должен прерываться из аппаратных прерываний или других потоков.

taskENTER_CRITICAL() .... taskEXIT_CRITICAL()

Первое , что приходит в голову это критическая секция - именно она не прерывается ничем. Но есть нюанс - все printf надо завести в одну функцию , допустим printfDontInterrupt(). Но в printf переменное число параметров. Что делать?

Можно конечно каждый раз перед printf добавлять taskENTER_CRITICAL(), а после нее taskEXIT_CRITICAL(). Простенько через макрос все это реализовать не проблема:

taskENTER_CRITICAL();
printf(); 
taskEXIT_CRITICAL();

НО тогда получается , что два потока и одно прерывание независимо друг от друга входят в taskENTER_CRITICAL() запрещая прерывание себя родимого... Получается наверное , что кто первым вошел в taskENTER_CRITICAL(), то и запретил прерывание себя , а остальные ждут?....

И вот тут уже выясняется главная проблема (или ограничение) . Из прерывания надо вызывать только taskENTER_CRITICAL_FROM_ISR() / taskEXIT_CRITICAL_FROM_ISR. Это не просто важно , а просто необходимо. В противном случае где-то программа просто зависнет.

VPortEnterCritical

Второе , что приходит в голову - попробовать семафор . Но не простой семафор , а мьютекс.