Библиотека LUFA (раннее название MyUSB) версия 101122
Простой планировщик задач - LUFA/Scheduler/Scheduler.h

Data Structures

struct  TaskEntry_t
 Структура записи задачи для списка. More...

Defines

#define TASK(name)   void name (void)
#define TASK_LIST   TaskEntry_t Scheduler_TaskList[] =
#define TASK_MAX_DELAY   (MAX_DELAYCTR_COUNT - 1)
#define TASK_RUN   true
#define TASK_STOP   false

Typedefs

typedef void(* TaskPtr_t )(void)
typedef uint16_t SchedulerDelayCounter_t

Functions

void Scheduler_Start (void)
void Scheduler_Init (void)
static void Scheduler_ResetDelay (SchedulerDelayCounter_t *const DelayCounter) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE
bool Scheduler_HasDelayElapsed (const uint16_t Delay, SchedulerDelayCounter_t *const DelayCounter) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2)
void Scheduler_SetTaskMode (const TaskPtr_t Task, const bool TaskStatus)
void Scheduler_SetGroupTaskMode (const uint8_t GroupID, const bool TaskStatus)

Variables

exter TaskEntry_t Scheduler_TaskList []
volatile uint8_t Scheduler_TotalTasks
volatile SchedulerDelayCounter_t Scheduler_TickCounter

Detailed Description

Deprecated:
Этот модуль устарел и будет удален в будущих релизах библиотеки.

зависимости для исходного кода модуля

Следующие файлы должны быть скомпилированы с любым проектом, который использует этот модуль:

модуля

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

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

Каждая задача для шедулера LUFA должна быть написана так же, как ISR (обработчик прерывания); она должна выполняться быстро (чтобы одна задача не пожирала ресурсы процессора, не давая другой задаче запуститься, когда истечет некоторый таймаут). В отличие от нормальных RTOS задач, каждая задача шедулера LUFA является обычной функцией, и должна быть разработана для вызова и возврата к вызывающей функции шедулера повторящимся образом. Данные, которые должны быть сохранены между запусками задачи, должны помещаться в глобальные переменные или (что лучше) в статические (static) переменные внутри тела функции задачи.

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

Пример использования:

      #include <LUFA/Scheduler/Scheduler.h>

      TASK(MyTask1); // Прототип задачи
      TASK(MyTask2); // Прототип задачи

      TASK_LIST
      {
          { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1  },
          { .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1  },
      }

      int main(void)
      {
          Scheduler_Init();

          // Здесь другая инициализация

          Scheduler_Start();
      }

      TASK(MyTask1)
      {
          // Здесь реализация задачи
      }

      TASK(MyTask2)
      {
          // Здесь реализация задачи
      }

Если есть желание, шелулер LUFA не нужно использовать в приложениях на основе библиотеки LUFA. Можно использовать более стандартный подход к проектированию приложения, или применить RTOS с правильным планировщиком вместо планировщика LUFA. В случае формирования задачи обработки USB, она должна запускаться вручную для поддержки коммуникаций USB, в случае RTOS должна быть составлена надлежащая задача, чтобы делать то же самое.


Define Documentation

#define TASK (   name)    void name (void)

Создает новое тело или прототип задачи шедулера. Должен использоваться в форме:

      TASK(TaskName); // Прототип

      TASK(TaskName)
      {
           // Тело задачи
      }
#define TASK_LIST   TaskEntry_t Scheduler_TaskList[] =

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

Пример использования:

      TASK_LIST
      {
           { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
           // Тут могут быть еще записи задач
      }
#define TASK_MAX_DELAY   (MAX_DELAYCTR_COUNT - 1)

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

#define TASK_RUN   true

Константа статуса режима задачи, для передачи в Scheduler_SetTaskMode() или Scheduler_SetGroupTaskMode().

#define TASK_STOP   false

Константа статуса режима задачи, для передачи в Scheduler_SetTaskMode() или Scheduler_SetGroupTaskMode().


Typedef Documentation

typedef uint16_t SchedulerDelayCounter_t

Тип для переменной, которая должна удерживать задержку в тиках шедулера, для определения максимально возможной задержки.

typedef void(* TaskPtr_t)(void)

Тип для указателя на задачу шедулера.


Function Documentation

bool Scheduler_HasDelayElapsed ( const uint16_t  Delay,
SchedulerDelayCounter_t *const  DelayCounter 
)

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

Parameters:
[in]DelayЗадержка для проверки, измеренная в тиках.
[in]DelayCounterСчетчик, в котором сохранено начальное значение тиков для отсчета задержки.
Returns:
Двоичное true, если задержка прошла, иначе false.

Пример использования:

      static SchedulerDelayCounter_t DelayCounter = 10000; // Принудительный начальный запуск

      // Задача будет запущена каждые 10000 тиков, для этого демо 10 секунд
      if (Scheduler_HasDelayElapsed(10000, &DelayCounter))
      {
           // Код для выполнения после истечения интервала задержки
      }
void Scheduler_Init ( void  )

Инициализирует шедулер, так что функции шедулера могут быть запущены, перед тем как шедулер будет запущен сам по себе. Эта функция должна быть вызвана перед любым вызовом функции шедулера, отличающейся от Scheduler_Start(), и может быть пропущена, если не нужно вызвывать функции шедулера до запуска самого шедулера.

static void Scheduler_ResetDelay ( SchedulerDelayCounter_t *const  DelayCounter) [inline, static]

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

Parameters:
[out]DelayCounterСчетчик, в котором сохранено начальное значение счетчика тиков для указанной задержки.
void Scheduler_SetGroupTaskMode ( const uint8_t  GroupID,
const bool  TaskStatus 
)

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

Parameters:
[in]GroupIDЗначение ID группы, у которой меняется состояние.
[in]TaskStatusНовое состояние для задач в указанной группе (TASK_RUN или TASK_STOP).
void Scheduler_SetTaskMode ( const TaskPtr_t  Task,
const bool  TaskStatus 
)

Установка режима запуска для указанной задачи.

Parameters:
[in]TaskИмя задачи, у которой меняется статус.
[in]TaskStatusНовое состояние задачи (TASK_RUN или TASK_STOP).
void Scheduler_Start ( void  )

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


Variable Documentation

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

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

volatile uint8_t Scheduler_TotalTasks

Содержит общее количество задач в списке, независимо от установленного статуса задачи TASK_RUN или TASK_STOP.

Note:
Это значение должно использоваться только для чтения (read-only), и никогда не меняться в коде пользователя.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines