- •Оглавление
- •Предисловие
- •Почему я написал книгу?
- •Для кого эта книга?
- •Как использовать эту книгу?
- •Как организована книга?
- •Об авторе
- •Ошибки и предложения
- •Поддержка книги
- •Как помочь автору
- •Отказ от авторского права
- •Благодарность за участие
- •Перевод
- •Благодарности
- •I Введение
- •1. Введение в ассортимент микроконтроллеров STM32
- •1.1. Введение в процессоры на базе ARM
- •1.1.1. Cortex и процессоры на базе Cortex-M
- •1.1.1.10. Внедренные функции Cortex-M в ассортименте STM32
- •1.2. Введение в микроконтроллеры STM32
- •1.2.1. Преимущества ассортимента STM32….
- •1.2.2. ….И его недостатки
- •1.3. Краткий обзор подсемейств STM32
- •1.3.1. Серия F0
- •1.3.2. Серия F1
- •1.3.3. Серия F2
- •1.3.4. Серия F3
- •1.3.5. Серия F4
- •1.3.6. Серия F7
- •1.3.7. Серия H7
- •1.3.8. Серия L0
- •1.3.9. Серия L1
- •1.3.10. Серия L4
- •1.3.11. Серия L4+
- •1.3.12. Серия STM32WB
- •1.3.13. Как правильно выбрать для себя микроконтроллер?
- •1.4. Отладочная плата Nucleo
- •2. Установка инструментария
- •2.1. Почему выбирают Eclipse/GCC в качестве инструментария для STM32
- •2.1.1. Два слова о Eclipse…
- •2.2. Windows – Установка инструментария
- •2.2.1. Windows – Установка Eclipse
- •2.2.2. Windows – Установка плагинов Eclipse
- •2.2.3. Windows – Установка GCC ARM Embedded
- •2.2.4. Windows – Установка инструментов сборки
- •2.2.5. Windows – Установка OpenOCD
- •2.2.6. Windows – Установка инструментов ST и драйверов
- •2.3. Linux – Установка инструментария
- •2.3.2. Linux – Установка Java
- •2.3.3. Linux – Установка Eclipse
- •2.3.4. Linux – Установка плагинов Eclipse
- •2.3.5. Linux – Установка GCC ARM Embedded
- •2.3.6. Linux – Установка драйверов Nucleo
- •2.3.7. Linux – Установка OpenOCD
- •2.3.8. Linux – Установка инструментов ST
- •2.4. Mac – Установка инструментария
- •2.4.1. Mac – Установка Eclipse
- •2.4.2. Mac – Установка плагинов Eclipse
- •2.4.3. Mac – Установка GCC ARM Embedded
- •2.4.4. Mac – Установка драйверов Nucleo
- •2.4.5. Mac – Установка OpenOCD
- •2.4.6. Mac – Установка инструментов ST
- •3. Hello, Nucleo!
- •3.1. Прикоснитесь к Eclipse IDE
- •3.2. Создание проекта
- •3.3. Подключение Nucleo к ПК
- •3.5. Изучение сгенерированного кода
- •4. Инструмент STM32CubeMX
- •4.1. Введение в инструмент CubeMX
- •4.1.1. Представление Pinout
- •4.1.2. Представление Clock Configuration
- •4.1.3. Представление Configuration
- •4.1.4. Представление Power Consumption Calculator
- •4.2. Генерация проекта
- •4.2.1. Генерация проекта Си при помощи CubeMX
- •4.2.2. Создание проекта Eclipse
- •4.2.3. Ручное импортирование сгенерированных файлов в проект Eclipse
- •4.3. Изучение сгенерированного кода приложения
- •4.3.1. Добавим что-нибудь полезное в микропрограмму
- •4.4. Загрузка исходного кода примеров книги
- •5. Введение в отладку
- •5.1. Начало работы с OpenOCD
- •5.1.1. Запуск OpenOCD
- •5.1.2. Подключение к OpenOCD Telnet Console
- •5.1.3. Настройка Eclipse
- •5.1.4. Отладка в Eclipse
- •5.2. Полухостинг ARM
- •5.2.1. Включение полухостинга в новом проекте
- •5.2.2. Включение полуохостинга в существующем проекте
- •5.2.3. Недостатки полухостинга
- •5.2.4. Как работает полухостинг
- •II Погружение в HAL
- •6. Управление GPIO
- •6.2. Конфигурация GPIO
- •6.2.1. Режимы работы GPIO
- •6.2.2. Режим альтернативной функции GPIO
- •6.2.3. Понятие скорости GPIO
- •6.3. Управление GPIO
- •6.4. Деинициализация GPIO
- •7. Обработка прерываний
- •7.1. Контроллер NVIC
- •7.1.1. Таблица векторов в STM32
- •7.2. Разрешение прерываний
- •7.2.1. Линии запроса внешних прерываний и контроллер NVIC
- •7.2.2. Разрешение прерываний в CubeMX
- •7.3. Жизненный цикл прерываний
- •7.4. Уровни приоритета прерываний
- •7.4.1. Cortex-M0/0+
- •7.4.2. Cortex-M3/4/7
- •7.4.3. Установка уровня прерываний в CubeMX
- •7.5. Реентерабельность прерываний
- •8. Универсальные асинхронные последовательные средства связи
- •8.1. Введение в UART и USART
- •8.2. Инициализация UART
- •8.3. UART-связь в режиме опроса
- •8.3.1. Установка консоли последовательного порта в Windows
- •8.3.2. Установка консоли последовательного порта в Linux и MacOS X
- •8.4. UART-связь в режиме прерываний
- •8.5. Обработка ошибок
- •8.6. Перенаправление ввода-вывода
- •9. Управление DMA
- •9.1. Введение в DMA
- •9.1.1. Необходимость DMA и роль внутренних шин
- •9.1.2. Контроллер DMA
- •9.2. Модуль HAL_DMA
- •9.2.1. DMA_HandleTypeDef в HAL для F0/F1/F3/L0/L1/L4
- •9.2.2. DMA_HandleTypeDef в HAL для F2/F4/F7
- •9.2.3. DMA_HandleTypeDef в HAL для L0/L4
- •9.2.4. Как выполнять передачи в режиме опроса
- •9.2.5. Как выполнять передачи в режиме прерываний
- •9.2.8. Разнообразные функции модулей HAL_DMA и HAL_DMA_Ex
- •9.3. Использование CubeMX для конфигурации запросов к DMA
- •10. Схема тактирования
- •10.1. Распределение тактового сигнала
- •10.1.1. Обзор схемы тактирования STM32
- •10.1.1.1. Многочастотный внутренний RC-генератор в семействах STM32L
- •10.1.3.1. Подача тактового сигнала от высокочастотного генератора
- •10.1.3.2. Подача тактового сигнала от 32кГц генератора
- •10.2. Обзор модуля HAL_RCC
- •10.2.1. Вычисление тактовой частоты во время выполнения
- •10.2.2. Разрешение Выхода синхронизации
- •10.2.3. Разрешение Системы защиты тактирования
- •10.3. Калибровка HSI-генератора
- •11. Таймеры
- •11.1. Введение в таймеры
- •11.1.1. Категории таймеров в микроконтроллере STM32
- •11.1.2. Доступность таймеров в ассортименте STM32
- •11.2. Базовые таймеры
- •11.2.1. Использование таймеров в режиме прерываний
- •11.2.2. Использование таймеров в режиме опроса
- •11.2.3. Использование таймеров в режиме DMA
- •11.2.4. Остановка таймера
- •11.3. Таймеры общего назначения
- •11.3.1.1. Режим внешнего тактирования 2
- •11.3.1.2. Режим внешнего тактирования 1
- •11.3.2. Режимы синхронизации ведущего/ведомого таймеров
- •11.3.2.1. Разрешение прерываний, относящихся к триггерной цепи
- •11.3.2.2. Использование CubeMX для конфигурации синхронизации ведущего/ведомого устройств
- •11.3.3. Программная генерация связанных с таймером событий
- •11.3.4. Режимы отсчета
- •11.3.5. Режим захвата входного сигнала
- •11.3.5.1. Использование CubeMX для конфигурации режима захвата входного сигнала
- •11.3.6. Режим сравнения выходного сигнала
- •11.3.6.1. Использование CubeMX для конфигурации режима сравнения выходного сигнала
- •11.3.7. Генерация широтно-импульсного сигнала
- •11.3.7.1. Генерация синусоидального сигнала при помощи ШИМ
- •11.3.7.2. Использование CubeMX для конфигурации режима ШИМ
- •11.3.8. Одноимпульсный режим
- •11.3.8.1. Использование CubeMX для конфигурации одноимпульсного режима
- •11.3.9. Режим энкодера
- •11.3.9.1. Использование CubeMX для конфигурации режима энкодера
- •11.3.10.1. Режим датчика Холла
- •11.3.10.2. Комбинированный режим трехфазной ШИМ и другие функции управления двигателем
- •11.3.10.3. Вход сброса таймера и блокировка регистров таймера
- •11.3.10.4. Предварительная загрузка регистра автоперезагрузки
- •11.3.11. Отладка и таймеры
- •11.4. Системный таймер SysTick
- •12. Аналого-цифровое преобразование
- •12.1. Введение в АЦП последовательного приближения
- •12.2. Модуль HAL_ADC
- •12.2.1. Режимы преобразования
- •12.2.1.1. Режим однократного преобразования одного канала
- •12.2.1.2. Режим сканирования с однократным преобразованием
- •12.2.1.3. Режим непрерывного преобразования одного канала
- •12.2.1.4. Режим сканирования с непрерывным преобразованием
- •12.2.1.5. Режим преобразования инжектированных каналов
- •12.2.1.6. Парный режим
- •12.2.2. Выбор канала
- •12.2.3. Разрядность АЦП и скорость преобразования
- •12.2.4. Аналого-цифровые преобразования в режиме опроса
- •12.2.6. Аналого-цифровые преобразования в режиме DMA
- •12.2.6.1. Многократное преобразование одного канала в режиме DMA
- •12.2.6.3. Непрерывные преобразования в режиме DMA
- •12.2.7. Обработка ошибок
- •12.2.8. Преобразования, управляемые таймером
- •12.2.9. Преобразования, управляемые внешними событиями
- •12.2.10. Калибровка АЦП
- •12.3. Использование CubeMX для конфигурации АЦП
- •13.1. Введение в периферийное устройство ЦАП
- •13.2. Модуль HAL_DAC
- •13.2.1. Управление ЦАП вручную
- •13.2.2. Управление ЦАП в режиме DMA с использованием таймера
- •13.2.3. Генерация треугольного сигнала
- •13.2.4. Генерация шумового сигнала
- •14.1. Введение в спецификацию I²C
- •14.1.1. Протокол I²C
- •14.1.1.1. START- и STOP-условия
- •14.1.1.2. Формат байта
- •14.1.1.3. Кадр адреса
- •14.1.1.4. Биты «Подтверждено» (ACK) и «Не подтверждено» (NACK)
- •14.1.1.5. Кадры данных
- •14.1.1.6. Комбинированные транзакции
- •14.1.1.7. Удержание синхросигнала
- •14.1.2. Наличие периферийных устройств I²C в микроконтроллерах STM32
- •14.2. Модуль HAL_I2C
- •14.2.1.1. Операции I/O MEM
- •14.2.1.2. Комбинированные транзакции
- •14.3. Использование CubeMX для конфигурации периферийного устройства I²C
- •15.1. Введение в спецификацию SPI
- •15.1.1. Полярность и фаза тактового сигнала
- •15.1.2. Управление сигналом Slave Select
- •15.1.3. Режим TI периферийного устройства SPI
- •15.1.4. Наличие периферийных устройств SPI в микроконтроллерах STM32
- •15.2. Модуль HAL_SPI
- •15.2.1. Обмен сообщениями с использованием периферийного устройства SPI
- •15.2.2. Максимальная частота передачи, достижимая при использовании CubeHAL
- •15.3. Использование CubeMX для конфигурации периферийного устройства SPI
- •16. Циклический контроль избыточности
- •16.1. Введение в расчет CRC
- •16.1.1. Расчет CRC в микроконтроллерах STM32F1/F2/F4/L1
- •16.2. Модуль HAL_CRC
- •17. Независимый и оконный сторожевые таймеры
- •17.1. Независимый сторожевой таймер
- •17.1.1. Использование CubeHAL для программирования таймера IWDG
- •17.2. Системный оконный сторожевой таймер
- •17.2.1. Использование CubeHAL для программирования таймера WWDG
- •17.3. Отслеживание системного сброса, вызванного сторожевым таймером
- •17.4. Заморозка сторожевых таймеров во время сеанса отладки
- •17.5. Выбор сторожевого таймера, подходящего для вашего приложения
- •18. Часы реального времени
- •18.1. Введение в периферийное устройство RTC
- •18.2. Модуль HAL_RTC
- •18.2.1. Установка и получение текущей даты/времени
- •18.2.1.1. Правильный способ чтения значений даты/времени
- •18.2.2. Конфигурирование будильников
- •18.2.3. Блок периодического пробуждения
- •18.2.5. Калибровка RTC
- •18.2.5.1. Грубая калибровка RTC
- •18.2.5.2. Тонкая калибровка RTC
- •18.2.5.3. Обнаружение опорного тактового сигнала
- •18.3. Использование резервной SRAM
- •III Дополнительные темы
- •19. Управление питанием
- •19.1. Управление питанием в микроконтроллерах на базе Cortex-M
- •19.2. Как микроконтроллеры Cortex-M управляют рабочим и спящим режимами
- •19.2.1. Переход в/выход из спящих режимов
- •19.2.1.1. «Спящий режим по выходу»
- •19.3. Управление питанием в микроконтроллерах STM32F
- •19.3.1. Источники питания
- •19.3.2. Режимы питания
- •19.3.2.1. Рабочий режим
- •19.3.2.2. Спящий режим
- •19.3.2.3. Режим останова
- •19.3.2.4. Режим ожидания
- •19.3.2.5. Пример работы в режимах пониженного энергопотребления
- •19.4. Управление питанием в микроконтроллерах STM32L
- •19.4.1. Источники питания
- •19.4.2. Режимы питания
- •19.4.2.1. Рабочие режимы
- •19.4.2.2. Спящие режимы
- •19.4.2.2.1. Режим пакетного сбора данных
- •19.4.2.3. Режимы останова
- •19.4.2.4. Режимы ожидания
- •19.4.2.5. Режим выключенного состояния
- •19.4.3. Переходы между режимами питания
- •19.4.4. Периферийные устройства с пониженным энергопотреблением
- •19.4.4.1. LPUART
- •19.4.4.2. LPTIM
- •19.5. Инспекторы источников питания
- •19.6. Отладка в режимах пониженного энергопотребления
- •19.7. Использование калькулятора энергопотребления CubeMX
- •20. Организация памяти
- •20.1. Модель организации памяти в STM32
- •20.1.1. Основы процессов компиляции и компоновки
- •20.2.1. Исследование бинарного ELF-файла
- •20.2.2. Инициализация секций .data и .bss
- •20.2.2.1. Пара слов о секции COMMON
- •20.2.3. Секция .rodata
- •20.2.4. Области Стека и Кучи
- •20.2.5. Проверка размера Кучи и Стека на этапе компиляции
- •20.2.6. Различия с файлами скриптов инструментария
- •20.3. Как использовать CCM-память
- •20.3.1. Перемещение таблицы векторов в CCM-память
- •20.4.1. Программирование MPU с использованием CubeHAL
- •21. Управление Flash-памятью
- •21.1. Введение во Flash-память STM32
- •21.2. Модуль HAL_FLASH
- •21.2.1. Разблокировка Flash-памяти
- •21.2.2. Стирание Flash-памяти
- •21.2.3. Программирование Flash-памяти
- •21.3. Байты конфигурации
- •21.3.1. Защита от чтения Flash-памяти
- •21.4. Дополнительные памяти OTP и EEPROM
- •21.5. Задержка чтения Flash-памяти и ускоритель ART™ Accelerator
- •21.5.1. Роль TCM-памятей в микроконтроллерах STM32F7
- •22. Процесс начальной загрузки
- •22.1.1. Программное физическое перераспределение памяти
- •22.1.2. Перемещение таблицы векторов
- •22.1.3. Запуск микропрограммы из SRAM с помощью инструментария GNU MCU Eclipse
- •22.2. Встроенный загрузчик
- •22.2.1. Запуск загрузчика из встроенного программного обеспечения
- •22.2.2. Последовательность начальной загрузки в инструментарии GNU MCU Eclipse
- •22.3. Разработка пользовательского загрузчика
- •22.3.2. Как использовать инструмент flasher.py
- •23. Запуск FreeRTOS
- •23.1. Введение в концепции, лежащие в основе ОСРВ
- •23.2.1. Структура файлов с исходным кодом FreeRTOS
- •23.2.1.2. Как импортировать FreeRTOS с использованием CubeMX и CubeMXImporter
- •23.3. Управление потоками
- •23.3.1. Состояния потоков
- •23.3.2. Приоритеты потоков и алгоритмы планирования
- •23.3.3. Добровольное освобождение от управления
- •23.3.4. Холостой поток idle
- •23.4. Выделение памяти и управление ею
- •23.4.1. Модель динамического выделения памяти
- •23.4.1.1. heap_1.c
- •23.4.1.2. heap_2.c
- •23.4.1.3. heap_3.c
- •23.4.1.4. heap_4.c
- •23.4.1.5. heap_5.c
- •23.4.2. Модель статического выделения памяти
- •23.4.3. Пулы памяти
- •23.4.4. Обнаружение переполнения стека
- •23.5. Примитивы синхронизации
- •23.5.1. Очереди сообщений
- •23.5.2. Cемафоры
- •23.5.3. Сигналы потоков
- •23.6. Управление ресурсами и взаимное исключение
- •23.6.1. Мьютексы
- •23.6.2. Критические секции
- •23.6.3. Обработка прерываний совместно с ОСРВ
- •23.7. Программные таймеры
- •23.7.1. Как FreeRTOS управляет таймерами
- •23.8. Пример из практики: Управление энергосбережением с ОСРВ
- •23.8.1. Перехват холостого потока idle
- •23.8.2. Бестиковый режим во FreeRTOS
- •23.9. Возможности отладки
- •23.9.1. Макрос configASSERT()
- •23.9.2. Статистика среды выполнения и информация о состоянии потоков
- •23.10. Альтернативы FreeRTOS
- •23.10.1. ChibiOS
- •23.10.2. ОС Contiki
- •23.10.3. OpenRTOS
- •24. Продвинутые методы отладки
- •24.1. Введение в исключения отказов Cortex-M
- •24.1.1.1. Как инструментарий GNU MCU Eclipse обрабатывает исключения отказов
- •24.1.1.2. Как интерпретировать содержимое регистра LR при переходе в исключение
- •24.1.2. Исключения отказов и их анализ
- •24.2.1. Представление Expressions
- •24.2.1.1. Мониторы памяти
- •24.2.2. Точки наблюдения
- •24.2.3. Режим Instruction Stepping Mode
- •24.2.4. Keil Packs и представление Peripheral Registers
- •24.2.5. Представление Core Registers
- •24.3. Средства отладки от CubeHAL
- •24.4. Внешние отладчики
- •24.4.1. Использование SEGGER J-Link для отладчика ST-LINK
- •24.4.2. Использование интерфейса ITM и трассировка SWV
- •24.5. STM Studio
- •24.6. Одновременная отладка двух плат Nucleo
- •25. Файловая система FAT
- •25.1. Введение в библиотеку FatFs
- •25.1.1. Использование CubeMX для включения в ваши проекты библиотеки FatFs
- •25.1.2. Наиболее важные структуры и функции FatFs
- •25.1.2.1. Монтирование файловой системы
- •25.1.2.2. Открытие файлов
- •25.1.2.3. Чтение и запись файла
- •25.1.2.4. Создание и открытие каталога
- •25.1.3. Как сконфигурировать библиотеку FatFs
- •26. Разработка IoT-приложений
- •26.2. Ethernet контроллер W5500
- •26.2.1. Как использовать шилд W5500 и модуль ioLibrary_Driver
- •26.2.1.1. Конфигурирование интерфейса SPI
- •26.2.1.2. Настройка буферов сокетов и сетевого интерфейса
- •26.2.2. API-интерфейсы сокетов
- •26.2.2.1. Управление сокетами в режиме TCP
- •26.2.2.2. Управление сокетами в режиме UDP
- •26.2.3. Перенаправление ввода-вывода на сокет TCP/IP
- •26.2.4. Настройка HTTP-сервера
- •26.2.4.1. Веб-осциллограф
- •27. Начало работы над новым проектом
- •27.1. Проектирование оборудования
- •27.1.1. Послойная разводка печатной платы
- •27.1.2. Корпус микроконтроллера
- •27.1.3. Развязка выводов питания
- •27.1.4. Тактирование
- •27.1.5. Фильтрация вывода сброса RESET
- •27.1.6. Отладочный порт
- •27.1.7. Режим начальной загрузки
- •27.1.8. Обратите внимание на совместимость с выводами…
- •27.1.9. …и на выбор подходящей периферии
- •27.1.10. Роль CubeMX на этапе проектирования платы
- •27.1.11. Стратегии разводки платы
- •27.2. Разработка программного обеспечения
- •27.2.1. Генерация бинарного образа для производства
- •Приложение
- •Принудительный сброс микроконтроллера из микропрограммы
- •B. Руководство по поиску и устранению неисправностей
- •Проблемы с установкой GNU MCU Eclipse
- •Проблемы, связанные с Eclipse
- •Eclipse не может найти компилятор
- •Eclipse постоянно прерывается при выполнении каждой инструкции во время сеанса отладки
- •Пошаговая отладка очень медленная
- •Микропрограмма работает только в режиме отладки
- •Проблемы, связанные с STM32
- •Микроконтроллер не загружается корректно
- •Невозможно загрузить микропрограмму или отладить микроконтроллер
- •C. Схема выводов Nucleo
- •Nucleo-F446RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F411RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F410RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F401RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F334R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F303RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F302R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F103RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F091RC
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F072RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F070RB
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-F030R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L476RG
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L152RE
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L073R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •Nucleo-L053R8
- •Разъемы, совместимые с Arduino
- •Morpho-разъемы
- •D. Корпусы STM32
- •LFBGA
- •LQFP
- •TFBGA
- •TSSOP
- •UFQFPN
- •UFBGA
- •VFQFP
- •WLCSP
- •E. Изменения книги
- •Выпуск 0.1 – Октябрь 2015
- •Выпуск 0.2 – 28 октября 2015
- •Выпуск 0.2.1 – 31 октября 2015
- •Выпуск 0.2.2 – 1 ноября 2015
- •Выпуск 0.3 – 12 ноября 2015
- •Выпуск 0.4 – 4 декабря 2015
- •Выпуск 0.5 – 19 декабря 2015
- •Выпуск 0.6 – 18 января 2016
- •Выпуск 0.6.1 – 20 января 2016
- •Выпуск 0.6.2 – 30 января 2016
- •Выпуск 0.7 – 8 февраля 2016
- •Выпуск 0.8 – 18 февраля 2016
- •Выпуск 0.8.1 – 23 февраля 2016
- •Выпуск 0.9 – 27 марта 2016
- •Выпуск 0.9.1 – 28 марта 2016
- •Выпуск 0.10 – 26 апреля 2016
- •Выпуск 0.11 – 27 мая 2016
- •Выпуск 0.11.1 – 3 июня 2016
- •Выпуск 0.11.2 – 24 июня 2016
- •Выпуск 0.12 – 4 июля 2016
- •Выпуск 0.13 – 18 июля 2016
- •Выпуск 0.14 – 12 августа 2016
- •Выпуск 0.15 – 13 сентября 2016
- •Выпуск 0.16 – 3 октября 2016
- •Выпуск 0.17 – 24 октября 2016
- •Выпуск 0.18 – 15 ноября 2016
- •Выпуск 0.19 – 29 ноября 2016
- •Выпуск 0.20 – 28 декабря 2016
- •Выпуск 0.21 – 29 января 2017
- •Выпуск 0.22 – 2 мая 2017
- •Выпуск 0.23 – 20 июля 2017
- •Выпуск 0.24 – 11 декабря 2017
- •Выпуск 0.25 – 3 января 2018
- •Выпуск 0.26 – 7 мая 2018
Управление Flash-памятью |
565 |
стратегия замены редко используемых данных (Least Recently Used, LRU). Данная функция особенно полезна в случае кода, содержащего циклы.
Эту функцию можно включить, установив для макроса INSTRUCTION_CACHE_ENABLE значение 1 в файле stm32xxxx_hal_conf.h для тех микроконтрооллеров, которые предоставляют ускоритель ART™ Accelerator.
Кэш-память данных
Ассемблерные инструкции часто перемещают данные между ячейками памяти и регистрами ЦПУ. Иногда эти данные хранятся во Flash-памяти (они являются постоянными значениями): в этом случае мы говорим о литеральных пулах (literal pools). Литеральные пулы извлекаются из Flash-памяти через шину D-Bus на этапе выполнения конвейера ЦПУ. Следовательно, конвейер ЦПУ останавливается до тех пор, пока не будет предоставлен повторно запрашиваемый литеральный пул. Чтобы ограничить время, потерянное из-за литеральных пулов, доступы через шину данных D-Bus шины AHB имеют приоритет над доступом через шину инструкций I-Bus шины AHB (это и в самом деле алгоритм арбитража шин в отношении шины D-Bus).
Кроме того, выделенная кэш-память данных существует между шиной D-Bus и Flashпамятью. Данный кэш меньше кэша инструкций, но он помогает увеличить общую производительность ЦПУ. Эту функцию можно включить, установив для макроса
DATA_CACHE_ENABLE значение 1 в файле stm32xxxx_hal_conf.h для тех микроконтроллеров,
которые предоставляют ускоритель ART™ Accelerator.
21.5.1. Роль TCM-памятей в микроконтроллерах STM32F7
Организация памяти более новых и мощных микроконтроллеров STM32F7 заслуживает отдельного упоминания. Фактически, это семейство микроконтроллеров сталкивается с более сложной и гибкой организацией памяти и шины, предлагая два различных интерфейса для доступа к Flash-памяти и памяти SRAM: продвинутый расширяемый интерфейс (Advanced eXtensible Interface, AXI), являющийся спецификацией шины ARM, который соединяет ядро ЦПУ с другими периферийными устройствами; интерфейс тесносвязанной памяти (Tightly-Coupled Memory, TCM), который соединяет ядро ЦПУ с энергозависимой и энергонезависимой памятью, непосредственно связанными с ним. Оба интерфейса, AXI и TCM, следуют Гарвардской архитектуре, предоставляя отдельные линии для инструкций (I-Bus) и данных (D-Bus).
На рисунке 310 видно, что ядро Cortex-M7 имеет три разных пути доступа к контроллеру Flash-памяти (и, следовательно, к Flash-памяти). Прежде чем мы опишем эти три пути, важно отметить фундаментальную вещь: ядро Cortex-M7 уже имеет встроенный кэш L1. Этот кэш имеет два выделенных пула кэша, каждый размером 64 КБ, один для I-Bus и один для D-Bus: это отличается от других семейств STM32, где кэш данных и инструкций реализован исключительно внутри ускорителя ART™ Accelerator.
10 Рисунок взят из руководства по применению AN4667 от ST (http://www.st.com/content/ccc/resource/technical/document/application_note/0e/53/06/68/ef/2f/4a/cd/DM00169764.pdf/files/DM00169764.pdf/jcr:content/translations/en.DM00169764.pdf).
Управление Flash-памятью |
566 |
Рисунок 3: Как осуществляется доступ к Flash-памяти в микроконтроллере STM32F7
Во всех микроконтроллерах STM32F7 Flash-память доступна через три основных интерфейса для чтения и/или записи:
•64-разрядный интерфейс ITCM: соединяет встроенную Flash-память с ядром Cortex-M7 через шину ITCM (путь Path 1 на рисунке 3) и используется для выполнения программы и доступа к чтению значений литеральных данных. Доступ к записи во Flash-память через эту шину не разрешен. Flash-память доступна ЦПУ через ITCM, начиная с адреса 0x0020 0000. Встроенная Flash-память медленнее ядра ЦПУ, при этом ускоритель ART™ Accelerator позволяет выполнять доступ
кFlash-памяти с состоянием 0-ожиданий на частоте ЦПУ до 216 МГц. Ускоритель ART™ Accelerator микроконтроллера STM32F7 предназначен только для доступа
кFlash-памяти через интерфейс ITCM. Он реализует единый кэш инструкций и ветвей из 256 бит х 64 строки в STM32F74xxx и STM32F75xxx и 128/256 бит х 64 строки в устройствах STM32F76xxx и STM32F77xxx в соответствии с выбранным режимом банка11. Доступ через ускоритель ART™ Accelerator возможен как к инструкциям, так и к данным, что увеличивает скорость выполнения последовательного кода и циклов. Ускоритель ART™ Accelerator также предоставляет буфер предварительной выборки инструкций.
•64-разрядный интерфейс AHB: соединяет встроенную Flash-память с ядром Cor- tex-M7 через мост AXI/AHB (путь Path 2 на рисунке 3). Он используется для выполнения кода, чтения и записи. Flash-память доступна ЦПУ через мост AXI/AHB, начиная с адреса 0x0800 0000, и она кэшируемая (то есть может использовать кэш L1), достигая того же состояния 0-ожиданий ускорителем ART™ Accelerator. Кэш L1 в ядрах Cortex-M7 может варьироваться от 4 КБ до 16 КБ. Микроконтроллеры STM32F74xxx и STM32F75xxx предоставляют два пула кэша: один для инструкций (I-Bus) и один для литеральных пулов (D-Bus), каждый размером 4 КБ. Вместо этого микроконтроллеры STM32F76xxx и STM32F77xxx предоставляют два пула кэша, каждый по 16 КБ. Кэши L1 на всех ядрах Cortex-M7 разделены на строки по 32 Байт. Каждая строка помечена адресом. Кэш данных является ассоциативным
11 Микроконтроллеры STM32F76xxx и STM32F77xxx обеспечивают двухканальную архитектуру с широкими возможностями настройки: микроконтроллер можно сконфигурировать для работы в двухбанковом режиме (два банка, каждый размером 512/1024 КБ) или в режиме одного банка (один банк размером 1024/2048 КБ). В первом случае кэш-память в ускорителе ART™ Accelerator разделена на две части, каждая из которых состоит из 128 бит х 64 строки. Если используется режим одного банка, пул кэша является единым и состоит из 256 бит х 64 строки.
Управление Flash-памятью |
567 |
с 4 путями (по четыре строки в наборе), а кэш инструкций является ассоциативным с 2 путями. Это аппаратный компромисс, чтобы избежать необходимости помечать каждую строку адресом.
•32-разрядный интерфейс AHB: используется для передачи через DMA из Flashпамяти (путь Path 3 на рисунке 3). Доступ к Flash-памяти через DMA осуществляется с адреса 0x0800 0000.
•Существует четвертый путь Path 4 (см. рисунок 3) через интерфейс продвинутой периферийной шины (Advanced Bus Peripheral, AHBP), и он зарезервирован для доступа к регистрам периферийного устройства Flash-память внутри области отображения периферийных устройств 0x4000 0000.
Вчем преимущество этой явно сложной архитектуры? Если оба интерфейса Flashпамяти, то есть AXI/AHB и ITCM, обеспечивают выполнение с 0-ожиданий (один благодаря внутренней кэш-памяти L1 и один благодаря ускорителю ART™ Accelerator), почему мы должны вникать в эти сложности во время разработки микропрограммы?
Рисунок 4: Шинная матрица в микроконтроллере STM32F7
Ответ можно получить при рассмотрении архитектуры шинной матрицы микроконтроллера STM32F7, которая показана на рисунке 412. Как видите, шина AXI/AHB подключена к внутреннему кэшу L1 через интерфейс AXIM. Это означает, что доступ к некоторым периферийным устройствам на шине кэшируемый. И это касается контроллеров FMC и QuadSPI. Благодаря этой архитектуре можно использовать внешнюю память NVM для хранения данных или программного кода, используя кэш-память L1 объемом 64 КБ и имея параллельный доступ (без арбитража шины) к внутренней Flash-памяти через интерфейс ITCM и ускоритель ART™ Accelerator. Это приводит к значительному повышению производительности для устройств, использующих много памяти для
12 Рисунок взят из руководства по применению AN4667 от ST (http://www.st.com/content/ccc/resource/technical/document/application_note/0e/53/06/68/ef/2f/4a/cd/DM00169764.pdf/files/DM00169764.pdf/jcr:content/translations/en.DM00169764.pdf).
Управление Flash-памятью |
568 |
хранения изображений, видео и мультимедийного контента в целом, а также большие таблицы с постоянными данными, такие как FFT IV.
Уровень CMSIS для микроконтроллеров на базе Cortex-M7 определяет специальный набор процедур для управления кэш-памятью L1 ядра Cortex-M7 (см. таблицу 6).
Таблица 6: Функции CMSIS для манипулирования кэшами L1 ядра Cortex-M7
Функция CMSIS-F7 |
Описание |
|
|
void SCB_EnableICache(void) |
Инвалидация и затем включение кэша инструкций |
void SCB_DisableICache(void) |
Отключение кэша инструкций и выполнение инва- |
|
лидации его содержимого |
void SCB_InvalidateICache(void) |
Выполнение инвалидации кэша инструкций |
void SCB_EnableDCache(void) |
Инвалидация и затем включение кэша данных |
void SCB_DisableDCache(void) |
Отключение кэша данных, а затем выполнение |
|
очистки и инвалидации его содержимого |
void SCB_InvalidateDCache(void) |
Выполнение инвалидации кэша данных |
void SCB_CleanDCache(void) |
Очистка кэша данных |
void SCB_CleanInvalidateDCache(void) |
Очистка и выполнение инвалидации кэша данных |
Рисунок 5: Четыре памяти SRAM, доступные в микроконтроллерах STM32F7
Взглянув на рисунок 513, следует отметить еще один важный момент. Как видите, микроконтроллер STM32F7 предлагает четыре отдельных памяти SRAM, доступных через три отдельных пути:
•ОЗУ инструкций (ITCM-RAM), отображаемое по адресу 0x0000 0000 и доступная только для ядра, то есть через путь Path 1 на рисунке 5. Доступ к нему побайтный,
13 Рисунок взят из руководства по применению AN4667 от ST (http://www.st.com/content/ccc/resource/technical/document/application_note/0e/53/06/68/ef/2f/4a/cd/DM00169764.pdf/files/DM00169764.pdf/jcr:content/translations/en.DM00169764.pdf).
Управление Flash-памятью |
569 |
полусловный (16 бит), пословный (32 бита) или к двойному слову (64 бита). К ITCM-RAM можно обращаться с максимальной тактовой частотой ЦПУ без задержки. ITCM-RAM защищено от конфликтов шины, так как только ЦПУ может получить доступ к этой области ОЗУ. Память ITCM-RAM играет ту же роль, что и CCM-память в других микроконтроллерах STM32.
•ОЗУ данных (DTCM-RAM), отображаемое на интерфейс TCM по адресу 0x2000 0000 и доступное для всех ведущих устройств на шине AHB шиной матрицы AHB: ЦПУ через шину DTCM (путь Path 5 на рисунке 5) и через DMA по специальному «мосту» AHBS в ядре Cortex-M7 (путь Path 6 на рисунке 5). Доступ к нему побайтный, полусловный (16 бит), пословный (32 бита) или к двойному слову (64 бита). Доступ к памяти DTCM-RAM без задержки при максимальной тактовой частоте ЦПУ. Одновременный доступ к DTCM-RAM ведущими устройствами (ядро и DMA) и их приоритет могут обрабатываться регистром управления ведомыми устройствами (slave control register) ядра Cortex-M7 (регистр
CM7_AHBSCR). По сравнению с другими ведущими устройствами (DMA) более высокий приоритет для доступа к DTCM-RAM может быть отдан ЦПУ. Подробнее об этом регистре см. справочное руководство “ARM Cortex-M7 processor Technical Reference Manual”.
•SRAM1, доступное всем ведущим устройствам на шине AHB шинной матрицы AHB, то есть для всех DMA общего назначения, а также для специализированных DMA. Доступ к SRAM1 побайтный, полусловный (16 бит) или пословный (32 бита). Обратитесь к рисунку 5 (путь Path 7) за возможными обращениями к SRAM1. Данная память может использоваться для загрузки/хранения данных, а также для выполнения кода (несмотря на то что она не обеспечивает какого-либо особого повышения производительности).
•SRAM2, доступное всем ведущим устройствам на шине AHB шинной матрицы AHB. Все DMA общего назначения, а также специализированные DMA могут получить доступ к данной области памяти. Доступ к SRAM2 побайтный, полусловный (16 бит) или пословный (32 бита). Обратитесь к рисунку 5 (путь Path 8) за возможными обращениями к SRAM2. Данная память может использоваться для загрузки/хранения данных, а также для выполнения кода (несмотря на то что она не обеспечивает какого-либо особого повышения производительности).
Рисунок 6: Контроллеры внешней памяти FMC и QuadSPI
В дополнение к внутренней Flash-памяти и памяти SRAM, пулы памяти STM32F7 могут быть расширены с помощью контроллера внешней памяти (Flexible Memory Controller,
Управление Flash-памятью |
570 |
FMC) и контроллера Quad-SPI. На рисунке 614 показаны пути, соединяющие ЦПУ с этими внешними памятями через шину AXI. Как показано на рисунке 6, внешняя память может использовать кэш L1 ядра Cortex-M7, достигая максимума производительности как при загрузке/хранении данных, так и во время выполнения кода. Кэш-память L1 ядра Cortex-M7 обеспечивает значительное улучшение производительности микроконтроллеров STM32F7 по сравнению с STM32F4 с такими же внешними контроллерами памяти.
В таблице 7 приведены типы памяти, как внутренней, так и внешней по отношению к микроконтроллеру, доступные в STM32F74xxx/STM32F75xxx. Таблица показывает объем этих памятей, их адрес отображения и интерфейс шины, используемый для доступа к ним. Например, вы можете увидеть, что диапазон адресов 0x0020 0000 – 0x002F FFFF позволяет получить доступ к внутренней Flash-памяти через интерфейс ITCM, который является кэшируемым благодаря ускорителю ART™ Accelerator. В таблице 8 приведены те же памяти для микроконтроллеров STM32F76xxx/STM32F77xxx (характеристики FMC и QSPI одинаковы, поэтому они не перечислены в таблице 8).
Для получения дополнительной информации по этим темам настоятельно рекомендуется взглянуть на руководство по применению AN4667 от ST15.
Таблица 7: Отображение памяти и размеры в микроконтроллерах STM32F74xxx/STM32F75xxx
14 Рисунок взят из руководства по применению AN4667 от ST (http://www.st.com/content/ccc/resource/technical/document/application_note/0e/53/06/68/ef/2f/4a/cd/DM00169764.pdf/files/DM00169764.pdf/jcr:content/translations/en.DM00169764.pdf).
15http://www.st.com/content/ccc/resource/technical/document/application_note/0e/53/06/68/ef/2f/4a/cd/DM00169764.pdf/files/DM00169764.pdf/jcr:content/translations/en.DM00169764.pdf
Управление Flash-памятью |
571 |
Таблица 8: Отображение памяти и размеры в микроконтроллерах STM32F76xxx/STM32F77xxx
21.5.1.1.Как обратиться к Flash-памяти через интерфейс TCM
Общий вопрос для всех новичков платформы STM32F7 – как воспользоваться преимуществом интерфейса TCM. Это явно работа скрипта компоновщика, который должен перераспределить адреса областей .text, .bss и .data, используя в качестве базовых адресов адреса, указанные в таблицах 7 и 8.
Однако эта операция не может быть легко выполнена путем изменения начального адреса области FLASH в скрипте компоновщика. Все потому, что, как уже было сказано, доступ в режиме записи через интерфейс ITCM не разрешен. Это означает, что OpenOCD или любой другой эквивалентный отладчик не сможет загрузить программный код, используя диапазон адресов 0x0020 0000 – 0x002F FFFF. Чтобы устранить это ограничение, нам нужно отделить диапазон адресов VMA от диапазона LMA так же, как мы это делали для области .data. Например, следующий фрагмент скрипта компоновщика показывает, как выполнить данную операцию.
1/* Задание областей памяти */
2MEMORY {
3ITCM_FLASH (rx): ORIGIN = 0x00200000, LENGTH = 1024K
4AXI_FLASH (rx): ORIGIN = 0x08000000, LENGTH = 1024K
5RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
6}
7
8/* Определение секций на выходе */
9SECTIONS
10{
11/* Сначала во FLASH помещается код запуска (startup) */
12.isr_vector :
13{
14. = ALIGN(4);
15KEEP(*(.isr_vector)) /* Код запуска */
16. = ALIGN(4);
17} >ITCM_FLASH AT>AXI_FLASH
18
19/* Программный код и другие данные помещаются во FLASH */
20.text :
21{
22. = ALIGN(4);
Управление Flash-памятью |
572 |
23*(.text) /* секции .text (код) */
24*(.text*) /* секции .text* (код) */
26KEEP (*(.init))
27KEEP (*(.fini))
29. = ALIGN(4);
30_etext = .; /* определение глобальных символьных имен в конце кода */
31} >ITCM_FLASH AT>AXI_FLASH
32
33/* Постоянные данные помещаются во FLASH */
34.rodata :
35{
36. = ALIGN(4);
37*(.rodata) /* секции .rodata (константы, строки, и т.д.) */
38*(.rodata*) /* секции .rodata* (константы, строки, и т.д.) */
39. = ALIGN(4);
40} >ITCM_FLASH AT>AXI_FLASH
Как видите (посмотрите на строки 17, 31 и 40), диапазон адресов VMA (то есть диапазон адресов, используемый ЦПУ для выборки программного кода) отображается на интерфейс ITCM-FLASH, тогда как диапазон адресов LMA (диапазон адресов, используемый для хранения программы во Flash-памяти), отображается на интерфейс AXI, позволяющий обращаться к Flash-памяти в режиме записи.
21.5.1.2.Использование CubeMX для конфигурации интерфейса
Flash-памяти
CubeMX упрощает конфигурацию шины, используемой для доступа к Flash-памяти
(TCM/AXI), ускорителя ART™ Accelerator и кэша L1 ядра Cortex-M7. Перейдя в раздел
Configuration и нажав кнопку Cortex-M7, можно сконфигурировать данные параметры, как показано на рисунке 7.
Рисунок 7: Представление Cortex-M7 Configuration в CubeMX
Управление Flash-памятью |
573 |
Обратите внимание, что на момент написания данной главы (август 2016 г.) генерируемый скрипт компоновщика был неправильным, поскольку он не задавал отдельные адреса LMA и VMA, как показано в предыдущем параграфе.