SlideShare a Scribd company logo
FreeRTOS
Философия разработки
FreeRTOS разработана как:
- Простая
- Портируемая
-Маленькая
Система FreeRTOS находится в стадии активной
разработки, которая была начата Ричардом
Барри (Richard Barry) в 2002 году.
Некоторые возможности FreeRTOS
• Выбор политики планирования
• Всегда работает задача с наивысшим приоритетом
из доступных. Задачи с одинаковым приоритетом
делят процессорное время.
• Coroutines(сопрограммы) - маленькие задачи,
использующие очень мало RAM.
• БОльшая часть кода одинакова для всех средств
разработки.
• Много портов и примеров.
• Дополнительные возможности могут быть легко и
быстро добавлены.
• Многозадачность и параллельность
Обычный процессор может выполнять только одну задачу одновременно
- но за счёт быстрого переключения между задачами делается вид,
будто задачи выполняются одновременно.
• Планирование
Планировщик - это часть ядра, отвечающий за то, какая задача должна
выполняться в какой момент времени. Ядро может приостановить и
потом продолжить задачу несколько раз за время работы задачи.
Планирование
Каждая задача имеет приоритет, назначенный пользователем, который
равен от 0 (самый низкий приоритет) и до значения времени
компиляции configMAX_PRIORITIES-1 (самый высокий приоритет)
Планировщик гарантирует, что процессорное время отдаётся задаче с
максимальным приоритетом из доступных(ready) задач. Даже если задачи с низким
приоритетом тоже находятся в состоянии готовности(ready) длительное время.
Тактовая частота системы
Система FreeRTOS настраивается таким образом, чтобы периодически выдавать
прерывания. Пользователь может регулировать частоту прерываний, которая обычно
находится в диапазоне миллисекунд.
/* Поиск очереди с наивысшим приоритетом, в которой есть готовые к запуску задачи. */
while( listLIST_IS_EMPTY( &( pxReadyTasksLists [uxTopReadyPriority ] ) ) )
{
configASSERT( uxTopReadyPriority );
--uxTopReadyPriority; } /*
}
/* listGET_OWNER_OF_NEXT_ENTRY проходит по списку, поскольку задачи с
одинаковым приоритетом получают одинаковое право пользоваться
процессорным временем. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[
uxTopReadyPriority ] ) );
Задачи
Задачей является определяемая пользователем
функция на языке C с заданным приоритетом.
В tasks.c и task.h делается вся тяжелая работа по
созданию, планированию и обслуживанию задач.
 Простая
 Нет ограничений использования
 Поддерживает полное вытеснение
 Приоритет задаётся всей задаче
 Каждая задача требует отдельного стека - это приводит к
большому потреблению оперативной памяти
 Повторная входимость должна быть тщательно
продумана, если используется вытеснение
Сопрограммы
Сопрограммы концептуально схожи с задачами, но
имеют некоторые различия.
 Требуется меньше оперативной памяти за счёт общего стека
 Совместная работа упрощает проблему повторного входа.
 Хорошо переносимо между разными архитектурами
 Полностью приоритезована по отношению к другим
сопрограммам, но всегда может быть вытеснена задачей,
имеющей больший приоритет, чем задача, запускающая
сопрограммы
 Отсутствие индивидуального стека требует особого
рассмотрения
 Ограниченный API
 Кооперативная многозадачность только между сопрограммами.
Объявление задач
• Задача должна иметь следующую структуру:
void vATaskFunction( void *pvParameters )
{
for ( ; ; )
{ /* Код задачи пишется тут */ }
}
Функции-задачи никогда не прерываются, поэтому обычно
реализуются при помощи непрерывного цикла. Опять-же
можно посмотреть примеры.
Задачи создаются с помощью xTaskCreate() и удаляются с
помощью vTaskDelete()
Блок управления задачей TCB (tasks.c)
typedef struct tskTaskControlBlock
{
volatile portSTACK_TYPE *pxTopOfStack; /* Указывает на месторасположение последнего
элемента, размещенного в стеке задач. */
xListItem xGenericListItem; /* Элемент списка, используемый для помещения блока TCB в
очереди готовых и заблокированных задач. */
xListItem xEventListItem; /* Элемент списка, используемый для помещения блока TCB в
списки событий.*/
unsigned portBASE_TYPE uxPriority; /* Приоритет задачи; 0 является низшим приоритетом.*/
portSTACK_TYPE *pxStack; /* Указывает на начало стека. */
signed char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* Описательное имя, которое
присваивается стеку, когда он создается. Используется только для отладки. */
#if ( portSTACK_GROWTH > 0 )
portSTACK_TYPE *pxEndOfStack; /* Используется для проверки стека на переполнение
в тех архитектурах, где стек растет с младших адресов памяти. */
#endif
#if ( configUSE_MUTEXES == 1 )
unsigned portBASE_TYPE uxBasePriority; /* Приоритет, назначенный задаче
последним – используется механизм наследования приоритетов. */
#endif
} tskTCB;
Списки
Списки
Список в системе FreeRTOS является стандартным закольцованным
двусвязным списком с парой интересных дополнений.
struct xLIST_ITEM
{
portTickType xItemValue; /* Значение, помещаемое в список.
В большинстве случае используется для сортировки
списка в порядке уменьшения значений */
volatile struct xLIST_ITEM * pxNext; /* Указатель на следующий
элемент xListItem в списке. */
volatile struct xLIST_ITEM * pxPrevious; /* Указатель на
предыдущий элемент xListItem в списке. */
void * pvOwner; /* Указатель на объект (обычно блок TCB), в
котором находится элемент списка. Таким образом,
организуется двусвязный список между объектами,
хранящимися в списке, и элементами самого списка. */
void * pvContainer; /* Указатель на список (если таковой имеется), в
который этот элемент списка помещается. */
};
void * pvContainer это:
typedef struct xLIST
{
volatile unsigned portBASE_TYPE uxNumberOfItems;
volatile xListItem * pxIndex; /* Используется для
прохода по списку. Указывает на последний
элемент, возвращенный функцией
pvListGetOwnerOfNextEntry (). */
volatile xMiniListItem xListEnd; /* Элемент списка, в
котором находится максимально возможное
значение, означающее, что он всегда
находится в конце списка и, поэтому,
используется как маркер. */
} xList;
Размер списка в любое время хранится в переменной uxNumberOfItems,
предназначенной для быстрого выполнения операций с размерами списков.
Списки
• Поскольку списки сортируются в порядке убывания,
элемент xListEnd используется как маркер начала списка. А поскольку
список кольцевой, этот элемент xListEnd также является маркером
конца списка.
• В большинстве «традиционных» операций доступа к списку, которыми
мы пользуемся, вся работа выполняется в одном цикле for() или в
функции, вызываемой следующим образом:
for (listPtr = listStart; listPtr != NULL; listPtr = listPtr->next)
{
// Что-то здесь делается с указателями listPtr ...
}
Каждый объект struct xListItem является, на самом деле,
объектом xGenericListItem из соответствующего блока TCB.
Очереди
Система FreeRTOS позволяет задачам с помощью очередей
общаться и синхронизироваться друг с другом. Процедуры
сервиса прерываний (ISR) также используют очереди для
взаимодействий и синхронизации.
Базовая структура данных очереди выглядит следующим образом:
typedef struct QueueDefinition
{
signed char *pcHead; /* Указывает на начало области хранения очереди. */
signed char *pcTail; /* Указывает на байт в конце области хранения очереди.
Еще один байт требуется поскольку хранятся отдельные
элементы очереди; он используется как маркер. */
signed char *pcWriteTo; /* Указывает на следующее свободное место в в области
хранения очереди. */
signed char *pcReadFrom; /* Указывает на последнюю позицию, откуда
происходило чтение очереди. */
xList xTasksWaitingToSend; /* Список задач, которые блокированы, ожидая пока не
произойдет обращение к этой очереди; Запомнены в
порядке приоритета. */
xList xTasksWaitingToReceive; /* Список задач, которые блокированы, ожидая пока
не произойдет чтение из этой очереди; Запомнены в
порядке приоритета. */
volatile unsigned portBASE_TYPE uxMessagesWaiting; /* Количество элементов,
имеющихся в очереди в текущий момент. */
unsigned portBASE_TYPE uxLength; /* Длина очереди, определяемая как количество
элементов, находящихся в очереди, а не как количество
байтов памяти, занимаемой очередью. */
unsigned portBASE_TYPE uxItemSize; /* Размер каждого элемента, который хранится
в очереди. */
} xQUEUE;
Очереди
Когда создается очередь, пользователь указывает длину очереди и размер
каждого элемента, который будет отслеживаться с помощью очереди.
В системе FreeRTOS поддерживаются вставки и удаления в очереди с
блокировкой и без блокировки.
Блокирования указываются с тайм-аутом. Задача может ожидать снятия
блокировки бесконечно или в течение ограниченного периода
времени.
В системе FreeRTOS используется список xTasksWaitingToSend для
отслеживания задач, которые блокированы при выполнении операции
вставки элемента в очередь. Каждый раз, когда элемент удаляется из
очереди, проверяется список xTasksWaitingToSend. Если задача
находится в состоянии ожидания в этом списке, то задача
разблокируется.
Аналогично, с помощью списка xTasksWaitingToReceive отслеживаются
задачи, которые блокируются при выполнении операции удаления из
очереди. Каждый раз, когда новый элемент вставляется в очередь,
проверяется список xTasksWaitingToReceive. Если задача находится в
состоянии ожидания в этом списке, то задача разблокируется.
Семафоры
Механизм семафоров основан на механизме очередей. По
большому счету API-функции для работы с семафорами
представляют собой макросы — «обертки» других API-
функций для работы с очередями.
Семафор должен быть явно создан перед первым его
использованием.
Двоичный семафор
Двоичные семафоры предназначены для эффективной
синхронизации выполнения задачи с возникновением
прерывания. Они позволяют переводить задачу из со-
стояния блокировки в состояние готовности к выполнению
каждый раз, когда происходит прерывание.
Организация обработки прерываний с помощью двоичных
семафоров — отличное решение, если частота
возникновения одного и того же прерывания не превышает
некоторый порог.
Если это же самое прерывание возникнет до того, как задача-
обработчик завершит его обработку, то задача-обработчик
не перейдет в блокированное состояние по завершении
обработки предыдущего прерывания, а сразу же займется
обслуживанием следующего. Предыдущее прерывание
окажется потерянным.
Счетный семафор
Существует два основных применения счетных семафоров:
• 1. Подсчет событий. В этом случае обработчик прерывания будет
отдавать семафор, то есть увеличивать его значение на единицу,
когда происходит событие. Задача-обработчик будет захватывать
семафор (уменьшать его значение на единицу) каждый раз при
обработке события. Текущее значение семафора будет представлять
собой разность между количеством событий, которые произошли, и
количеством событий, которые обработаны.
• 2. Управление доступом к ресурсам. В этом случае значение
счетного семафора представляет собой количество доступных
ресурсов. Для получения доступа к ресурсу задача должна сначала
получить (захватить) семафор — это уменьшит значение семафора
на единицу. Когда значение семафора станет равным нулю, это
означает , что доступных ресурсов нет. Когда задача завершает
работу с данным ресурсом, она отдает семафор — увеличивает его
значение на единицу.
Мьютекс
2. Мьютекс используется для защиты общего ресурса. Задача
включает мьютекс, использует общий ресурс, а затем
отключает мьютекс. Никакая задача не может включить
мьютекс, пока он включен другой задачей.
2. Мьютекс во FreeRTOS представляет собой специальный
тип двоичного семафора, который используется для
реализации совместного доступа к ресурсу двух или
большего числа задач.
Реализация семафоров и мьютексов
В системе FreeRTOS реализован N-элементный семафор в
виде очереди, в которой может быть N элементов.
Семафор следит за тем, сколько записей в текущий
момент помещено в очередь, что осуществляется с
помощью поля uxMessagesWaiting, имеющегося в
очереди.
Семафор реализует «чистую синхронизацию» так, как это
названо в вызовах заголовочного файла semphr.h
системы FreeRTOS. Поэтому размер элемента в очереди
указан равным нулю байтов (uxItemSize == 0). Каждое
обращение к семафору увеличивает или уменьшает на
единицу значение поля uxMessagesWaiting;
копирование элементов очереди или данных выполнять
не требуется.
Реализация семафоров и мьютексов
Точно также, как и семафоры, мьютексы реализованы в виде
очередей, но в них с помощью
определений #defines перегружены несколько полей xQUEUE:
/* Перепределение полей структуры xQUEUE. */
#define uxQueueType pcHead
#define pxMutexHolder pcTail
Поскольку мьютекс не хранит никаких данных в очереди, ему не
нужна внутренняя память, и, поэтому, не нужны
поля pcHead и pcTail. Система FreeRTOS устанавливает
поле uxQueueType (в действительности поле pcHead) равным 0,
указывая, что эта очередь используется для мьютекса.
Список используемой литературы
1. http://wiki.fh-up.ru/?title=FreeRTOS
2. http://rus-linux.net/MyLDP/BOOKS/Architecture-Open-
Source-Applications/Vol-2/freertos-01.html
3. http://robot-develop.org/archives/2777

