Как определить, какая задача мертва? - PullRequest
2 голосов
/ 30 апреля 2009

У меня есть встроенная система, которая имеет несколько (> 20) задач, выполняющихся с разными приоритетами. У меня также есть контрольная задача, которая запускается, чтобы проверить, не застряли ли все остальные задачи. Мой сторожевой таймер работает, потому что каждый раз в голубой луне он перезагружает систему, потому что задание не регистрируется.

Как определить, какая задача умерла?

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

Есть предложения?

Ответы [ 7 ]

2 голосов
/ 03 мая 2009

Даже последние несколько недель я работал над проблемой сброса сторожевого таймера. Но, к счастью для меня, в файлах ramdump (в среде разработки ARM), в которых есть один буфер трассировки обработчика прерываний, содержащий PC и SLR на каждом прерывании. Таким образом, из буфера трассировки я мог точно узнать, какая часть кода работала до сброса WD.

Я думаю, что если у вас есть один и тот же механизм хранения ПК, зеркалки при каждом прерывании, то вы можете точно выяснить задачу преступника.

2 голосов
/ 01 мая 2009

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

1 голос
/ 30 апреля 2009

Это упреждающий? Я так понимаю, потому что в противном случае задача сторожевого таймера не запустилась бы, если бы один из остальных застрял.

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

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

В зависимости от ОС, это может быть легко или сложно.

0 голосов
/ 09 июня 2009

Как работает ваша система? Я всегда использую комбинацию программных и аппаратных сторожевых псов. Позвольте мне объяснить ...

В моем примере предполагается, что вы работаете с вытесняющим ядром реального времени, и у вас есть поддержка сторожевого таймера в вашем процессоре / микроконтроллере. Этот сторожевой таймер выполнит сброс, если он не был активирован в течение определенного периода времени. Вы хотите проверить две вещи:

1) Периодический системный таймер («часы RTOS») работает (если нет, такие функции, как «сон», больше не будут работать, и ваша система не будет работать).

2) Все потоки могут работать в течение разумного периода времени.

Моя RTOS (www.lieron.be/micror2k) предоставляет возможность запуска кода в обработчике прерывания часов RTOS. Это единственное место, где вы обновляете аппаратный сторожевой таймер, поэтому вы уверены, что часы работают постоянно (если сторожевой таймер не перезагрузит вашу систему).

В свободном потоке (всегда работающем с самым низким приоритетом) обновляется «сторожевой таймер программного обеспечения». Это просто установка переменной на определенное значение (например, 1000). В прерывании часов RTOS (где вы запускаете аппаратный сторожевой таймер) вы уменьшаете и проверяете это значение. Если он достигает 0, это означает, что свободный поток не работает в течение 1000 тактов, и вы перезагружаете систему (это можно сделать бесконечным циклом внутри обработчика прерываний, чтобы перезагрузить аппаратный сторожевой таймер).

Теперь к вашему первоначальному вопросу. Я предполагаю, что системные часы продолжают работать, так что это программный сторож, который сбрасывает систему. В обработчике прерывания часов RTOS вы можете выполнить некоторый «сбор статистики» в случае возникновения программной сторожевой таймера. Вместо сброса системы вы можете видеть, какой поток запущен на каждом такте (после возникновения проблемы), и попытаться выяснить, что происходит. Это не идеально, но это поможет.

Другой вариант - добавить несколько программных сторожевых таймеров с разными приоритетами. Установите для незанятого потока значение VariableA равным 1000, а для (выделенного) потока среднего приоритета - переменную B. В обработчике прерывания часов RTOS вы проверяете обе переменные. С помощью этой информации вы узнаете, имеет ли зацикливающийся поток приоритет выше, чем «средний» или ниже, чем «средний». Если вы хотите, вы можете добавить 3-го или 4-го или сколько сторожевых программ программного обеспечения вам нравится. В худшем случае добавьте программный сторожевой таймер для каждого используемого приоритета (хотя это будет стоить вам столько же дополнительных потоков).

0 голосов
/ 30 апреля 2009

Упрощенный подход с использованием салфеток будет выглядеть примерно так:

int8_t wd_tickle[NUM_TASKS]

void taskA_main()
{
   ...
   // main loop
   while(1) {
     ...
     wd_tickle[TASKA_NUM]++;
   }
}

... tasks B, C, D... follow similar pattern

void watchdog_task()
{
   for(int i= 0; i < NUM_TASKS; i++) {
     if(0 == wd_tickle[i]) {
       // Egads! The task didn't kick us! Reset and record the task number
     }
    }
}
0 голосов
/ 30 апреля 2009

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

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

0 голосов
/ 30 апреля 2009

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

...