Jump to content

    
Sign in to follow this  
Algol

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

Recommended Posts

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

 

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

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

 

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

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

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

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

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

 

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

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

aaarrr

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

Share this post


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

 

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

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

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

 

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

Share this post


Link to post
Share on other sites

AlexandrY

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

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

 

Share this post


Link to post
Share on other sites

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

Share this post


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

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

 

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this