More Related Content

PDF
DOCX
9 free rtos
PPTX
Svitla .Net meetup in Kiev, Anzhiiak Oleksii
PPT
Usage concurrence in java
PDF
Архитектура. Доступноять программных систем.
PPTX
Working with .NET Threads
PDF
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
PDF
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
9 free rtos
Svitla .Net meetup in Kiev, Anzhiiak Oleksii
Usage concurrence in java
Архитектура. Доступноять программных систем.
Working with .NET Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...

What's hot (20)

PDF
Java осень 2013 лекция 6
PDF
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
PDF
Лекция 1. Основные понятия стандарта MPI. Дифференцированные обмены
PDF
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
PDF
"Мультимастер для PostgreSQL" Кельвич Станислав, Книжник Константин, PostgresPro
PDF
Multimaster2
PPT
Root Conf2009 Fin
PDF
Пространства имен Linux (linux namespaces)
PDF
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
PDF
PDF
Модель памяти C++ - Андрей Янковский, Яндекс
PPTX
Reactive extensions
PDF
МАИ, Сети ЭВМ, Лекция №5
PDF
Вечный вопрос измерения времени
PPT
Лекция 6
PDF
Для чего мы делали свой акторный фреймворк и что из этого вышло?
PDF
МАИ, Сети ЭВМ, Лекция №4
PDF
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
PDF
C++ STL & Qt. Занятие 09.
PPTX
разработка серверов и серверных приложений лекция №2
Java осень 2013 лекция 6
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Лекция 1. Основные понятия стандарта MPI. Дифференцированные обмены
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
"Мультимастер для PostgreSQL" Кельвич Станислав, Книжник Константин, PostgresPro
Multimaster2
Root Conf2009 Fin
Пространства имен Linux (linux namespaces)
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Модель памяти C++ - Андрей Янковский, Яндекс
Reactive extensions
МАИ, Сети ЭВМ, Лекция №5
Вечный вопрос измерения времени
Лекция 6
Для чего мы делали свой акторный фреймворк и что из этого вышло?
МАИ, Сети ЭВМ, Лекция №4
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
C++ STL & Qt. Занятие 09.
разработка серверов и серверных приложений лекция №2
Ad

