Операционная система с открытым исходным кодом RT-Thread предоставляет разработчикам множество компонентов, что упрощает развертывание на различных аппаратных платформах и бизнес-сценариях. Система поддерживает программирование flash и OTP. Такие компоненты, как консоль FinSH, виртуальная файловая система (virtual file system, VFS), фреймворк utest, dynamic module, socket abstraction layer, AT component, интерфейс POSIX, лог Ulog, power management, сетевая подсистема, и т. п., значительно упрощают разработчику создание современного полнофункционального устройства.
[Консоль FinSH]
FinSH [2] это компонент командной строки RT-Thread, предоставляющий для пользователей интерфейс взаимодействия с устройством наподобие того, как это реализовано в Linux. Конечно, функционал консоли ограничен, насколько это позволяют доступные ресурсы MCU и требования разработчика, однако консоль предоставляет достаточно возможностей по выводу отладочной информации, настройки системы и тестирования функций. Подключиться к консоли FinSH можно на компьютере PC, используя последовательный порт, Ethernet, USB, Wi-Fi.
На фазе разработки командная строка FinSH дает возможность разработчику быстрее проверить работу необходимых частей программы, управлять настройками, быстрее найти ошибки, и в конечном счете уменьшает количество итераций по перепрошивке, сокращая общее время разработки и тестирования.
FinSH после запуска поддерживает функцию верификации прав доступа к строке команд, автодополнение и историю команд.
[Virtual File System]
Виртуальная файловая система (VFS) это набор абстрактных типов данных, реализующих хранилище, иерархическую организацию, доступ к чтению и записи данных для пользователей [7]. Базовую единицу хранения информации обычно представляют файлы, и для их организации существуют папки.
DFS (сокращение от Device File System) это компонент виртуальной файловой системы RT-Thread. Применена система именования, аналогичная организации системы имен файлов и папок UNIX:
Путь до всех объектов в файловой системы начинается от корня (root), обозначенного как /. Например, файл f1.bin в корневой директории представлен путем /f1.bin, и файл f1.bin в директории data/2019 представлен путем /data/2019/f1.bin. Эта система имен отличается от Windows, где в качестве разделителя используется \, и все пути к файлам начинаются от буквы диска с двоеточием.
Основные функции компонента RT-Thread DFS:
• Унифицированные POSIX-операции над файлами и папками для приложений: read, write, poll/select, и т. п. • Несколько типов файловых систем: FatFS, RomFS, DevFS, с поддержкой обычных файлов, файлов устройств, сетевых дескрипторов файлов. • Несколько типов устройств хранения: SD Card, SPI Flash, Nand Flash, и т. д.
Иерархическая структура компонента DFS показана на следующем рисунке, и основные части здесь это слой интерфейса POSIX, слой VFS, слой абстракции от устройства хранения.
[Фреймворк utest]
Модуль utest (сокращение от unit test) это система тестирования элементов программы, разработанная командой RT-Thread. Основное его назначение - упростить создание тестов для разработчиков приложений на основе RT-Thread (unit testing, coverage testing, integration testing).
[Dynamic Module: dlmodule]
Dynamic Module представляет механизм динамической загрузки модулей программы для RT-Thread. Из-за того, что модуль скомпилирован и хранится отдельно от ядра системы (kernel), то появляется дополнительная гибкость для расширения функций. В контексте реализации это механизм разделения ядра и программных (динамических) модулей. Благодаря этому механизму kernel и динамические модули могут компилироваться отдельно, и во время работы системы (runtime) скомпилированные динамические модули загружаются в ядро с помощью загрузчика модулей (module loader).
Для динамического модуля RT-Thread в настоящий момент поддерживается 2 формата:
.mo Это исполняемый динамический модуль, у файла которого после компиляции появляется суффикс .mo; он может быть загружен, и будет автоматически создан главный поток системы (main thread), чтобы выполнить функцию main() модуля. Одновременно функция main(int argc, char**argv) может также принять аргументы командной строки.
.so Это динамическая библиотека, у файла которой после компиляции появляется суффикс .so; она может быть загружена в память, и её набор функций может вызывается из других программ (обычный код или динамические модули в ядре).
[Socket Abstraction Layer]
Чтобы добавить в приложение больше сетевых протоколов и избежать зависимости системы от одного стека протокола, в RT-Thread предоставляются компоненты SAL (Socket Abstraction Layer), в которых реализованы различные сетевые протоколы или варианты организации сетевых коммуникаций. Интерфейс абстракции предоставляет набор стандартных вызовов BSD Socket API для верхнего уровня программы, благодаря чему разработчику нужно заботиться только об использовании API-интерфейса на сетевом уровне приложения, не вдаваясь в подробности реализации специфики протоколов нижележащих уровней. Это упрощает реализацию сетевых приложений на основе стандартных протоколов верхнего уровня. Основные функции компонента SAL:
• Абстрактный и универсальный интерфейс для нескольких сетевых протоколов. • Шифрование пакетов на уровне сокета (Socket-level TLS encrypted transport). • Стандартный BSD Socket API. • Унифицированное управление сетевыми дескрипторами файлов (FD management) с использованием read/write poll/select (SAL Network Framework).
Основная структура SAL network framework RT-Thread показана на следующей диаграмме:
[Компонент AT]
Интернет Вещей (Internet of Things, IoT) реализует множество сетевых модулей AT, и для упрощения разработки в RT-Thread разработан фреймворк AT, который может работать через стандартный интерфейс сокетов BSD.
Компонент AT в системе RT-Thread базируется на реализации AT Server и AT Client. Компонент обеспечивает передачу команды AT, обработку её формата и параметров, ответ на команду, прием и парсинг данных, обработку данных URC, и другую обработку интерактивных данных команды.
Через компонент компонент AT устройство может использовать последовательный порт для подключения к другим устройствам, чтобы посылать и принимать обрабатываемые данные. Устройство может работать как сервер (AT Server), позволяющий другим устройствам подключаться к нему, или даже к устройству может подключиться компьютер. Также устройство может работать в режиме консоли (CLI mode), когда поддерживается одновременно и AT Server, и AT Client. Одновременное использование режимов сервера и клиента AT чаще всего применяется для разработки и отладки.
Расход ресурсов компонента AT:
AT Client: 4.6K ROM и 2.0K RAM. AT Server: 4.0K ROM и 2.5K RAM; AT CLI: 1.5K ROM и RAM почти не используется.
В целом расход ресурсов компонентом AT очень небольшой, делая его идеальным для использования во встраиваемых устройствах с ограниченными ресурсами. Исходный код компонента AT находится в основном в каталоге rt-thread/components/net/at/.
Основные функции AT Server:
- Базовые команды. Реализовано несколько основных команд (ATE, ATZ, и т. д.). - Совместимость команд. Поддерживается игнорирование регистра символов. - Детектирование команд. Команда поддерживает пользовательские параметры и выражения, реализовано автоматическое детектирование принятых параметров команды. - Регистрация команды. Предоставлен простой способ добавления пользовательских команд, подобно тому как это сделано для добавления команд FinSH/MSH. - Debug mode. Предоставлен интерактивный CLI-режим командной строки, используемый в основном для отладки firmware.
Основные функции AT Client:
- Обработка данных URC. Реализован метод полной обработки URC data. - Анализ данных. Поддерживается анализ пользовательских данных ответа (custom response data), упрощено извлечение необходимой информации из этих данных. - Debug mode. Предоставлен интерактивный CLI-режим командной строки, используемый в основном для отладки firmware. - AT Socket. В качестве расширения функции AT Client, на базе AT-команды для передачи и приема данных реализованы стандартный BSD Socket API. Это дает пользователю реализовать работу устройства по сети с помощью AT-команд. - Multi-client. Компонент AT также поддерживает несколько одновременно работающих клиентов.
[Интерфейс POSIX]
API-интерфейс POSIX в RT-Thread включает следующие части: libc (например newlib), файловая система, pthread, и так далее. Для этого нужно открыть в rtconfig.h соответствующие опции:
#define RT_USING_LIBC
#define RT_USING_DFS
#define RT_USING_DFS_DEVFS
#define RT_USING_PTHREADS
RT-Thread реализует большинство функций и констант Pthreads, определенных в заголовочных файлах pthread.h, mqueue.h, semaphore.h и sched.h, соответствующих стандарту POSIX. Pthreads является дочерней библиотекой в libc, и Pthreads в RT-Thread базируется на инкапсуляции kernel-функций RT-Thread, что делает систему POSIX-совместимой.
[Лог Ulog]
Ulog это очень простой для использования компонент лога C/C++. Первая буква u в имени компонента означает μ, т. е. micro, микроконтроллер. Компоненту ulog нужен минимальный набор ресурсов: ROM < 1K, RAM < 0.2K. Хотя компонент ulog очень небольшой по объему, в нем есть очень продвинутые функции. Концепция его дизайна перекликается с другой C/C++ open source библиотекой лога: EasyLogger (которую называют еще elog), и сделано много улучшений в плане функционала и производительности. Основные функции следующие:
- Нижний слой (backend) вывода лога может работать поверх serial port, network, file, памяти flash memory и других элементов хранения и отображения информации. - Вывод лога реализован потокобезопасным (thread-safe), и поддерживает асинхронный режим вывода. - Система лога очень надежна, и доступна даже в таких жестких условиях, как обработчики прерываний (ISR) и событий отказа (Hardfault). - Уровень вывода диагностических сообщений может быть установлен как во время компиляции, так и runtime. - Поддерживается глобальная фильтрация лога по ключевому слову или метке. - API и форматы лога совместимы с syslog Linux. - Поддержка вывода дампа данных в hex-формате. - Поддерживается совместимость API-функций вывода лога с rtdbg (ранний заголовочный файл лога RTT) и EasyLogger.
На следующем рисунке показана архитектура компонента ulog:
[Power Management: PM]
На начальной стадии разработки обычно больше уделяется внимания как можно более полной реализации всех функций устройства. После того, как функции продукта разработаны, встает вопрос о внедрении функции управления питанием (power management, PM). Чтобы устройство удовлетворяло требованиям IoT-устройства, в RT-Thread предоставлены компоненты управления питанием. Идея реализации PM-компонентов - сделать их как можно более прозрачными и удобными для простого внедрения в устройство функций управления питанием.
PM-компоненты RT-Thread основаны на идее нескольких слоев, отделяя части кода, привязанные к архитектуре, от частей кода, работающих на слоя ядра. Хотя общий интерфейс предоставлен для верхнего уровня приложения, также существует несложный способ адаптации компонентов на низком уровне драйвера.
Основные функции PM-компонентов RT-Thread:
- PM на основе текущего режима управляет потребляемой мощностью, динамически подстраивает рабочий режим в режиме ожидания (idle), и поддерживает несколько уровней режима сна. Это работает прозрачно для приложений, компоненты автоматически управляют питанием на нижнем слое. - Поддерживается динамическое преобразование частоты в рабочем режиме (running), и автоматически обновляет конфигурацию частоты оборудования в соответствии с режимом, гарантируя нормальное функционирование в различных рабочих режимах. - Поддерживает управление питанием оборудования, автоматически управляя приостановкой и возобновлением работы в соответствии с режимом, гарантируя корректное погружение в сон и возврат из него в различных режимах пониженного энергопотребления (sleep mode). - Поддерживается опциональная компенсация времени сна, что делает тик системы (OS Tick) прозрачным для приложения. - Предоставляется интерфейс устройства верхнего уровня. Если открыт компонент devfs, то к нему может осуществляться доступ через интерфейс файловой системы.
[Фреймворк сети]
Чтобы поддерживать стеки различных сетевых протоколов, в RT-Thread был разработан компонент SAL (сокращение от Socket Abstraction Layer). RT-Thread может прозрачно получить доступ к различным стекам протоколов, включая протокол TCP/IP, такой как широко распростаненный стек LwIP, часто используемый во встраиваемых системах, а также компонент стека протокола AT Socket. Реализована полная поддержка преобразования данных между слоем сети и слоем транспорта.
Основные функции RT-Thread network framework:
- Стандартный сетевой BSD Socket API, с поддержкой poll/select. - Множество абстрактных, универсальных интерфейсов к сетевым протоколам. - Поддержка различных физических сетевых карт с помощью модуля сетевого оборудования. - Небольшой расход ресурсов памяти компонента SAL: ROM 2.8K и RAM 0.6K.
Фрейморк сети RT-Thread распределен по 4 слоям, каждый слой отвечает за свой функционал. На следующем рисунке показана структура RT-Thread network framework:
Эти функциональные компоненты разработаны в виде отдельных модулей, отдельно от ядра OS, и могут быть адаптированы и расширены с помощью графической среды IDE. Модульный дизайн обеспечивает гибкость при конфигурировании и невысокую зависимость между компонентами системы.
[Ссылки]
1. RT-Thread RTOS Overview and its Components site:iotbyhvm.ooo. 2. Консоль FinSH. 3. RT-Thread is an open source IoT operating system site:github.com. 3. IoT OS and RTOS for Internet of Things devices site:iotbyhvm.ooo. 4. What is RT-Thread RTOS site:iotbyhvm.ooo. 5. Internet of Things (IoT) Introduction | IoT Tutorial site:iotbyhvm.ooo. 6. QEMU: быстрый старт. 7. RT-Thread Virtual File System. |