Вход |  Регистрация
 
 
Время электроники Суббота, 23 февраля
 
 


Это интересно!

Новости


Обзоры, аналитика


Интервью, презентации

Ранее

Открытое программное обеспечение в потребительской электронике: что, зачем и как

В статье рассматривается назначение открытого программного обеспечения и области его применения, анализируются цели и вопросы взаимодействия производителей с сообществом разработчиков ПО на основе открытого исходного кода Linux. В качестве примера рассматривается участие компании Texas Instruments в различных проектах и организациях по разработке открытого исходного кода, в т.ч. в альянсе Open Handset Alliance (OHA), основанном Google.

Встраиваемому контроллеру не всегда нужен центральный процессор

В статье рассмотрен подход к построению интеллектуальной периферии микроконтроллера (МК) с помощью программируемого логического устройства (ПЛУ) и тракта обработки данных, что позволяет разгрузить центральный процессор от ряда задач и повысить эффективность и надежность системы.

VIA Technologies — новые технологии и промышленные стандарты

VIA Technologies, Inc. является ведущим разработчиком энергосберегающих процессорных платформ с х86-архитектурой для рынка промышленных компьютеров, автоматизированных систем управления и мониторинга, а также для мобильных приложений.

Реклама

По вопросам размещения рекламы обращайтесь в отдел рекламы

Реклама наших партнеров

 

10 июня

Особенности работы операционной системы реального времени FreeRTOS

В статье представлены особенности операционной системы реального времени FreeRTOS, которая применяется для разработки встроенного программного обеспечения (ПО). Алгоритмы FreeRTOS основаны на вытеснении низкоприоритетных задач высокоприоритетными, с возможностью целостного исполнения кода задач посредством механизмов синхронизации.



В

настоящее время к оборудованию, для которого разрабатывается встроенное ПО, предъявляются новые требования по надежности, времени реакции на событие и объему выполняемых функций. Это приводит к усложнению логики работы программ. Другими словами, эра тривиальных задач подходит к концу или может быть уже завершена, а для решения нетривиальных задач разработчику необходим своего рода помощник. Операционная система реального времени (ОСРВ) или микроядро, о котором мы рассказывали в статье [1], прекрасно выполняет роль помощника разработчика. ОСРВ с легкостью берет на себя часть рутинной работы, а главное — реализует механизм псевдопараллельного исполнения кода задач.
За использование ОСРВ в коммерческих приложениях принято платить, однако появляется все больше ОСРВ, которые могут использоваться в коммерческих приложениях совершенно бесплатно. Примером является ОСРВ FreeRTOS, которая портирована более чем на 20 платформ (микроконтроллеров) и потребует от аппаратного обеспечения от 32 Кбайт флэш-памяти и от 16 Кбайт ОЗУ. FreeRTOS предоставляет­ся с открытым исходным кодом программ и лицензирована в соответствии с GNU General Public License (GPL).


Основные особенности FreeRTOS:

