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


КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 6 '2011



Pdf көрінісі
бет45/129
Дата28.09.2023
өлшемі4.1 Mb.
#478975
1   ...   41   42   43   44   45   46   47   48   ...   129
Kurniz

98
КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 6 '2011
компоненты
микроконтроллеры
Андрей КУРНИЦ
kurnits@stim.by
Необходимость 
использования очередей
Самый простой способ организовать об-
мен информацией между задачами — ис-
пользовать общую глобальную переменную. 
Доступ к такой переменной осуществляется 
одновременно из нескольких задач. Такой 
подход был продемонстрирован в [1, КиТ 
№ 4] в учебной программе № 3.
Однако такой подход имеет существен-
ный недостаток: при совместном досту-
пе нескольких задач к общей переменной 
возникает ситуация, когда выполнение одной 
задачи прерывается планировщиком именно 
в момент модификации общей переменной
когда та содержит не окончательное (иска-
женное) значение. При этом результат рабо-
ты другой задачи, которая получит управле-
ние и обратится к этой переменной, также 
окажется искаженным.
Продемонстрировать этот эффект позво-
ляет учебная программа № 1, в которой объ-
явлена глобальная переменная lVal и две за-
дачи: задача, которая модифицирует общую 
переменную, — vModifyTask(), и задача, кото-
рая проверяет значение этой переменной, — 
vCheckTask(). Модификация производится 
так, чтобы итоговое значение глобальной 
переменной после окончания вычислений 
не изменялось. В случае если значение общей 
переменной отличается от первоначального, 
задача vCheckTask() выдает соответствующее 
сообщение на экран.
Текст учебной программы № 1:
#include
#include
#include
#include “FreeRTOS.h”
#include “task.h”
#include “queue.h”
/* Глобальная переменная, доступ к которой будет 
* осуществляться из нескольких задач */
long lVal = 100;
/*------------------------------------------------------------------------*/
/* Функция, реализующая задачи, которая модифицирует 
* глобальную переменную */
void vModifyTask(void *pvParameters) {
/* Бесконечный цикл */
for (;;) {
/* Модифицировать переменную lVal так, 
* чтобы ее значение не изменилось */
lVal 
+= 
10;
lVal 
-= 
10;
}
}
/*------------------------------------------------------------------------*/
/* Функция, реализующая задачу, которая проверяет значение 
* переменной */
void vCheckTask(void *pvParameters) {
/* Бесконечный цикл */
for (;;) {
if (lVal != 100) {
puts(“Variable lVal is not 100!”);
}
vTaskDelay(100);
}
}
/*------------------------------------------------------------------------*/
/* Точка входа. С функции main() начнется выполнение 
* программы. */
int main(void) {
/* Создать задачи с равным приоритетом */
xTaskCreate(vModifyTask, “Modify”, 1000, NULL, 1, NULL);
xTaskCreate(vCheckTask, “Check”, 1000, NULL, 1, NULL);
/* Запуск планировщика. Задачи начнут выполняться. */
vTaskStartScheduler();
for 
(;;);
}
Результаты работы показывают (рис. 1), 
что значение глобальной переменной часто 
оказывается не равным ожидаемому (100).
Решить подобные проблемы позволяет ис-
пользование очередей для передачи инфор-
мации между задачами. Во FreeRTOS очереди 
представляют собой фундаментальный ме-
ханизм взаимодействия задач друг с другом. 
Они могут быть использованы для передачи 
информации как между задачами, так и меж-
ду прерываниями и задачами. Основное 
преимущество использования очередей — 
это то, что их использование является безо-


Достарыңызбен бөлісу:
1   ...   41   42   43   44   45   46   47   48   ...   129




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

    Басты бет