RTOS: создание задач

     Цель данного примера показать как можно создавать новые задачи средствами STM32CubeMx.

     Давайте откроем проект EX_0_FreeRTOS который мы делали в статье "Создание проекта с STM32 Cube MX и FreeRTOS для Atollic TrueSTUDIO" и внесем некоторые изменения в его конфигурацию. 

     Первым делом подключим и настроем USART1 и ножку PC7 рисунок 1 и рисунок 2.

Рисунок 1

Рисунок 2

     Перейдем в раздел FREERTOS вкладку Task and Queues и добавим две задачи uart_task_1 и uart_task_2 рисунок 3 и рисунок 4.

Рисунок 3

Рисунок 4

     Рассмотрим более подробно какие поля есть у таблицы Tasks рисунок 5.

Рисунок 5

     Пока что следует обратить внимание на первые 4 поля:

     Task Nameимя задачи (для отладки) и имя которое будет использоваться в дескрипторе задачи. Когда создается новая задача, ядро операционной системы возвращает ее дескриптор и в дальнейшем через него можно получать доступ к этой задаче.

     Priority - при создании задачи ей назначается приоритет, по умолчанию установлен osPriorityIdle = (-3), это значит что у задачи минимально-возможный приоритет.

     Перечисление вариантов приоритетов:

     osPriorityIdle = -3,
     osPriorityLow = -2,
     osPriorityBelowNormal = -1,
     osPriorityNormal = 0,
     osPriorityAboveNormal = + 1,
     osPriorityHigh = +2,
     osPriorityRealtime = +3,
     osPriorityError = 0x84

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

     Entry function - Это название функции в которой будет выполняться задача

     Нажимаем GENERATE CODE открываем проект и смотрим что сгенерировал Куб:

osThreadId defaultTaskHandle;
osThreadId uart_task_1Handle;
osThreadId uart_task_2Handle;

     Строки 48-50, здесь объявляются переменные типа osThreadId в которых будут хранится дескрипторы задач.

void StartDefaultTask(void const * argument);
void StartTask02(void const * argument);
void StartTask03(void const * argument);

     Строки 59-61, здесь объявляются функции самих задач, при создании задачи ей можно передать данные (указатель типа void может указывать на объекты любого типа данных:).

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of uart_task_1 */
  osThreadDef(uart_task_1, StartTask02, osPriorityIdle, 0, 128);
  uart_task_1Handle = osThreadCreate(osThread(uart_task_1), NULL);

  /* definition and creation of uart_task_2 */
  osThreadDef(uart_task_2, StartTask03, osPriorityIdle, 0, 128);
  uart_task_2Handle = osThreadCreate(osThread(uart_task_2), NULL);

     Строки 123-132, здесь в функции osThreadDef(name, thread, priority, instances, stacksz) происходит определение атрибутов функций будущих задач, которые будут созданы функцией osThreadCreate(thread_def, argument) с помощью osThread(name).

     osThreadDef(name, thread, priority, instances, stacksz):

     name -   имя задачи

     thread - функция задачи

     priority - начальный приоритет задачи

     instances - количество возможных экземпляров задачи

     stacksz - требования к размеру стека

     osThreadCreate(thread_def, argument):

     thread_def - определение атрибутов задачи на которые ссылается osThread

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

     osThread(name):

     name - имя задачи

/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{

  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END 5 */ 
}

/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the uart_task_1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartTask02 */
}

/* USER CODE BEGIN Header_StartTask03 */
/**
* @brief Function implementing the uart_task_2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask03 */
void StartTask03(void const * argument)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartTask03 */
}

     Строки 266-313, как видим имеется 3 функции задач с бесконечными циклами. Если раньше мы работали в одном бесконечном цикле функции main, то теперь можем работать с задачами как будто это отдельные маленькие программа со своими собственными правами. Задача никогда не выходит из своего бесконечного цикла.

Комментариев (0)

Написать комментарий

Имя *
E-mail
Введите комментарий *
Капча
18 + ? = 22