– работа диспетчера задач в двух режимах: вытесняющей многозадачности и кооперативной многозадачности;
– отсутствие ограничений на количество задач, которые может создать пользователь. Теоретически можно создать бесконечное количество задач, при условии бесконечного объема ОЗУ;
– широкий выбор механизмов синхронизации: двоичные, счетные, рекурсивные семафоры, мьютексы;
– очередь сообщений — для обеспечения межзадачной коммуникации;
– функции управления временем, предусматривающие возможность периодического запуска задач;
– функции управления памятью;
– функции статистики времени выполнения задач.
Для определения принципов работы FreeRTOS введем основные понятия, которые используются в статье:
– задача — набор операций (ма-
шинных инструкций), предназначен-ный для выполнения логически законченной функции системы. При этом задача конкурирует с другими задачами за получение контроля над ресурсами вычислительной системы;
– контекст задачи — набор данных, содержащий всю необходимую информацию для возобновления выполнения задачи с того места, где она была прервана;
– стек — структура данных с методом доступа к элементам LIFO (Last In — First Out). Вместе с областью статических данных полностью задает текущее состояние задачи [2];
– диспетчер задач — программа, которая отвечает за управление совместным ресурсом и последовательность выполнения всех успешно проинициализированных задач;
– очередь сообщений — структура данных, позволяющая передавать данные фиксированной длины от одной задачи к другой;
– переключение контекста — алгоритм сохранения в стек контекста прерванной задачи и восстановления из стека контекста запускаемой задачи;
– тик таймера — период возникновения циклического прерывания от таймера;
– критическая секция — часть кода задачи, которая не должна прерываться только другими критическими секциями, исключающими друг друга из заданного набора задач [2].
Если театр начинается с вешалки, расследование преступления — с оп­роса свидетелей, то работа FreeRTOS начинается с конфигури­рования. Конфи­гура­ционный файл (FreeRTOSConfig.h)
содержит основные настройки ОСРВ (указывается частота, на которой работает CPU и периферийные устройства, диапазон приоритетов задач, размер стека и т.д.) [3]. Некорректная работа механизмов и функций FreeRTOS очень часто связана с неправильным конфигурированием. Например, невозможно создать и правильно использовать механизм синхронизации мьютекс без описания соответствующего макро­определения #define config_USE_MUTEX 1.
Важный этап разработки встроенного ПО — это декомпозиция или фрагментация всего объема выполняемых действий на отдельные, порой связанные между собой задачи или потоки (в терминологии FreeRTOS и далее по тексту — задачи), которые выполняются процессором (CPU) в соответствии с выбранным алгоритмом диспетчеризации. Для разработчика, который использует в своей работе FreeRTOS, задача — это обособленный программный код, оформленный в виде бесконечного цикла. Задача имеет структуру-описатель, так называемый TCB (Task Control Block), который содержит имя, указатель стека, приоритет и другие данные. Для того чтобы зарегистрировать или создать задачу в ОСРВ FreeRTOS, необходимо вызвать системную функцию vTaskCreate (). Задача может находиться в одном из следующих типичных состояний, представленных на рисунке 1.

 

Рис. 1. Схема возможных состояний задачи

Состояния задачи:
– Running (выполняется) — задача выполняется и использует CPU. В любой момент времени только одна задача может находиться в состоянии Running;
– Ready (готова) — задача не заблокирована, не остановлена, но не выполняется. Например, задача может не выполняться CPU, если в данный момент выполняется другая, более приоритетная задача;
– Blocked (заблокирована) — задача ждет некоторого события, которые бывают двух видов:
– события, возникающие по завершении тайм-аута (интервала времени). Например, задача заблокирована на время ожидания, равное 10 мс. По завершении тайм-аута, задача перейдет в состояние Ready;
– события синхронизации — в этом случае источниками события становятся прерывания или другая задача. Например, задача заблокирована до тех пор, пока не получит сообщения посредством очереди сообщений.
– Suspended (остановлена) — задача не доступна для диспетчера задач. Задача попадает в состояние Suspended при вызове функции vTaskSuspended(), а выходит из этого состояния по вызову функции vTaskResume().
В случае, если в списке Ready нет ни одной задачи, диспетчер задач запустит фоновую задача (Idle Task) со значением приоритета равным нулю, что соответствует наименьшему приоритету. Существует возможность добавления кода программ в тело фоновой задачи. В коде фоновой задачи не должно быть вызова функций блокирования и функции vTaskDelete(). Фоновая задача может находиться в двух возможных состояниях: Ready — когда выполняется более приоритетная задача и Running — когда CPU исполняет фоновую задачу.
Задача имеет свой собственный стек, в котором сохраняются локальные переменные, результат выполнения функции и регистры CPU при возникновении прерывания. Разработчик может создать такое количество задач, какое может ему понадобиться, а к ограничениям можно отнести память, которая выделяется для стека, для ТСВ и… здравый смысл разработчика.
Всеми успешно проинициализированными задачами управляет диспетчер задач, который всегда работает в одном из двух возможных режимов:
– режиме вытеснения задач, согласно их приоритету (далее — вытесняющая многозадачность);
–  кооперативном режиме исполнения задач (далее — кооперативная многозадачность).
Механизм вытесняющей многозадачности работает по двум правилам:
1. Высокоприоритетная задача вытесняет низкоприоритетную задачу. Например, Task_A (приоритет равен 2) вытесняет Task_B (приоритет равен 1). Если Task_A завершил свое выполнение или заблокировался, то диспетчер задач продолжит выполнять Task_B (см. рис. 2).

 

