цифровая электроника
вычислительная техника
встраиваемые системы

 

Arduino и FreeRTOS: семафоры

Автор: Mike(admin) от 25-03-2020, 05:55

Операционная система реального времени FreeRTOS – это простая, легкая в использовании, надежная ОС, оптимизированная для Arduino IDE. В предыдущей статье мы рассмотрели, как использовать многозадачтость FreeRTOS в Arduino IDE. В этом проекте мы покажем, как использовать семафоры FreeRTOS для совместного использования и защиты физических ресурсов.


Arduino и FreeRTOS: семафоры

В среде Arduino IDE и среде доступно множество драйверов и библиотек, но среда Arduino ограничена простыми базовыми функциями setup() и loop() и не поддерживает эффективную многозадачность. В этой статье описывается использование мьютекс-семафоров в рамках простой в использовании и надежной реализации FreeRTOS, которая включена в Arduino IDE в качестве библиотеки и позволяет использовать лучшие функции обеих сред.


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


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


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


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


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


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


В предыдущей статье мы описали, как установить библиотеку FreeRTOS для Arduino IDE и проверить, что она работает правильно. Если вы еще не сделали этот шаг, сделайте это сейчас.


Теперь либо загрузите файл AnalogRead_DigitalRead.ino в Arduino IDE, либо скопируйте и вставьте приведенный ниже код в новый файл, который вы должны соответствующим образом назвать и сохранить. В скетче есть несколько шагов для создания и использования мьютексного семафора для защиты последовательного порта. Соответствующая данному скетчу схема подключения приведена далее.


Arduino и FreeRTOS: семафоры

Теперь, когда задача желает использовать функции Serial.println() последовательного порта, она должна убедиться, что она заранее «приняла» семафор последовательного порта. Когда задача с последовательным портом завершается, она должна «отдать» семафор, чтобы другие задачи могли получить доступ к порту.



#include <Arduino_FreeRTOS.h>
#include <semphr.h>

SemaphoreHandle_t xSerialSemaphore;

void TaskDigitalRead( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

void setup() {

  Serial.begin(9600);

  if ( xSerialSemaphore == NULL )
  {
    xSerialSemaphore = xSemaphoreCreateMutex();
    if ( ( xSerialSemaphore ) != NULL )
      xSemaphoreGive( ( xSerialSemaphore ) );
  }

  xTaskCreate(
    TaskDigitalRead
    ,  (const portCHAR *)"DigitalRead"
    ,  128
    ,  NULL
    ,  2
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  (const portCHAR *) "AnalogRead"
    ,  128
    ,  NULL
    ,  1
    ,  NULL );

}

void loop()
{

}


void TaskDigitalRead( void *pvParameters __attribute__((unused)) )
{

  uint8_t pushButton = 2;

  pinMode(pushButton, INPUT);

  for (;;)
  {
    int buttonState = digitalRead(pushButton);

    if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
    {

      Serial.println(buttonState);

      xSemaphoreGive( xSerialSemaphore );
    }

    vTaskDelay(1);
  }
}

void TaskAnalogRead( void *pvParameters __attribute__((unused)) )
{

  for (;;)
  {
    int sensorValue = analogRead(A0);

    if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
    {

      Serial.println(sensorValue);

      xSemaphoreGive( xSerialSemaphore );
    }

    vTaskDelay(1);
  }
}



© digitrode.ru


Теги: Arduino, FreeRTOS




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

Комментарии:

Оставить комментарий