Чтобы ответить на ваши сомнения - да, этот код будет работать. С технической точки зрения сам код RTOS на самом деле не заботится о функции, которая принимает или освобождает мьютекс, это задача, которая выполняет код, который имеет значение (или, более конкретно, контекст, поскольку мы также включаем прерывания).
Фактически, некоторое время назад (я полагаю, какой-то версии FreeRTOS 7) они ввели дополнительную проверку в функции освобождения мьютекса, которая сравнивает задачу освобождения мьютекса с задачей, которая содержит мьютекс. Если это не то же самое, на самом деле происходит сбой утверждения, которое фактически является бесконечным циклом, мешающим вашей задаче продолжать работу, чтобы вы могли заметить и устранить проблему (есть многочисленные комментарии вокруг утверждений, которые помогут вам диагностировать проблему). Это делается так, как мьютексы используются для защиты ресурсов - например, доступ к SD-карте, доступ к дисплею и т. П. - и взятие мьютекса из одной задачи и освобождение его от другой противоречит всей этой идее или, по крайней мере, указывает на вонючий код. Если вам нужно сделать что-то подобное, вы, вероятно, захотите использовать вместо этого семафор.
Теперь, что касается второй части вашего вопроса - является ли это хорошей практикой для этого - я бы сказал, что это зависит от того, какСложно сделать это, но в целом я считаю это сомнительным. В целом, код, работающий на мьютексе, выглядит примерно так:
if(xSemaphoreTake(mutex, waitTime) == pdTRUE)
{
doResourceOperation();
xSemaphoreGive(mutex);
}
Это просто, легко понять, потому что именно так большинство используют для написания такого кода. Это в значительной степени позволяет избежать целого класса проблем с этим мьютексом, которые могут возникнуть, если вы начнете усложнять получение и освобождение кода («Почему он не освобожден?», «Кто держит этот мьютекс?», «Я в тупике?»). ). Проблемы такого рода, как правило, трудно отлаживать, а иногда даже трудно исправить, поскольку это может потребовать перестановки некоторых частей кода.
Чтобы дать общий совет - сделайте его простым. Видеть некоторые странные вещи, происходящие вокруг мьютекса, часто означает, что там происходят некоторые сомнительные вещи. Возможны некоторые неприятные тупики или условия гонки. Как и в вашем примере, вместо того, чтобы пытаться использовать мьютекс каждые 50 мсек до тех пор, пока он не преуспеет, просто подождите вечно, указав portMAX_DELAY
время задержки для xSemaphoreTake
и поместите его в ту же функцию, которая использует ресурс и освобождает мьютекс.