Предисловие
Как я понимаю ваш вопрос, вы думаете, как написать свой собственный проект RTOS, чтобы сделать первые шаги во встроенном программировании с использованием RTOS после того, как вы сделали HAL программирование, некоторое время работавшее тестером, теперь пытающееся «перерасти» из роли тестера в роль разработчика чем тестеры.).
Поэтому я предполагаю, что вы знаете, как создать встроенное программное приложение на STM32 на основе архитектуры main-l oop.
Любые идеи приветствуются
Ваш вопрос сформулирован очень открыто, поэтому я осмелюсь попытаться набросать план, как вы можете сделать свой (весь) личный образовательный проект. Приношу свои извинения тем читателям, которые считают этот ответ обширным.
1. Пример с двумя задачами RTOS, от датчика к дисплею?
Пример, который вы упомянули, является довольно известным учебным примером для вашей работы, потому что он идеально подходит для демонстрации того, для чего нужна ОСРВ в контексте учебника: Поддержка функциональная декомпозиция двух совершенно не связанных между собой компонентов системы путем развертывания их для различных задач.
Другой вопрос, является ли это хорошим примером приложения для изучения фактической интеграции ОСРВ для ваших личных целей обучения. Это зависит от знакомства с тем, что вы делаете внутри этих двух задач, и это должно быть как можно лучше, чтобы вы могли хорошо сосредоточиться на специфике архитектуры SW на основе RTOS. Одна задача («IN») обрабатывает
чтение значений с датчика
- Я предполагаю, что вы используете датчик I² C, с которым вы уже работали с. - Отлично! Другая задача («OUT») связана с отображением на экране
.
Я лично пару лет разрабатывал прошивки RTOS, но Я никогда не интегрировал встроенный дисплей. Если бы я выполнил план для себя, я бы сбросил значения в другой последовательный интерфейс (скажем, UART, подключенный к виртуальному последовательному порту, который вы получаете при использовании STM32 простой платы Nucleo), и на моем терминальном окне P C будет фактическим показом. Пожалуйста, измените ваш личный план на ваш собственный технический опыт.
2. Подготовьте свое программное обеспечение для RTOS
Начните с того, что вы уже хорошо делаете: сделайте прошивку main-l oop, работающую правильно на вашей цели, где вы хорошо разделяете две функции, заботясь о том, чтобы они были красивыми и простыми интерфейс между этими двумя частями (компонент IN общается только с OUT, что ему нужно знать). Самое главное, интерфейс для IN, чтобы помещать обновления данных в OUT, должен управляться событиями, а не опрашивать, т. Е. IN вызывает функцию, только если есть что обновить, и OUT не вызывает какую-либо функцию для «прослушивания», если IN имеет какие-то новая информация для отчета.
На данный момент оба компонента должны иметь функцию "галочки", вызываемую из основного l oop, чтобы любой компонент делал все необходимое для себя внутри этой функции. Например, задача IN периодически запускает запрос получения данных на периферийном устройстве I² C (или его DMA), используя ваш драйвер.
3a. Добавьте RTOS к монолитной прошивке
Теперь, пожалуйста, интегрируйте библиотеку RTOS, чтобы она выполняла одну задачу, которая содержит ваш прежний главный l oop. Подсказка: старый main l oop становится вашей единственной «задачей по умолчанию», а функция main () завершается после вызова start-RTOS (и, возможно, оператора assert, отлавливающего любой неожиданный возврат, если вы допустили ошибку конфигурации ). Вызов для запуска планировщика обычно не возвращается, поскольку основной (системный) контекст будет заменен контекстом задачи RTOS.
Если вы еще не приняли решение, какую RTOS выбрать, я предлагаю выбрать freeRTOS (то есть OSS) и предварительно сконфигурировать его с помощью STM32CubeMX (также бесплатно), чтобы вам не приходилось разбираться во всех деталях на время. Если вы выберете freeRTOS, последним вызовом для запуска RTOS будет «osKernelStart ()».
Fini sh установка и отладка, чтобы он снова запустился.
3b. Сделайте это многозадачным программным обеспечением
Это когда ваша прошивка превращается в настоящую прошивку RTOS (а не просто как если бы). Вам нужна еще одна задача - вставьте ее в конфигурацию ОСРВ рядом с уже выполненной задачей и создайте еще одну функцию задачи. Функции задач выглядят как функции main (), состоящие из части инициализации с одним выстрелом и бесконечной l oop. Удалите один компонент из существующей задачи и поместите его в новую задачу.
Теперь вы должны заменить вызов функции "put" сверху взаимодействием между задачами. Настройте очередь, которая читается задачей OUT. Каждый раз, когда OUT может вывести обновление данных из очереди, оно должно применить его к «отображению» (например, передать последовательность кадров UART). Пусть задача IN поместит структуру данных в созданную вами очередь. Примечание: дескриптор очереди (постоянный указатель после создания) должен быть единственным символом переменной, который видят обе задачи. Кроме того, задания будут жить в разных мирах.
3 c. Время запуска задачи
Предполагая, что ваша задача OUT может работать с одним действием, например помещением структуры данных в буфер DMA и запуском этого DMA, эта задача должна выполняться только тогда, когда она передается через «свой» очередь из задачи IN. Т.е. он не будет потреблять процессорное время, если у него нет работы. Присвойте этой задаче более высокий приоритет, чем задаче IN.
Теперь задача IN будет выполняться только тогда, когда задача OUT не занята. На данный момент - если заданию IN нечего делать, вы можете оставить его в режиме ожидания, пока не захотите получить следующий набор данных с вашего датчика. Завершите sh код и отладьте его, чтобы у вас снова была работающая система.
Конечно, вы не хотите, чтобы задача IN занимала почти все процессорное время, а только то, что ей нужно. Перепроверьте интерфейс драйвера I² C и определите, как часто он должен вызываться. Настройте таймер перезагрузки (используйте HW-таймер или SW-таймер, когда вы sh, попробуйте другой вариант позже). Обратный вызов таймера (для HW timer: обработчик ISR) должен отправить событие в задачу IN. Задача IN должна прослушивать это событие (и блокировать, когда событие отсутствует). Всякий раз, когда событие происходит из-за обратного вызова таймера, задача IN активируется, получает данные от датчика, помещает их в очередь на OUT и ожидает повторного блокирования следующего события.
Теперь вам нужно простоя задача, которая запускается ОСРВ, в то время как все производительные задачи заблокированы. ИМХО, простое задание не должно ничего делать, но это предмет философской дискуссии. Re-fini sh кодирование и отладка. Снова запустите вашу систему, улыбнитесь и попробуйте мороженое: -)
4. Добавление дополнительных вкусностей
Вы освоили ключевые моменты, теперь углубите свои знания / опыт работы с RTOS на следующие моменты:
- Проверьте все виды межпроцессного взаимодействия, которые предлагает ваша библиотека RTOS, попробуйте их внутри вашей системы.
- Добавьте дополнительные задачи с причудливыми вещами. Например, используйте другую очередь / задачу для управления светодиодом в зависимости от значений датчика.
- Настройте трассировку / отладку SWV и исследуйте нагрузку, создаваемую каждой задачей (ITM / SWO), а также состояние времени выполнения в произвольной точке останова. моменты.
- Приведите в порядок свой код и выясните, куда поместить границы модулей.
- Используйте слой абстракции операционной системы поверх вашей ОСРВ.