Рис. 2. Схема работы вытесняющей многозадачности для задач с разным приоритетом: 1) переключение контекста, запуск Task_B; 2) код Task_B; 3) переключение контекста, запуск Task_A; 4) код Task_A; 5) переключение контекста, продолжение выполнения Task_B; 6) переключение контекста, продолжение выполнения фоновой задачи

2. Если существуют две и более задач с одинаковым приоритетом — то они выполняются последовательно, а каждой задаче для выполнения выделен временной промежуток или квант (Time slice). По истечении времени выполнения одной задачи диспетчер задач запустит следующую задачу с тем же приоритетом (см. рис. 3).

 

Рис. 3. Схема работы вытесняющей многозадачности для задач с одинаковыми приоритетами: 1) интервал времени (Time Slice) завершен; 2) код разных задач с одинаковыми приоритетом; 3) переключение контекста, запуск следующей задачи; 4) интервал времени (квант)

Как следует из рисунка 2, при каждом вытеснении задач сохраняется контекст прерванной задачи и восстанавливается контекст запускаемой задачи. Время выполнения этих действий является накладным расходом системы. Например, для микропроцессоров SH2A сохранить и восстановить контекст — это 80 простейших ассемблерных инструкций. Как видно из рисунка 2, чтобы приостановить выполнение Task_B и выполнить Task_A, а потом снова продолжить Task_B, CPU необходимо потратить время на выполнение порядка 160 ассемблерных инструкций. Это без учета времени выполнения функций диспетчера задач! На наш взгляд, при таком подходе ощущается нехватка механизма анализа продолжительности действий, которые необходимо выполнить Task_B до логического завершения, прежде чем более приоритетная задача вытеснит Task_B.
Кооперативная многозадачность подразумевает «добровольную» передачу управления от одной задачи к другой посредством вызова системной функции taskYIELD() (см. рис. 4). Из рисунка 4 следует, что для кооперативной многозадачности предусмотрена гибридная схема работы, т.е. добровольная передача управления для задач с одинаковым приоритетом и приоритетное вытеснение при запуске задач с более высоким приоритетом. Режим кооперативной многозадачности исключает возможность выполнения задач в соответствии с выделенным квантом времени.

 

Рис. 4. Схема работы кооперативной многозадачности: 1) код разных задач; 2) «добровольная» передача управления с помощью функции taskYIELD(), которая выполняет переключение контекста; 3) переключение контекста и запуск приоритетной задачи; 4) код приоритетной задачи; 5) переключение контекста и запуск прерванной задачи

Важной характеристикой ОСРВ является наличие механизмов по управлению общими ресурсами, которыми одновременно могут пользоваться сразу несколько задач. К таким ресурсам относятся в основном память и CPU. Именно объекты синхронизации позволяют задаче получить уникальный доступ к ресурсу и выполнить критическую секцию кода без вмешательства со стороны других задач. К объектам синхронизации, которые реализованы в ОСРВ FreeRTOS, относятся:
– семафоры (двоичные, счетные, рекурсивные);
– мьютексы;
– очереди сообщений.
Объекты синхронизации выполняют три основные задачи:
–  разделение ресурса. Например, две задачи пытаются получить доступ к общему ресурсу;
– синхронизацию. Например, запуск задачи в связи с возникновением события;
– обмен информацией между задачами посредством очередей сообщений (эта функция справедлива только для очередей сообщений).
Аналогично задаче семафор должен быть зарегистрирован в системе с помощью функции vSemaphoreCreateBinary(). Механизм работы семафора достаточно прост. Логическое значение семафора (далее семафор) равно нулю, следовательно, ресурс занят. Семафор равен единице (в случае бинарного семафора), следовательно, ресурс свободен. Типичным примером использования бинарного семафора является алгоритм чтения и записи данных между двумя задачами, где Task_A является поставщиком данных, а Task_B является потребителем этих данных (см. рис. 5).

 

