- •Встроенные микропроцессорные системы
- •Оглавление
- •2. Программное обеспечение встроенных систем ……….
- •Введение
- •Модуль 1
- •Аппаратные средства встроенных систем
- •1.2. Элементы архитектуры процессоров встроенных систем
- •1.2.1. Множество команд
- •1.2.3.1. Адресное пространство
- •1.2.3.2. Порядок байт
- •1. 2.3.3. Когерентность памяти
- •1. 2.3.4. Защита памяти
- •1. 2. 4. Модель прерываний
- •1.2. 5.Модель управления памятью
- •1.2.5.1. Страничная организация памяти
- •1.2.5.2. Сегментация памяти
- •1.3. Типы процессоров
- •1.4. Формы параллелизма в процессорах
- •1.4.1. Конвейеризация
- •1.4.2. Параллелизм уровня команд
- •1.5.Технологии памяти
- •1.5.1. Оперативная память
- •1.5.1. 1. Статическое озу
- •1.5.2. Постоянное запоминающее устройство (rom)
- •1.6. Иерархия памяти
- •1.6.1. Распределение или карта памяти
- •1.6.2. Блокнотная и кэш память
- •1.6.2.1. Кэш-память прямого отображения
- •1.6.2.2. Ассоциативная по множеству кэш-память
- •1.6.2.3. Обновление кэш-памяти.
- •1.6.2.4. Протокол когерентности кэширования с обратной записью
- •1.7. Магистраль микропроцессорной системы
- •1.8. Базовые устройства ввода-вывода встроенных систем
- •1.8.1. Порты ввода-вывода общего назначения
- •1.7.2. Таймер-счетчик
- •1.8.3. Импульсно-кодовая модуляция.
- •1.8.4. Многоканальный аналого-цифровой преобразователь
- •1.9. Базовые последовательные интерфейсы ввода-вывода
- •1.9.2. Последовательный интерфейс spi
- •1.9.4.1. Введение в usb
- •1.9.4.2. Интерфейс Open Host Controller для usb
- •Вопросы для самоконтроля
- •Модуль 2
- •1.10. Язык проектирования аппаратуры vhdl
- •1.10.2. Введение в vhdl
- •1.10.2.1. Программирование на vhdl для моделирования и синтеза [19]
- •1.10.2.2. Entity и architecture
- •1.10.2.3. Операторы присваивание и process [19]
- •1.10.2.4. Цикл моделирования vhdl
- •1.10.2.5. Многозначная логика и стандарт ieee 1164
- •1.11. Проектирование устройств ввода-вывода и контроллеров
- •1.12. Интегрированная среда разработки аппаратных средств
- •Вопросы для самоконтроля
- •Модуль 3
- •2. Программное обеспечение встроенных систем
- •2.1 Модель вычислений
- •2.2 Автомат с конечным числом состояний
- •2.3. Асинхронный язык проектирования sdl
- •2.4. Синхронный язык проектирования Lustre
- •2.5. Многозадачность.
- •2.5.1. Язык программирования Си
- •2.5.2. Потоки
- •2.5.2.1. Реализация потоков
- •2.5.2.2. Взаимное исключение
- •2.5.2.3. Взаимная блокировка
- •2.5.2.4. Модели непротиворечивости памяти
- •2.5.2.5. Проблемы с потоками
- •2.5.3. Процессы и передача сообщений
- •2.6. Интегрированная среда разработки прикладного программного
- •2.6.2. Комплект программ Telelogic Tau sdl Suite
- •2.6.3. Средства разработки программного обеспечения
- •2.7.1. Моделирование, эмуляция и макетирование
- •2.7.2. Формальная верификация
- •2.7.3. Оценка производительности
- •2.7.3.1. Оценка wcet
- •2.7.3.2. Исчисление реального времени
- •1 2 3 E
- •2.7.4. Модели энергии и мощности
- •2.7.5. Тепловая модель
- •Вопросы для самоконтроля
- •Заключение
- •Задания
- •1. Конвейеризация
- •2. Иерархия памяти
- •3. Базовые устройства ввода-вывода встроенных систем
- •5. Многозадачность
- •6. Валидация и оценка проекта
- •Библиографический список
- •Встроенные микропроцессорные системы
2.5.2.3. Взаимная блокировка
Большое количество мутексов в программах увеличивает риск взаимной блокировки (deadlock). Взаимоблокировка имеет место, когда некоторые потоки становятся постоянно блокированными пытаясь получить замки. Например, если поток A сохраняет замок 1 и затем блокируется при попытке получить замок 2, которым владеет поток B, затем блокируется B при попытке получить замок 1. От таких «смертельных объятий» не спастись. Программа должна быть прервана.
Предположим что функции addListener и update на рис. 73 защищены мутексом, как и двух предыдущих примерах. Update содержит строку (*(element->listener))(newx), которая вызывает функцию, указанную в элементе списка. Разумно для этой функции получить замок мутекса. Предположим, например, что функции слушателя необходимо обновить дисплей. Дисплей типичный разделяемый ресурс и, следовательно, должен быть защищен собственным замком мутекса. Предположим, что поток A вызывает функцию update, которая достигает оператора (*(element->listener))(newx) и затем блокируется, т.к. функция слушателя пытается получить другой замок, которым владеет B. Предположим затем, что поток B вызывает addListener, что приводит к взаимной блокировке.
Взаимную блокировку трудно преодолеть. В классической статье [27] даются необходимые условия возникновения взаимной блокировки, некоторые из которых могут быть удалены для преодоления взаимной блокировки. Простая техника состоит в использовании только одного замка для всей многопоточной программы. Эта техника, однако, не приводит к высокомодульной программе. Более того она может затруднить удовлетворению ограничениям реального времени, т.к. некоторые разделяемые ресурсы (например дисплей) могут нуждаться в достаточно длительном удержании, что приведет к просрочке времени исполнения другими потоками.
В очень простом микроядре иногда можно использовать разрешение/запрещение прерываний, а так же простой глобальный мутекс. Предположим, что имеется простой процессор (не многоядерным) и прерывания являются механизмом только для приостановки потоков (т.е. потоки не приостанавливаются при вызовах сервисов ядра или блокировке ввода-вывода). С такими предположениями запрещение прерываний предотвращает потоки от приостановки. В большинстве ОС, однако, потоки могут быть приостановлены по многим причинам, следовательно, эта техника не будет работать.
Третья техника говорит о том, что когда существует много замков, каждый поток получает замки в одном и том же порядке. Однако по некоторым причинам это трудно гарантировать. Во-первых, большинство программ пишутся многими людьми, получение замков функцией не является частью описания функции. Таким образом, эта техника полагается на очень тщательную и непротиворечивую документацию и перекрестную кооперацию в группе разработчиков. В некоторый момент добавляется замок, затем все части программы, которые получают замок должны быть модифицированы.
Во-вторых, может оказаться трудным делом корректное программирование. Если программист захочет вызвать функцию, которая получает замок 1, который согласно принятому соглашению всегда является первым для получения, затем должен первыми освободить некоторые удерживаемые замки. Как только поток освободит эти замки, он может быть приостановлен и ресурс, который замки удерживали, может быть модифицирован. Однажды получив замок 1, он должен вновь приобрести эти замки, но затем будет необходимо предположить, что нет больше каких-либо сведений о состоянии ресурсов, и придется переделать значительное количество работы. Большинство техник налагают строгие ограничения на программиста или требуют определенных изощрений для применения, которые напоминают, что проблема связана с моделью параллельного программирования потоков.