Можно ли не опрашивать задачу FreeRTOS taskGetTickCount()?

Я думаю, что у меня либо а) неправильное понимание того, как работает функция FreeRTOS taskGetTickCount(), либо б) что-то не так с нашим портом.

У меня есть отладка, в которой я показываю вывод xTaskGetCount(). Каждый раз, когда я выполнял vTaskDelayUntil(), кажется, что он обновлен и актуален. Но если я сделаю ожидание вращения, ожидая увеличения, этого никогда не произойдет. Я думал, что прерывание срабатывало каждый тик, и увеличивал это значение. Но в данный момент я выполняю только одну задачу, поэтому, возможно, она достаточно умна, чтобы никогда не проверять перепланирование, а tickCount никогда не обновляется? Я буду очень признателен любому, кто может объяснить мне, как работает счетчик тиков FreeRTOS.

РЕДАКТИРОВАТЬ: Фрагмент образца:

void someTask(void * _)
{
    portTickType now = xTaskGetTickCount();
    for( ; xTaskGetTickCount() - now < 25; )
    {
        debug("%u", xTaskGetTickCount();
    }
} 

Это будет вращаться вечно, намного дольше 25 мс, подразумеваемых, когда тик = 1 мс. Вывод будет постоянно отображать одно и то же значение снова и снова. ЕСЛИ я добавлю vTaskDelay() в конец цикла, он будет правильно увеличиваться и в конечном итоге выпадет.


person Travis Griggs    schedule 21.12.2012    source источник
comment
Покажите простой фрагмент кода, показывающий проблему.   -  person Mats Petersson    schedule 22.12.2012
comment
Немного экстраполируя, хорошо спроектированная RTOS не позволит вызову debug() значительно задержать вызывающий его поток. Итак, вы будете просматривать, о, пару сотен тысяч строк вывода отладчика, прежде чем он снова догонит вас.   -  person Hans Passant    schedule 22.12.2012
comment
@HansPassant, здесь все не так. Я модифицировал его, чтобы он выполнял длинные циклы между операторами отладки, но, похоже, он все еще не увеличивается.   -  person Travis Griggs    schedule 28.12.2012


Ответы (2)


Вы не говорите, какой порт вы используете. По сути, в вашем коде нет ничего плохого, хотя это необычно. Цикл никогда не блокируется, поэтому он будет голодать для всех задач с более низким приоритетом любого времени выполнения и будет выделять время для задач с таким же приоритетом.

Вот несколько заметок:

Лучшим решением этой проблемы было бы:

while( whatever )
{
    vTaskDelay( 25 );
    DoSomething();
}

debug() не является оператором FreeRTOS, и я понятия не имею, как он реализован. Если вы используете какой-то полухостинг, то может случиться так, что вызов debug() останавливает выполнение вашего процессора (вы не говорите, какой) в течение длительных периодов времени.

person Richard    schedule 22.12.2012
comment
В конце концов, мы обнаружили проблемы с нашим портом xmega256a3. Когда порт работает, вышеперечисленное должно работать нормально. - person Travis Griggs; 12.02.2013

vTaskDelay( 25 );

Ну что ты предложил?! Это не решение! VTaskDelay() — функция, переводящая задачу в заблокированное состояние на период времени, который отсчитывается с момента вызова vTaskDelay().

VTaskDelayUntil() — эта функция обеспечивает циклическое выполнение с заданным периодом.

Цикл никогда не блокируется, поэтому он будет голодать для всех приоритетных задач любого времени выполнения и будет выделять время для задач с одинаковым приоритетом.

Функция vTaskDelayUntil() специально для того, чтобы этого избежать! Например, я не могу поставить этот костыль с функцией vTaskDelay(), из-за критического участка кода, а функция xTaskGetTickCount() всегда возвращает 0. И решить эту проблему не могу((

Несколько часов пыток спустя:

void StartTask01(void const * argument)
{
  portTickType xLastWakeTime;
  xLastWakeTime = xTaskGetTickCount();
  const portTickType xPeriod = pdMS_TO_TICKS(100);

  while(1)
  {
    canInterviewMC_100();                       // Interview CAN Message
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
  }
}

В результате этот код выполняется каждые 100 мс. При этом она имеет наивысший приоритет, но эта задача не будет занимать процессорное время для задач с низким приоритетом, потому что выполняется только один раз в 100мс.

person Dmitrij Budejkin    schedule 20.07.2017