Рис. 5. Схема работы бинарного семафора

Как представлено на рисунке 5, Task_A записывает данные в опреде­ленный буфер памяти, а Task_B считывает данные из этого буфера. Критиче­ским ресурсом в данном примере является память, а операции записи в буфер и чтения из буфера должны выполняться целостно по отношению друг к другу. Прежде чем выполнить операцию записи, Task_A проверяет семафор путем вызова функции xSemaphoreTake(). Если ресурс свободен (семафор = 1), то Task_A получит доступ к ресурсу и начнет выполнять действия, связанные с записью данных в буфер. В этот момент возникает более приоритетный Task_B, которому нужно совершить операцию чтения. Ресурс занят (семафор = 0), поэтому Task_B заблокируется (состояние Blocked). Task_A продолжит выполнение, завершит целостно всю операцию записи и освободит ресурс путем вызова функции xSemaphoreGive(). Ресурс свободен, следовательно, будет запущен высокоприоритетный Task_B, который завершит целостно всю операцию чтения и освободит ресурс путем вызова функции xSemaphoreGive().
Аналогичным образом семафор может быть использован для разграничения доступа к критическому ресурсу, который используют несколько задач. В любой момент времени только одна задача может «захватить» семафор, остальные задачи при обращении к семафору будут вставать в очередь и ожидать его освобождения.
В ОСРВ FreeRTOS семафоры и мьютексы работают по одному и тому же принципу, т.е., мьютекс — это тот же бинарный семафор, однако при использовании мьютекса подключается механизм, предотвращающий инверсию приоритетов с помощью метода наследования приоритетов.
Счетные семафоры работают аналогично бинарным. Отличие заключается в том, что значение счетного семафора может быть равным 1, 2, 3, 4 и т.д. Например, семафор, который проинициализирован значением, равным 3, можно успешно «захватить» ровно 3 раза. Попытка «захватить» семафор в четвертый раз приведет к тому, что задача заблокируется, ведь семафор равен нулю, следовательно, ресурс занят.
Выполнение продолжительных действий в функции обработчика прерывания приводит к задержке выполнения и потере других источников прерываний, поэтому целесообразно выполнять продолжительные действия в коде задачи, синхронизированной относительно прерывания. Рассмотрим пример использования счетного семафора, максимальное значение которого может быть равно трем, для синхронизации задачи относительно момента возникновения события или прерывания (см. рис. 6).

 

Рис. 6. Схема синхронизации выполнения задачи с помощью счетного семафора: 1) возникновение прерывания; 2) код обработчика прерывания, инкремент значения семафора (семафор = 1); 3) переключение контекста, декремент значения семафора (семафор = 0), запуск Task_A на выполнение; 4) не выполняется переключение контекста, не выполняется декремент значения семафора, (семафор = 1), продолжение выполнения Task_A; 5) код Task_A, (семафор = 0); 6) первая попытка Task_A перейти в состояние Blocked, (семафор = 1); 7) вторая попытка Task_A перейти в состояние Blocked, (семафор = 0); 8) восстановление контекста и запуск фоновой задачи