Viewers also liked (20)

PPTX
Free rtos seminar
PPT
Free FreeRTOS Course-Task Management
PPTX
FreeRTOS
PDF
Use Analytics to Prevent Costly Product Returns
PPT
GLONASS conference on ChipExpo 2011
PDF
FreeRTOS API
PPTX
Stm32f303 rest and Clock contol
PDF
A low cost, real-time algorithm for embedded devices based on freertos kernel
PDF
Localization using filtered dgps
PPT
GLONASS forum
PDF
OSM to Garmin
PPTX
платформа Microsoft Windows Embedded
PDF
PPT
Существующие и перспективные системы навигации (Борис Салтовский)
PPTX
Ten things about GPS
PPT
Satellite Navigation. Present and Future
PPTX
Free rtos简介
PDF
Internet Of Things: возможности Intel Galileo gen 2 и Intel Edison
PPTX
How to Measure RTOS Performance
PDF
era_27Nov2012
Free rtos seminar
Free FreeRTOS Course-Task Management
FreeRTOS
Use Analytics to Prevent Costly Product Returns
GLONASS conference on ChipExpo 2011
FreeRTOS API
Stm32f303 rest and Clock contol
A low cost, real-time algorithm for embedded devices based on freertos kernel
Localization using filtered dgps
GLONASS forum
OSM to Garmin
платформа Microsoft Windows Embedded
Существующие и перспективные системы навигации (Борис Салтовский)
Ten things about GPS
Satellite Navigation. Present and Future
Free rtos简介
Internet Of Things: возможности Intel Galileo gen 2 и Intel Edison
How to Measure RTOS Performance
era_27Nov2012
Ad

