Компоненты и технологии • №2 '2011 компоненты


#define configUSE_TIMERS  1 #define



Pdf көрінісі
бет129/129
Дата28.09.2023
өлшемі4.1 Mb.
#478975
1   ...   121   122   123   124   125   126   127   128   129
Kurniz

#define configUSE_TIMERS 
1
#define configTIMER_TASK_PRIORITY 
1
#define configTIMER_QUEUE_LENGTH 
( 10 )
#define configTIMER_TASK_STACK_DEPTH 
configMINIMAL_STACK_SIZE
Результат работы учебной программы приведен на рис. 6.
В учебной программе демонстрируется прием, когда запуск (в дан-
ном случае сброс, как было сказано выше — не имеет значения) тай-
меров производится ДО запуска планировщика. В этом случае тайме-
ры начинают отсчет времени сразу после старта планировщика.
В графическом виде работа учебной программы представлена 
на рис. 7.
Учебная программа демонстрирует также разницу между интер-
вальными и периодическими таймерами. Как видно на рис. 6 и 7, бу-
дучи единожды запущен, интервальный таймер вызовет свою функ-
цию один раз. Периодический же таймер напротив — вызывает свою 
функцию до тех пор, пока не будет удален или остановлен.
Справедливости ради следует отметить, что на практике можно 
обойтись без использования идентификатора таймера для определе-
ния, какой таймер вызвал функцию таймера, как это сделано в учеб-
ной программе.
рис. 6. Выполнение учебной программы
рис. 7. Отсчет временных промежутков в учебной программе


100
КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 10 '2011
компоненты
микроконтроллеры
Для этой цели вполне достаточно использовать дескриптор тайме-
ра. В таком случае функция интервальных таймеров в модифициро-
ванной учебной программе примет вид:
/* Функция интервальных таймеров.
* Нескольким экземплярам интервальных таймеров соответствует одна-единственная функция.
* Эта функция автоматически вызывается при истечении времени любого из связанных с ней таймеров.
* Для того чтобы выяснить, время какого таймера истекло, используется идентификатор таймера. */
void vOneShotTimersFunction(xTimerHandle xTimer) {
/* Различные действия в зависимости от того, какой таймер вызывал функцию */
/* Сработал интервальный таймер 1? */
if (xTimer == xOneShotTimers[0]) {
/* Индикация работы + текущее время */
printf(“\t\t\t\tOneShot timer ID = %d. Time = %d sec\n\r”, *pxTimerID, xTaskGetTickCount() /
configTICK_RATE_HZ);
xTimerChangePeriod(xAutoReloadTimer, 6000, 0);
/* Запустить интервальный таймер 2 */
xTimerStart(xOneShotTimers[1], 0);
/* Сработал интервальный таймер 2? */
} else if (xTimer == xOneShotTimers[1]) {
/* Индикация работы + текущее время */
printf(“\t\t\t\tOneShot timer ID = %d. Time = %d sec\n\r”, *pxTimerID, xTaskGetTickCount() /
configTICK_RATE_HZ);
/* Запустить интервальный таймер 3 */
xTimerStart(xOneShotTimers[2], 0);
/* Сработал интервальный таймер 3? */
} else if (xTimer == xOneShotTimers[2]) {
/* Индикация работы + текущее время */
printf(“\t\t\t\tOneShot timer ID = %d. Time = %d sec\n\r”, *pxTimerID, xTaskGetTickCount() /
configTICK_RATE_HZ);
puts(“\n\r\t\t\t\tAbout to delete AutoReload timer!”);
fflush();
/* Удалить периодический таймер.
* После этого активных таймеров в программе не останется. */
xTimerDelete(xAutoReloadTimer, 0);
}
}
Дескрипторы созданных интервальных таймеров хранятся в гло-
бальном массиве. Кроме того, дескриптор таймера, который привел 
к вызову функции таймера, передается в эту функцию в виде ее ар-
гумента. Поэтому выполняя сравнение аргумента функции таймера 
с дескриптором, который хранится в глобальной переменной, можно 
сделать вывод о том, какой конкретно таймер инициировал вызов 
этой функции таймера.
Результат выполнения модифицированной учебной программы 
ничем не будет отличаться от приведенного на рис. 6, что подтверж-
дает, что для однозначной идентификации таймера вполне достаточ-
но иметь его дескриптор.
Выводы
Подводя итог можно сказать, что их применение оправдано в слу-
чаях, когда к точности отмеряемых временных интервалов не предъ-
является высоких требований, так как активность других задач в про-
грамме может существенно повлиять на точность работы програм-
мных таймеров. Кроме того, немаловажным ограничением является 
дискретность работы таймеров величиной в один системный квант 
времени.
В дальнейших публикациях речь пойдет о способах отладки про-
граммы, которая выполняется под управлением FreeRTOS. Внимание 
будет сконцентрировано на:
способах трассировки программы;

получении статистики выполнения в реальном времени;

способах измерения потребляемого задачей объема стека и спосо-

бах защиты от его переполнения.
n
Литература
1. Курниц А. FreeRTOS — операционная система для микроконтроллеров //
Компоненты и технологии. 2011. № 2–9.
2. 
www.freertos.org
3. 
http://ru.wikipedia.org/wiki/FreeRTOS
4. 
http://electronix.ru/forum/index.php?showforum=189
5. 
http://sourceforge.net/projects/freertos/files/FreeRTOS/
6. 
http://www.ee.ic.ac.uk/t.clarke/rtos/lectures/RTOSlec2x2bw.pdf 


Достарыңызбен бөлісу:
1   ...   121   122   123   124   125   126   127   128   129




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет