Задачи FreeRTOS не являются переключением контекста - PullRequest
3 голосов
/ 28 февраля 2011

Я использую порт FreeRTOS для микроконтроллера PIC32 в стартовом наборе PIC32MX.Просто играл с задачами, но задачи не являются переключением контекста.Вот мои основные настройки:

#define configMAX_PRIORITIES    ( ( unsigned portBASE_TYPE ) 5 )
#define configKERNEL_INTERRUPT_PRIORITY         0x01
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    0x03
#define configTICK_RATE_HZ              ( ( portTickType ) 100 )

Теперь у меня есть две задачи, которые мигают двумя светодиодами.Оба имеют приоритет 4 (самый высокий).При нормальной работе светодиоды должны попеременно мигать на каждые 100 тиков.Но этого не происходит.Второй светодиод мигает в течение 100 тиков, и управление переходит к обработчику общих исключений.Почему это происходит?Похоже, что вообще нет расписания.

Ответы [ 5 ]

6 голосов
/ 28 февраля 2011

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

Ваши задачи должны войти в состояние Заблокировано , ожидающее какого-либо события (например, прошедшего времени), чтобы позволить друг другу работать как положено.

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

5 голосов
/ 15 марта 2011

Абсолютно первое, что нужно проверить, это ваше «тиковое» прерывание.Часто прерывания не включены, таймеры не настроены правильно, часы не настроены должным образом в # pragma, которые настраивают PIC32 .. и все эти проблемы проявляются в первую очередь в отсутствии "галочки".

Это # 1 причина не переключения задач: если вы не получаете прерывание по тику.Вот где происходит обычное упреждающее переключение задач.

Предполагая, что вы используете "готовую демонстрацию", в MPLAB установите точку останова в функции void vPortIncrementTick( void ) (около строки 177 в FreeRTOS \ Source\ portable \ MPLAB \ PIC32MX \ port.c) и запустите ваш код.Если там есть точки останова, ваш таймер срабатывает.

4 голосов
/ 28 февраля 2011

Вы уверены, что обе задачи хорошо зарегистрированы, и планировщик запущен?

Что-то вроде следующего кода сделает эту работу:

xTaskCreate( yourFirstTask, "firstTask", STACK_SIZE, NULL, TASK_PRIORITY, NULL );
xTaskCreate( yourSecondTask, "secondTask", STACK_SIZE, NULL, TASK_PRIORITY, NULL );
vTaskStartScheduler();

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

4 голосов
/ 28 февраля 2011

Есть ли у вас круговой планировщик? Ваши задачи спят какое-то время или просто уступают (или заняты ожиданием)?

Очень распространенная ошибка во встроенных ОС состоит в том, что планировщик часто не пытается планировать несколько процессов с одинаковым приоритетом. То есть, как только A уступает, если A является работоспособным, A может быть снова сразу запланирован, даже если у B не было процессоров целую вечность. Это очень нелогично, если вы привыкли к настольным операционным системам, которые прилагают много усилий, чтобы сделать честное планирование (или, по крайней мере, это было для меня).

Если вы столкнулись с этим, вам нужно убедиться, что ваши задачи выглядят так:

for (;;)
{
  led(on); sleep(delay);
  led(off); sleep(delay);
}

... чтобы гарантировать, что задача фактически перестает выполняться между миганиями. Это не сработает, если будет выглядеть так:

for (;;)
{
  led(on);
  led(off);
}

(Кроме того, как правило, вы хотите использовать обычный приоритет, а не высокий приоритет, если только вы не уверены, что он вам действительно нужен - если вы не справитесь с системной задачей, система может вести себя странно или аварийно.)

3 голосов
/ 02 марта 2011

Существуют стандартные демонстрационные задачи, которые просто мигают светодиодами в исходном файле FreeRTOS / Demo / Common / Minimal / flash.c.Задачи, созданные в этом файле, включены в стандартное демонстрационное приложение PIC32 (которое предназначено для платы Microchip Explorer16).

В самой простой форме задача, которая просто переключается и светится каждые 500 мс, будет выглядеть следующим образом:

/* Standard task prototype, the parameter is not used in this case. */    
void vADummyTask( void *pvParameters )
{
const portTickType xDelayTime = 500 / portTICK_RATE_MS;

    for( ;; )
    {
        ToggleLED();
        vTaskDelay( xDelayTime );
    }        
}
...