Similar to FreeRTOS (20)

PDF
Архитектура ROS
PDF
Linux basics. Занятие 3.
PDF
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
PDF
лек9 10
PDF
C++ осень 2012 лекция 9
PPTX
Оптимизация трассирования с использованием Expression templates
PPTX
Оптимизация трассирования с использованием Expression templates
PPTX
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
PDF
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
PDF
C++ Базовый. Занятие 15.
PDF
Многопоточное программирование на C#, путевые заметки
PDF
C++ осень 2013 лекция 4
PDF
C++ STL & Qt. Занятие 11.
PPT
Типичный стек технологий для использования с Node.js
PDF
C++ осень 2013 лекция 6
PDF
PPTX
Текст.pptx
PDF
Лекция 13. Многопоточность и GIL
PPTX
Query perfomance tuning
PDF
20111002 information retrieval raskovalov_lecture3
Архитектура ROS
Linux basics. Занятие 3.
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
лек9 10
C++ осень 2012 лекция 9
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
C++ Базовый. Занятие 15.
Многопоточное программирование на C#, путевые заметки
C++ осень 2013 лекция 4
C++ STL & Qt. Занятие 11.
Типичный стек технологий для использования с Node.js
C++ осень 2013 лекция 6
Текст.pptx
Лекция 13. Многопоточность и GIL
Query perfomance tuning
20111002 information retrieval raskovalov_lecture3

