2016-07-21 3 views
0

У меня есть проект C++, где у меня есть два состояния машины, A и B, работает в двух различных задач Freertos, как это:Перезапуск задачи после ее состояния изменяется другая задача

A::task() 
{ 
    while (1) 
    { 
     switch (m_state) 
     { 
     case A1: 
      // Do A1 stuff 
      break; 
     case A2: 
      // [1] Do A2 stuff before yielding to B::task() 
      // [2] Do more A2 stuff after resuming from B::task() 
      break; // [3] 
     default: 
      break; 
     } // switch: state 
    } // while: task loop 
} 

B::task() 
{ 
    while (1) 
    { 
     switch (m_state) 
     { 
     case B1: 
      // Do B1 stuff 
      break; 
     case B2: 
      // Do B2 stuff 
      break; 
     default: 
      break; 
     } // switch: state 
    } // while: task loop 
} 

Теперь B имеет возможность изменять состояние A (асинхронно, через обратный вызов). Все это прекрасно работает, но мне хотелось бы, чтобы машина «перезагрузилась» A при изменении ее состояния (т. Е. break от того, что она делала в последний раз, когда задача выполнялась [1]), так что код в старом состоянии [2] не продолжается до нажатия break[3] и изменение состояния вступает в силу.

Могу ли я достичь такого поведения?

+0

Похоже, вы хотите переменную условия. То есть, когда B устанавливает состояние A в A2, A затем будет ждать переменной условия, в которой b будет уведомляться. Более простым примером является то, что у вас есть мьютекс, который B берет, прежде чем установить состояние A в A2. После того, как A завершает работу с A2, он пытается захватить мьютекс, который будет работать до тех пор, пока B не выпустит его. – AndyG

ответ

1

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

Я не уверен, что это хорошая идея, но подумайте, может ли задача B удалять и воссоздавать задачу. Всякий раз, когда задача B изменяет состояние задачи A. Возможно, тогда задача A может перезагрузиться всякий раз, когда задача B изменяет состояние A.

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

+0

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

+0

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

+0

Задача не знает, что она была выгружена. Поэтому вы не можете заставить задачу сделать что-то другое, когда оно будет возобновлено. Код задачи - это код задачи. Я не думаю, что разумно вставлять дополнительные коды в тот момент, когда он возобновляется. Тест на превенцию был бы в коде во время компиляции, а затем вам нужно было бы повторить тест после каждого утверждения, потому что вы не знаете заранее, когда произойдет преемственность. – kkrambo