Как следует из рисунка 6, при возникновении события текущее выполнение команд приостанавливается, запускается обработчик прерывания. В обработчике прерывания вызывается функция xSemaphoreGiveFromISR(), которая инкрементирует значение семафора, инициируя тем самым запуск Task_A. Если во время исполнения Task_A возникнет прерывание, то значение семафора инкрементируется, поэтому первая попытка Task_A перейти в состояние Blocked приводит к простому декременту семафора, а задача уходит на «второй круг» выполнения. Вторая попытка Task_A перейти в состояние Blocked приводит к тому, что Task_A переходит в состояние Blocked и запускается фоновая задача. Таким образом, выполнение задачи синхронизировано с возникновением события, а системная функция xSemaphoreGiveFromISR() является инициатором запуска выполнения соответствующей задачи.
Очень важно помнить, что обработчик прерывания оформляется по определенным правилам. В теле обработчиков прерываний вызываются специальные системные функции с постфиксом FromISR. По завершении кода обработчика прерывания необходимо переключить контекст в том случае, если приоритет прерванной задачи ниже, чем приоритет инициируемой (запускаемой) задачи. Вот как выглядит пример кода обработчика прерывания, показанного на рисунке 6:

static void vExampleInterruptHandler( void )
{
static portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
/* Выполнить действия */
...
/* Отпустить семафор. */
xSemaphoreGiveFromISR( xCountSemaphore, &xHigherPriorityTaskWoken );
/*Анализируем, нужно ли переключить контекст*/
if( xHigherPriorityTaskWoken == 1 )
{
/*Переключить контекст*/
portSWITCH_CONTEXT();
}
}
Обмен информацией между задачами осуществляется посредством очереди сообщений. Очередь сообщений можно рассматривать как буфер, который состоит из блоков фиксированной длины. Параметры очередей сообщений разработчик определяет в функции инициализации очереди xQueueCreate(). Очередь сообщений выступает в роли объекта синхронизации при запуске одной задачи относительно выполнения другой (см. рис. 7).

 

Рис. 7. Схема передачи сообщений посредством очереди сообщений

Task_A занимается передачей сообщения, Task_B обрабатывает эти сообщения. Выполнение Task_B бессмысленно, если нечего обрабатывать, поэтому Task_B запускается на выполнение и блокируется при вызове функции xQueueReceive(). Как только Task_A передаст элемент в очередь сообщений, Task_B продолжит свое выполнение. Теоретически Task_A может передавать сообщения гораздо быстрее, чем Task_B их обрабатывать. В этом случае очередь сообщений выступает в роли демпфера при возникновении критической нагрузки. Однако если Task_A переполнит очередь сообщений, то Task_A заблокируется до тех пор, пока Task_B не обработает по крайней мере одно сообщение.
Безусловно, все функции, выполняющие механизмы объектов синхронизации требуют времени CPU для своего выполнения — это накладные расходы системы. Время выполнения большинства системных функций должно быть определено опытным путем, хотя бы с точностью 50% для выбранного микроконтроллера. Это очень важно, особенно, если встроенное ПО разрабатывается по требованиям жесткого реального времени. Нецелесообразно защищать семафором с помощью функций xSemaphoreTake(), xSemaphoreGive(), суммарно выполняемых за 10 мс, участок кода, который выполняется 100 мкс! В этом случае необходимо использовать какую-то альтернативу.
Альтернативными методами разграничения доступа к критическому участку являются:
– механизм запрета выполнения диспетчера задач. Функция запрета выполнения диспетчера задач — vTaskSuspendAll(). Функция разрешения выполнения диспетчера задач — xTaskResumeAll();
– механизм запрета возникновения прерываний. Функция запрета выполнения прерывания — taskENTER_CRITICAL(). Функция разрешения выполнения прерывания — taskEXIT_CRITICAL().
Механизм запрета выполнения диспетчера задач заключается в том, что запрещена передиспетчеризация задач, т.е. задача с высоким приоритетом не вытесняет задачу с низким приоритетом. Метод достаточно эффективен, особенно при условии, что возникновение прерываний разрешено. Отрицательная сторона этого подхода состоит в том, что высокоприоритетные задачи, инициированные из обработчиков прерываний, не выполняются в течение интервала времени, пока запрещено выполнение диспетчера задач. Закрывать прерывания — это самый низкозатратный метод с точки зрения количества выполняемых команд. Отрицательная сторона этого подхода состоит в том, что при запрете возникновения прерываний на продолжительное время возрастает вероятность потери события.
Кроме функций управления задачами в ОСРВ FreeRTOS реализованы функции управления временем (Time Management Function), которые преследуют несколько целей:
– периодического запуска задач;
– исключения возможности бесконечного блокирования задач по причине заблокированного ресурса;
– формирования статистических отчетов времени исполнения задач.
Необходимость периодического запуска задач обусловлена потребностью выполнения определенных действий через равные промежутки времени. Например, модуль аналогового ввода, который входит в состав ПЛК, должен периодически, с частотой 1 Гц, передавать в центральный процессор результаты диагностики корректной работы измерительных каналов. Разработчику, который использует ОСРВ в своих разработках, необходимо проинициализировать задачу — Task_A, вызвать процедуры диагностики, формирования сообщения, инициации передачи и вызвать функцию vTaskDelay(), как показано в листинге кода Task_A:

