Algol 0 11 марта, 2012 Опубликовано 11 марта, 2012 · Жалоба Доброго всем времени суток! Задача в целом тривиальна, но поскольку я впервые реализую ее с использование ОС, FreeRTOS в частности, то решил посоветоваться с более опытными людьми. Абстрактно задача заключается в опросе ацп с заданной частотой и отправкой полученных данных в коммуникационный порт. Следовательно можно выделить две задачи для ОС - задача №1 опроса ацп и задача №2 отправки готовых данных. Приоритет задачи 1 > приоритета задачи 2. Соответственно, чтобы запустить опрос ацп, нужно отсчитывать таймером заданные интервалы времени и в прерывании по переполнению таймера запускать задачу 1. Сейчас нахожусь на стадии чтения туториала по FreeRTOS..задачи моргания светодиодами и выдачи в консоль данных сделаны. Хотелось бы услышать 1) в целом верна ли моя концепция..или в рамках ОС можно сделать проще? Скажем отсчитывая периоды между опросами системным таймером ОС, но тогда снижается точность, если я правильно понял - интервал времени будет кратным системному тику. 2) данные между задачами нужно перебрасывать с помощью очереди в данном случае? 3) как лучше и/или проще пробудить задачу опроса ацп, блокированную событием таймера? Какое API для этого предоставляет FreeRTOS или же в прерывании от таймера просто искусственно повысить приоритет задачи опроса, чтобы по выходу из прерывания планировщик переключился на нее. Извините за некий сумбур...пока больше нахожусь на этапе сбора и осмысления информации. Все-таки работа с ОС требует некоторой перестройки мозгов, нежели standalone. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 11 марта, 2012 Опубликовано 11 марта, 2012 · Жалоба В этой концепции задача 1 просто лишняя: внутри прерывания таймера можно обслужить АЦП, а после накопления нужного количества данных известить об этом задачу 2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Algol 0 12 марта, 2012 Опубликовано 12 марта, 2012 · Жалоба aaarrr Хм...логично. Хотя вот вчера добрался до главы работы с прерываниями в FreeRTOS tutorial book, так там на первой странице вроде как ответ на мой вопрос. Вроде как не рекомендуется делать большие обработчики прерываний, поэтому задачу блокируют бинарным семафором, а в прерывании просто разблокируют, тогда задача начнет свое выполнение сразу после выхода из прерывания. Мне кажется такой подход как то красивее...или я не прав? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 12 марта, 2012 Опубликовано 12 марта, 2012 · Жалоба Следовательно можно выделить две задачи для ОС - задача №1 опроса ацп и задача №2 отправки готовых данных. ... Опрос АЦП делать в отдельной задаче вообще не корректно. Не знаю на каком микроконтроллере вы работаете, но стоит организовать аппаратное преобразование с сохранением в память по DMA. А задача обмена просто читает из той памяти пользуясь тем, что DMA атомарно пишет слова. Использовать механизмы RTOS на таком низком уровне неэффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Algol 0 12 марта, 2012 Опубликовано 12 марта, 2012 · Жалоба AlexandrY Прошу прощения, что возможно ввел в заблуждение стремлением абстрагировать задачу от архитектуры. Работаю с STM32. Насколько я понял из ваших слов, вы говорите о внутренней АЦП...в моей же задаче будет использоваться внешняя АЦП с SPI-интерфейсом, т.е. по прерыванию таймера должен работать аппаратный spi. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
viterra 0 13 апреля, 2012 Опубликовано 13 апреля, 2012 · Жалоба Стандартное решение. АЦП->SPI->DMA-> 2 'кольцевых' буфера. Один заполняется, второй в это время обрабатываете. Если скорость отсчётов не большая, то можно конечно и опросом, но как правило это не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 13 апреля, 2012 Опубликовано 13 апреля, 2012 (изменено) · Жалоба поэтому задачу блокируют бинарным семафором, а в прерывании просто разблокируют, тогда задача начнет свое выполнение сразу после выхода из прерывания. Мне кажется такой подход как то красивее...или я не прав? такой подход лучше реализовать без прерываний. void task1(void*) { portTickType xLastWakeTime; xLastWakeTime = xTaskGetTickCount (); for(;;) { vTaskDelayUntil( &xLastWakeTime, 1000); //здесь читаем АЦП //здесь посылаем событие или сразу в компорт отправляем данные } } В таком случае чтение АЦП будет опрашиваться строго через каждые 1000 тиков. Точность будет мне кажется до 1 такта ЦПУ. с момента прерывания от системного таймера до момента переключения и входа в задачу task1() будет фиксированное кол-во тактов цпу (если конечно прерывание системного таймера не будет перекрыто более приоритетным прерыванием или запретом прерывания). Стандартное решение. АЦП->SPI->DMA-> 2 'кольцевых' буфера. Один заполняется, второй в это время обрабатываете. Если скорость отсчётов не большая, то можно конечно и опросом, но как правило это не так. Если частота выборок небольшая.... и чтение по спи быстрое, то vTaskDelayUntil вполне даже "красивее". Если конечно выборки частые, проц медленный, спи не быстрый...... то тут наверно применение АЦП->SPI->DMA будет оправдано. Иначе дма юзать - только если ради туториала. Изменено 13 апреля, 2012 пользователем juvf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться