Перейти к содержанию
    

Периодический опрос датчика

Доброго всем времени суток!

 

Задача в целом тривиальна, но поскольку я впервые реализую ее с использование ОС, FreeRTOS в частности, то решил посоветоваться с более опытными людьми.

Абстрактно задача заключается в опросе ацп с заданной частотой и отправкой полученных данных в коммуникационный порт. Следовательно можно выделить две задачи для ОС - задача №1 опроса ацп и задача №2 отправки готовых данных. Приоритет задачи 1 > приоритета задачи 2. Соответственно, чтобы запустить опрос ацп, нужно отсчитывать таймером заданные интервалы времени и в прерывании по переполнению таймера запускать задачу 1.

 

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

Хотелось бы услышать 1) в целом верна ли моя концепция..или в рамках ОС можно сделать проще? Скажем отсчитывая периоды между опросами системным таймером ОС, но тогда снижается точность, если я правильно понял - интервал времени будет кратным системному тику.

2) данные между задачами нужно перебрасывать с помощью очереди в данном случае?

3) как лучше и/или проще пробудить задачу опроса ацп, блокированную событием таймера? Какое API для этого предоставляет FreeRTOS

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

 

Извините за некий сумбур...пока больше нахожусь на этапе сбора и осмысления информации. Все-таки работа с ОС требует некоторой перестройки мозгов, нежели standalone.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В этой концепции задача 1 просто лишняя: внутри прерывания таймера можно обслужить АЦП, а после накопления нужного количества данных известить об этом задачу 2.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

aaarrr

Хм...логично. Хотя вот вчера добрался до главы работы с прерываниями в FreeRTOS tutorial book, так там на первой странице вроде как ответ на мой вопрос. Вроде как не рекомендуется делать большие обработчики прерываний, поэтому задачу блокируют бинарным семафором, а в прерывании просто разблокируют, тогда задача начнет свое выполнение сразу после выхода из прерывания. Мне кажется такой подход как то красивее...или я не прав?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Следовательно можно выделить две задачи для ОС - задача №1 опроса ацп и задача №2 отправки готовых данных. ...

 

Опрос АЦП делать в отдельной задаче вообще не корректно.

Не знаю на каком микроконтроллере вы работаете, но стоит организовать аппаратное преобразование с сохранением в память по DMA.

А задача обмена просто читает из той памяти пользуясь тем, что DMA атомарно пишет слова.

 

Использовать механизмы RTOS на таком низком уровне неэффективно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

AlexandrY

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

Работаю с STM32. Насколько я понял из ваших слов, вы говорите о внутренней АЦП...в моей же задаче будет использоваться внешняя АЦП с SPI-интерфейсом, т.е. по прерыванию таймера должен работать аппаратный spi.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Стандартное решение. АЦП->SPI->DMA-> 2 'кольцевых' буфера. Один заполняется, второй в это время обрабатываете. Если скорость отсчётов не большая, то можно конечно и опросом, но как правило это не так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

поэтому задачу блокируют бинарным семафором, а в прерывании просто разблокируют, тогда задача начнет свое выполнение сразу после выхода из прерывания. Мне кажется такой подход как то красивее...или я не прав?
такой подход лучше реализовать без прерываний.
void task1(void*)
{
    portTickType xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount ();
    for(;;)
    {
         vTaskDelayUntil( &xLastWakeTime, 1000);
        //здесь читаем АЦП
        //здесь посылаем событие или сразу в компорт отправляем данные
    }
}

В таком случае чтение АЦП будет опрашиваться строго через каждые 1000 тиков. Точность будет мне кажется до 1 такта ЦПУ. с момента прерывания от системного таймера до момента переключения и входа в задачу task1() будет фиксированное кол-во тактов цпу (если конечно прерывание системного таймера не будет перекрыто более приоритетным прерыванием или запретом прерывания).

 

Стандартное решение. АЦП->SPI->DMA-> 2 'кольцевых' буфера. Один заполняется, второй в это время обрабатываете. Если скорость отсчётов не большая, то можно конечно и опросом, но как правило это не так.
Если частота выборок небольшая.... и чтение по спи быстрое, то vTaskDelayUntil вполне даже "красивее". Если конечно выборки частые, проц медленный, спи не быстрый...... то тут наверно применение АЦП->SPI->DMA будет оправдано. Иначе дма юзать - только если ради туториала.
Изменено пользователем juvf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...