void Task_A( void * pvParameters )
{
for( ;; )
{
/*Запуск диагностики, формирование сообщения, передача сообщения*/

/*Система, разбуди меня через секунду. Ну пожалуйста! */
vTaskDelay( 1000 );
}
}
В вышеописанном примере Task_A выполняет полезные действия и блокируется на 1 с. По завершении интервала времени диспетчер задач запустит Task_A, который выполнится и будет отложен на 1 с. У всех без исключения функций, которые могут инициировать переход задачи из состояния Running в состояние Blocked (в случае, если ресурс занят другой задачей), определяется специальный параметр — xTicksToWait. Список функций представлен ниже:
– xSemaphoreTake (xSemaphore, xTicksToWait);
– xSemaphoreTakeRecursive (xMutex, xTicksToWait);
– xQueueReceive (xQueue, *pvBuffer, xTicksToWait );
– xQueuePeek (xQueue, *pvBuffer, xTicksToWait );
– xQueueSend (xQueue, *pvItemToQueue, xTicksToWait);
– xQueueSendToFront (xQueue, *pvItemToQueue, xTicksToWait);
– xQueueSendToBack (xQueue, *pvItemToQueue, xTicksToWait).
Параметр xTicksToWait определяет временной интервал, равный количеству тиков таймера, в течение которого задача остается в состоянии Blocked. Параметр xTicksToWait всегда кратен тику таймера и может принимать следующие значения:
1. xTicksToWait = 0. Задача не переходит в состояние Blocked, а продолжает выполнение.
2. xTicksToWait = value. Задача заблокируется, но продолжит выполнение по завершении тайм-аута, равного value, даже если ресурс остается занят другой задачей;
3. xTicksToWait = portMAX_DELAY. Задача заблокируется до тех пор, пока ресурс остается занят.
На рисунке 8 показан механизм сброса блокировки задачи по завершении временного интервала.

 

Рис. 8. Схема сброса блокировки задачи: 1) возникновение прерывания (событие произошло); 2) код обработчика прерывания; 3) переключение контекста, запуск Task_A на выполнение; 4) код Task_A; 5) вызов функции xSemaphoreTake(); 6) интервал времени, при котором Task_A находится в состоянии Blocked; 7) завершение интервала времени ожидания события (событие не произошло), переключение контекста, запуск Task_A на выполнение; 8) переключение контекста, запуск фоновой задачи

Одной из распространенных ошибок, связанных с некорректным выполнением задач согласно их приоритету, является инверсия приоритетов. Инверсия приоритетов возникает тогда, когда в системе есть как минимум три задачи с разными приоритетами, а две из них разделяют доступ к общему ресурсу. Для предотвращения инверсии приоритетов в ОСРВ FreeRTOS используется механизм наследования приоритетов (Priority Inheritance), представленный на рисунке 9.

 

