Я заметил странное поведение при отладке анализируемой системы. В системе есть три периодических задачи:
«Задача-1» с периодичностью 10 миллисекунд. Высокий приоритет.
«Задача-2» с периодичностью 10 миллисекунд. Средний приоритет.
«Задача-3» с периодичностью 10 миллисекунд. Низкий приоритет.
Содержание трех задач - это просто критическая секция, которая является общедоступной. Инверсия приоритетов происходит часто, и я заставляю эту ситуацию видеть, как система ведет себя во времени. Systick имеет период 1 мс.
Из того, что я читал о FreeRTOS, в Cortex-M изменение контекста задачи выполняется через ожидающий бит, который в сценарии периодических задач может быть активирован с помощью:
Обработчик тикового таймера находит задачу с наивысшим приоритетом в очереди готовности и устанавливает ожидающий бит переключения контекста;
В функции «vDelayTaskUntil», которая ожидает следующей активации;
Когда семафор занят и задача, которая пытается его получить.
Тем не менее, я обнаружил такое поведение:
Иногда, когда задача с высоким приоритетом находится внутри семафора, переключение контекста происходит само, как описано ниже.
Как уже отмечалось, задача 1 сама переключает контекст.
Вы знаете, как мне сказать, почему это происходит?
Прикрепляем код теста:
Задание 1:
void vTask1_handler(void *params) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
xLastWakeTime = xTaskGetTickCount();
int i = 0, to =0;
for (;;) {
vTaskDelayUntil(&xLastWakeTime, xFrequency);
to = DWT->CYCCNT;
for (i = 0; i < to % 500; i++);
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
to = DWT->CYCCNT;
for (i = 0; i < to % 5000; i++);
xSemaphoreGive(xSemaphore);
}
}
}
Задача-2:
void vTask2_handler(void *params) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
xLastWakeTime = xTaskGetTickCount();
int i = 0, to = 0;
for (;;) {
vTaskDelayUntil(&xLastWakeTime, xFrequency);
to = DWT->CYCCNT;
for (i = 0; i < to % 200; i++);
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
to = DWT->CYCCNT;
for (i = 0; i < to % 10000; i++);
xSemaphoreGive(xSemaphore);
}
}
Задача-3:
void vTask3_handler(void *params) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
xLastWakeTime = xTaskGetTickCount();
int i = 0, to=0;
for (;;) {
vTaskDelayUntil(&xLastWakeTime, xFrequency);
to = DWT->CYCCNT;
for (i = 0; i < to % 200; i++);
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
to = DWT->CYCCNT;
for (i = 0; i < to % 10000; i++);
xSemaphoreGive(xSemaphore);
}
}
}
Спасибо.