воскресенье, 25 октября 2026 г.

Визуализация работы кэш памяти

Кэш — это специализированная высокоскоростная память, предназначенная для временного хранения и быстрого извлечения часто используемых данных.

Современные электронные устройства (компьютеры, смартфоны, микроконтроллеры) используют многоуровневую систему памяти. У каждого типа свои свойства и назначение:

• Основная память (например, жесткие диски или Flash-память) способна вмещать огромные объемы информации и хранить её долго, но работает медленно. Если процессор будет постоянно обращаться напрямую к ней, это сильно замедлит выполнение программ.

• Кэш-память решает эту проблему. Она выступает «буфером»: копирует в себя самые востребованные данные, обеспечивая процессору мгновенный доступ к ним.

Благодаря кэшированию работа программ значительно ускоряется, а количество запросов к медленной основной памяти снижается. Для некоторых типов накопителей (например, Flash или SSD) это критически важно, так как уменьшение числа циклов перезаписи сохраняет их ресурс и продлевает срок службы устройства.

Виды кэша

Кэш бывает двух типов:

1. Аппаратный — физически встроен в архитектуру процессора или контроллера (например, кэш-память уровней L1, L2, L3).

2. Программный — реализуется разработчиками в коде приложений на базе оперативной памяти (RAM) или регистров для ускорения работы с базами данных и файлами.

Алгоритмы вытеснения: стратегия LRU

Объем кэша всегда ограничен. Когда он заполняется «под завязку», устройству нужно решить, какие старые данные удалить, чтобы освободить место для новых. Для этого используются специальные алгоритмы.

Один из самых популярных — LRU (Least Recently Used), что переводится как «наименее недавно использованный». Его логика проста: алгоритм отслеживает время последнего обращения к элементам. Если кэш полон и в него нужно записать новые данные, LRU находит ту ячейку, к которой дольше всего никто не обращался, удаляет её содержимое и записывает туда свежую информацию.

Визуализация работы алгоритма LRU

Ниже представлена интерактивная схема, которая наглядно показывает этот процесс:

• Слева расположена основная (медленная) память, состоящая из 4 ячеек. В таблице отображаются адреса ячеек, хранящиеся в них данные, а также счетчики обращений (для общей информации).

• По центру находится быстрый кэш, рассчитанный всего на 2 ячейки.

• Справа выводится текущее извлекаемое значение, к которому программа обращается в данный момент.

память
>
0a0
1b0
2c0
3d0
>
кэш
>
текущее значение

Адрес биткоин кошелька для поддержки канала - bc1qlhrmmkh77x2lzhqe4lt9qwkglswj64tsqt2l5g


воскресенье, 4 октября 2026 г.

STM32 FreeRTOS уведомления задач

 Операционная система FreeRTOS содержит некоторое количество инструментов для коммуникации задачи и обработчиков прерываний между собой. Для этого можно использовать бинарные семафоры и даже, рассмотренные ранее, очереди но если нужно организовать максимально быстрое и не затратное по памяти решение то лучше всего подойдут "уведомления задач" (Task Notifications). Уведомления задач имеются в новых версиях FreeRTOS и могут передавать не только уведомления но и некоторое небольшое количество данных, 32 бита. Уведомления задач на 40% работают быстрее бинарных семафоров и в 90% случаев могут их заменить. Попробуем изучить уведомления задач на простом примере. Допустим у нас есть прерывание по приему на UART1 после получения данных в UART1, в обработчике прерывания, упакуем принятый байт данных и отправим как уведомление в задачу.Задача примет байт и отправит его в UART1. Таким образом мы получим простой эхо режим, работающий через задачу и использующий уведомление задачи. Чтобы использовать уведомление задачи нужно сначала инициализировать её хэндл.

В функции main когда мы создаем задачу то в функцию xTaskCreate, последним параметром, передаем этот хэндл.
Он, в последствии, будет использоваться для передачи уведомлений. Периферию настраиваем как обычно, включаем UART1, 
не будем на этом останавливаться см. предыдущие уроки.

Сейчас нас интересуют две функции. Это сама задача и обработчик прерывания по приему UART1.
В обработчике прерывания принимаем байт.
Далее используя специальную функцию для отправки уведомлений задачам из прерывания.
Отправляем уведомление задаче. Важно в прерывании использовать именно такую функцию. Если нужно отправить уведомление от задачи к задаче то есть другая похожая.
В этой функции хэндл задачи указываем первым параметром. Вторым параметром передаем принятый байт, предварительно приведя его к нужному типу.
Третьим параметром передаем константу означающую перезапись значения если задача не успела его вовремя принять и обработать. 
Ну и остальное просто оставим пока как есть. В самой задаче, объявляем переменную в которую будем принимать байт от UART1.
В бесконечном цикле задачи проверяем когда в задачу придет уведомление. Когда оно приходит, извлекаем принятый байт.
После отправляем его обратно в UART1.
Полный код файла main.c проекта, можно скопировать от сюда:

Его можно вставить в свой проект и откомпилировать запустив скрипт. О том как скачать и настроить проект а также откомпилировать см. первый урок по FreeRTOS. Если откомпилировать проект получилось то можно его загрузить в микроконтроллер. Подключить его через usb-uart переходник к компьютеру и в каком либо терминале последовательного порта наблюдать работу.


Адрес биткоин кошелька для поддержки канала - bc1qlhrmmkh77x2lzhqe4lt9qwkglswj64tsqt2l5g

суббота, 3 октября 2026 г.

Визуализация работы кольцевого буфера

 Кольцевой буфер — один из самых эффективных инструментов для обмена данными между асинхронными процессами. Его главное преимущество в средах с ограниченными ресурсами — работа без динамической памяти. Типичный пример асинхронности в микроконтроллерах — прерывания, момент возникновения которых заранее неизвестен. Встраиваемые системы имеют свою специфику выделения памяти, которая кардинально отличается от ПК: • На ПК оперативной памяти много, поэтому программы динамически запрашивают её у ОС и возвращают в общую кучу. • В микроконтроллерах объем ОЗУ жестко ограничен. Инженер может полностью контролировать всю память и заранее распределить её между задачами, избегая непредсказуемого поведения кучи. В таких условиях кольцевой буфер служит идеальным временным хранилищем. Конечно, это не единственный способ защитить данные от потери. Однако, в отличие от классической очереди, он требует гораздо меньше тактов процессора на операции чтения и записи. Благодаря высокому быстродействию и простоте программной реализации этот алгоритм стал стандартом де-факто в микроконтроллерных системах. Принцип его работы наглядно показан на визуализации ниже:

Кольцевой буфер с перезаписью (Overwrite)

➔
➔
Буфер пуст

Пример реализации кольцевого буфера на языке си
Пример использования:

Адрес биткоин кошелька для поддержки канала - bc1qlhrmmkh77x2lzhqe4lt9qwkglswj64tsqt2l5g