Рис. 9. Схема предотвращения инверсии приоритетов с помощью метода наследования приоритетов: 1) код Task_A, уровень приоритета равен 1; 2) переключение контекста, запуск Task_C; 3) код Task_C, уровень приоритета равен 3; 4) код Task_A, уровень приоритета равен 3; 5) уровень приоритета равен 1, переключение контекста, запуск Task_B; 5*) уровень приоритета равен 3, запуск Task_B отложен; 6) код Task_B, уровень приоритета равен 2; 7) Task_B завершен, переключение контекста, запуск Task_А; 8) ресурс занят , переключение контекста, Task_А унаследовал приоритет Task_C, запуск Task_А; 9) ресурс свободен, переключение контекста, запуск Task_C; 10) Task_C завершен, переключение контекста, запуск Task_А; 11) Task_B завершен, переключение контекста, запуск Task_А

Механизм наследования приоритетов уменьшает интервал t1, во время которого задача с высоким приоритетом не может быть выполнена. Инверсию приоритетов достаточно сложно идентифицировать на этапе отладки программ. Механизм наследования приоритетов работает только при условии, что выбранным объектом синхронизации является мьютекс. Все другие объекты синхронизации, реализованные в ОСРВ FreeRTOS, не предотвращают инверсии приоритетов.
Еще одной распространенной ошибкой, которая очень трудно поддается процессу отладки, является ошибка взаимного блокирования задач (DeadLock) (см. рис. 10). Нужно иметь в виду, что как и инверсию приоритетов, взаимное блокирование сложно идентифицировать на этапе отладки программ.

 

Рис. 10. Схема взаимного блокирования задач: 1) переключение контекста, запуск Task_A; 2) код Task_A; 3) семафор_A = 0, ресурс заблокирован Task_A; 4) переключение контекста, запуск Task_B; 5) код Task_B; 6) семафор_B = 0, ресурс заблокирован Task_B; 7) семафор_A = 0, Task_B блокируется; 8) переключение контекста, продолжение выполнения Task_A; 9) семафор_B = 0, Task_A блокируется; 10) переключение контекста, продолжение выполнения фоновой задачи

Выводы

Надеемся, что представленная информация поможет разработчикам встроенного ПО в изучении принципов работы ОСРВ FreeRTOS. Любая ОСРВ предоставляет разработчику встроенного ПО определенный диапазон сервисов или функций. Разработчик может использовать все предоставляемые функции или только часть из них, но даже при использовании бесплатной ОСРВ мы заплатим временем, которое потратит CPU на выполнение системных функций.
Есть еще одна сложность — назначение соответствующих приоритетов существующим задачам системы. Универсального алгоритма назначения приоритетов, который подходил бы для всех случаев, не существует. Разработчик должен решить самую главную задачу: сконструировать программный код таким образом, что даже самой низкоприоритетной задаче будет предоставлена возможность выполнения в самом наихудшем случае. Этот случай возникает тогда, когда все события системы пришли почти одновременно, в связи с этим большое количество задач готово к выполнению.
Факт использования ОСРВ в разработке встроенного ПО не является гарантией успешной реализации конечного программного продукта. Использование ОСРВ позволяет разработчику создавать программный продукт на проверенном фундаменте четко определенных алгоритмов работы ОСРВ.

Литература

1. Щербаков К.С., Щербаков С.А. Технология разработки встроенного программного обеспечения для ПЛК//Журнал интеллектуальных технологий Itech, Т.1, №14, 2009.
2. Толковый словарь по вычислительным системам/Под ред. В. Иллингуорта и др.: Пер. с англ. А.К. Белицкого и др./Под ред. Е.К. Масловского. Т. 1. — М.: Машиностроение, 1990.
3. www.freertos.org.

 

 



Вы можете скачать эту статью в формате pdf здесь.
Оцените материал:

Автор: Константин Щербаков, Сергей Щербаков, «ЭлеСи»



Комментарии

0 / 0
0 / 0

Прокомментировать





 

Горячие темы

 
 




Rambler's Top100
Руководителям  |  Разработчикам  |  Производителям  |  Снабженцам
© 2007 - 2019 Издательский дом Электроника
Использование любых бесплатных материалов разрешено, при условии наличия ссылки на сайт «Время электроники».
Создание сайтаFractalla Design | Сделано на CMS DJEM ®
Контакты