FreeRTOS

  • 2. Философия разработки FreeRTOS разработана как: - Простая - Портируемая -Маленькая Система FreeRTOS находится в стадии активной разработки, которая была начата Ричардом Барри (Richard Barry) в 2002 году.
  • 3. Некоторые возможности FreeRTOS • Выбор политики планирования • Всегда работает задача с наивысшим приоритетом из доступных. Задачи с одинаковым приоритетом делят процессорное время. • Coroutines(сопрограммы) - маленькие задачи, использующие очень мало RAM. • БОльшая часть кода одинакова для всех средств разработки. • Много портов и примеров. • Дополнительные возможности могут быть легко и быстро добавлены.
  • 4. • Многозадачность и параллельность Обычный процессор может выполнять только одну задачу одновременно - но за счёт быстрого переключения между задачами делается вид, будто задачи выполняются одновременно. • Планирование Планировщик - это часть ядра, отвечающий за то, какая задача должна выполняться в какой момент времени. Ядро может приостановить и потом продолжить задачу несколько раз за время работы задачи.
  • 5. Планирование Каждая задача имеет приоритет, назначенный пользователем, который равен от 0 (самый низкий приоритет) и до значения времени компиляции configMAX_PRIORITIES-1 (самый высокий приоритет) Планировщик гарантирует, что процессорное время отдаётся задаче с максимальным приоритетом из доступных(ready) задач. Даже если задачи с низким приоритетом тоже находятся в состоянии готовности(ready) длительное время.
  • 6. Тактовая частота системы Система FreeRTOS настраивается таким образом, чтобы периодически выдавать прерывания. Пользователь может регулировать частоту прерываний, которая обычно находится в диапазоне миллисекунд. /* Поиск очереди с наивысшим приоритетом, в которой есть готовые к запуску задачи. */ while( listLIST_IS_EMPTY( &( pxReadyTasksLists [uxTopReadyPriority ] ) ) ) { configASSERT( uxTopReadyPriority ); --uxTopReadyPriority; } /* } /* listGET_OWNER_OF_NEXT_ENTRY проходит по списку, поскольку задачи с одинаковым приоритетом получают одинаковое право пользоваться процессорным временем. */ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );
  • 7. Задачи Задачей является определяемая пользователем функция на языке C с заданным приоритетом. В tasks.c и task.h делается вся тяжелая работа по созданию, планированию и обслуживанию задач.  Простая  Нет ограничений использования  Поддерживает полное вытеснение  Приоритет задаётся всей задаче  Каждая задача требует отдельного стека - это приводит к большому потреблению оперативной памяти  Повторная входимость должна быть тщательно продумана, если используется вытеснение
  • 8. Сопрограммы Сопрограммы концептуально схожи с задачами, но имеют некоторые различия.  Требуется меньше оперативной памяти за счёт общего стека  Совместная работа упрощает проблему повторного входа.  Хорошо переносимо между разными архитектурами  Полностью приоритезована по отношению к другим сопрограммам, но всегда может быть вытеснена задачей, имеющей больший приоритет, чем задача, запускающая сопрограммы  Отсутствие индивидуального стека требует особого рассмотрения  Ограниченный API  Кооперативная многозадачность только между сопрограммами.
  • 9. Объявление задач • Задача должна иметь следующую структуру: void vATaskFunction( void *pvParameters ) { for ( ; ; ) { /* Код задачи пишется тут */ } } Функции-задачи никогда не прерываются, поэтому обычно реализуются при помощи непрерывного цикла. Опять-же можно посмотреть примеры. Задачи создаются с помощью xTaskCreate() и удаляются с помощью vTaskDelete()
  • 10. Блок управления задачей TCB (tasks.c) typedef struct tskTaskControlBlock { volatile portSTACK_TYPE *pxTopOfStack; /* Указывает на месторасположение последнего элемента, размещенного в стеке задач. */ xListItem xGenericListItem; /* Элемент списка, используемый для помещения блока TCB в очереди готовых и заблокированных задач. */ xListItem xEventListItem; /* Элемент списка, используемый для помещения блока TCB в списки событий.*/ unsigned portBASE_TYPE uxPriority; /* Приоритет задачи; 0 является низшим приоритетом.*/ portSTACK_TYPE *pxStack; /* Указывает на начало стека. */ signed char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* Описательное имя, которое присваивается стеку, когда он создается. Используется только для отладки. */ #if ( portSTACK_GROWTH > 0 ) portSTACK_TYPE *pxEndOfStack; /* Используется для проверки стека на переполнение в тех архитектурах, где стек растет с младших адресов памяти. */ #endif #if ( configUSE_MUTEXES == 1 ) unsigned portBASE_TYPE uxBasePriority; /* Приоритет, назначенный задаче последним – используется механизм наследования приоритетов. */ #endif } tskTCB;
  • 12. Списки Список в системе FreeRTOS является стандартным закольцованным двусвязным списком с парой интересных дополнений. struct xLIST_ITEM { portTickType xItemValue; /* Значение, помещаемое в список. В большинстве случае используется для сортировки списка в порядке уменьшения значений */ volatile struct xLIST_ITEM * pxNext; /* Указатель на следующий элемент xListItem в списке. */ volatile struct xLIST_ITEM * pxPrevious; /* Указатель на предыдущий элемент xListItem в списке. */ void * pvOwner; /* Указатель на объект (обычно блок TCB), в котором находится элемент списка. Таким образом, организуется двусвязный список между объектами, хранящимися в списке, и элементами самого списка. */ void * pvContainer; /* Указатель на список (если таковой имеется), в который этот элемент списка помещается. */ };
  • 13. void * pvContainer это: typedef struct xLIST { volatile unsigned portBASE_TYPE uxNumberOfItems; volatile xListItem * pxIndex; /* Используется для прохода по списку. Указывает на последний элемент, возвращенный функцией pvListGetOwnerOfNextEntry (). */ volatile xMiniListItem xListEnd; /* Элемент списка, в котором находится максимально возможное значение, означающее, что он всегда находится в конце списка и, поэтому, используется как маркер. */ } xList; Размер списка в любое время хранится в переменной uxNumberOfItems, предназначенной для быстрого выполнения операций с размерами списков.
  • 14. Списки • Поскольку списки сортируются в порядке убывания, элемент xListEnd используется как маркер начала списка. А поскольку список кольцевой, этот элемент xListEnd также является маркером конца списка. • В большинстве «традиционных» операций доступа к списку, которыми мы пользуемся, вся работа выполняется в одном цикле for() или в функции, вызываемой следующим образом: for (listPtr = listStart; listPtr != NULL; listPtr = listPtr->next) { // Что-то здесь делается с указателями listPtr ... } Каждый объект struct xListItem является, на самом деле, объектом xGenericListItem из соответствующего блока TCB.
  • 15. Очереди Система FreeRTOS позволяет задачам с помощью очередей общаться и синхронизироваться друг с другом. Процедуры сервиса прерываний (ISR) также используют очереди для взаимодействий и синхронизации.
  • 16. Базовая структура данных очереди выглядит следующим образом: typedef struct QueueDefinition { signed char *pcHead; /* Указывает на начало области хранения очереди. */ signed char *pcTail; /* Указывает на байт в конце области хранения очереди. Еще один байт требуется поскольку хранятся отдельные элементы очереди; он используется как маркер. */ signed char *pcWriteTo; /* Указывает на следующее свободное место в в области хранения очереди. */ signed char *pcReadFrom; /* Указывает на последнюю позицию, откуда происходило чтение очереди. */ xList xTasksWaitingToSend; /* Список задач, которые блокированы, ожидая пока не произойдет обращение к этой очереди; Запомнены в порядке приоритета. */ xList xTasksWaitingToReceive; /* Список задач, которые блокированы, ожидая пока не произойдет чтение из этой очереди; Запомнены в порядке приоритета. */ volatile unsigned portBASE_TYPE uxMessagesWaiting; /* Количество элементов, имеющихся в очереди в текущий момент. */ unsigned portBASE_TYPE uxLength; /* Длина очереди, определяемая как количество элементов, находящихся в очереди, а не как количество байтов памяти, занимаемой очередью. */ unsigned portBASE_TYPE uxItemSize; /* Размер каждого элемента, который хранится в очереди. */ } xQUEUE;
  • 17. Очереди Когда создается очередь, пользователь указывает длину очереди и размер каждого элемента, который будет отслеживаться с помощью очереди. В системе FreeRTOS поддерживаются вставки и удаления в очереди с блокировкой и без блокировки. Блокирования указываются с тайм-аутом. Задача может ожидать снятия блокировки бесконечно или в течение ограниченного периода времени. В системе FreeRTOS используется список xTasksWaitingToSend для отслеживания задач, которые блокированы при выполнении операции вставки элемента в очередь. Каждый раз, когда элемент удаляется из очереди, проверяется список xTasksWaitingToSend. Если задача находится в состоянии ожидания в этом списке, то задача разблокируется. Аналогично, с помощью списка xTasksWaitingToReceive отслеживаются задачи, которые блокируются при выполнении операции удаления из очереди. Каждый раз, когда новый элемент вставляется в очередь, проверяется список xTasksWaitingToReceive. Если задача находится в состоянии ожидания в этом списке, то задача разблокируется.
  • 18. Семафоры Механизм семафоров основан на механизме очередей. По большому счету API-функции для работы с семафорами представляют собой макросы — «обертки» других API- функций для работы с очередями. Семафор должен быть явно создан перед первым его использованием.
  • 19. Двоичный семафор Двоичные семафоры предназначены для эффективной синхронизации выполнения задачи с возникновением прерывания. Они позволяют переводить задачу из со- стояния блокировки в состояние готовности к выполнению каждый раз, когда происходит прерывание. Организация обработки прерываний с помощью двоичных семафоров — отличное решение, если частота возникновения одного и того же прерывания не превышает некоторый порог. Если это же самое прерывание возникнет до того, как задача- обработчик завершит его обработку, то задача-обработчик не перейдет в блокированное состояние по завершении обработки предыдущего прерывания, а сразу же займется обслуживанием следующего. Предыдущее прерывание окажется потерянным.
  • 20. Счетный семафор Существует два основных применения счетных семафоров: • 1. Подсчет событий. В этом случае обработчик прерывания будет отдавать семафор, то есть увеличивать его значение на единицу, когда происходит событие. Задача-обработчик будет захватывать семафор (уменьшать его значение на единицу) каждый раз при обработке события. Текущее значение семафора будет представлять собой разность между количеством событий, которые произошли, и количеством событий, которые обработаны. • 2. Управление доступом к ресурсам. В этом случае значение счетного семафора представляет собой количество доступных ресурсов. Для получения доступа к ресурсу задача должна сначала получить (захватить) семафор — это уменьшит значение семафора на единицу. Когда значение семафора станет равным нулю, это означает , что доступных ресурсов нет. Когда задача завершает работу с данным ресурсом, она отдает семафор — увеличивает его значение на единицу.
  • 21. Мьютекс 2. Мьютекс используется для защиты общего ресурса. Задача включает мьютекс, использует общий ресурс, а затем отключает мьютекс. Никакая задача не может включить мьютекс, пока он включен другой задачей. 2. Мьютекс во FreeRTOS представляет собой специальный тип двоичного семафора, который используется для реализации совместного доступа к ресурсу двух или большего числа задач.
  • 22. Реализация семафоров и мьютексов В системе FreeRTOS реализован N-элементный семафор в виде очереди, в которой может быть N элементов. Семафор следит за тем, сколько записей в текущий момент помещено в очередь, что осуществляется с помощью поля uxMessagesWaiting, имеющегося в очереди. Семафор реализует «чистую синхронизацию» так, как это названо в вызовах заголовочного файла semphr.h системы FreeRTOS. Поэтому размер элемента в очереди указан равным нулю байтов (uxItemSize == 0). Каждое обращение к семафору увеличивает или уменьшает на единицу значение поля uxMessagesWaiting; копирование элементов очереди или данных выполнять не требуется.
  • 23. Реализация семафоров и мьютексов Точно также, как и семафоры, мьютексы реализованы в виде очередей, но в них с помощью определений #defines перегружены несколько полей xQUEUE: /* Перепределение полей структуры xQUEUE. */ #define uxQueueType pcHead #define pxMutexHolder pcTail Поскольку мьютекс не хранит никаких данных в очереди, ему не нужна внутренняя память, и, поэтому, не нужны поля pcHead и pcTail. Система FreeRTOS устанавливает поле uxQueueType (в действительности поле pcHead) равным 0, указывая, что эта очередь используется для мьютекса.
  • 24. Список используемой литературы 1. http://wiki.fh-up.ru/?title=FreeRTOS 2. http://rus-linux.net/MyLDP/BOOKS/Architecture-Open- Source-Applications/Vol-2/freertos-01.html 3. http://robot-develop.org/archives/2777