RMP Real-time kernel
Click HERE for English version.
RMP — это система, которая специализируется на формальной верификации и простоте использования небольших систем реального времени. Она использует формальные методы для обеспечения надежности системы (текущая работа по верификации еще не завершена; однако покрытие ветвей 100% белого ящика уже достигнуто). Текущее ядро может быть рассмотрено как предварительно сертифицированное на уровне IEC 61508 SIL2 или EAL 4. Оно обладает всеми необходимыми функциями операционных систем реального времени, но не предоставляет дополнительных компонентов для обеспечения ядра. Таким образом, полученное ядро представляет собой минимальное ядро, которое легко поддается формальной верификации. Кроме того, оно может использоваться в качестве клиентской операционной системы, работающей на виртуальном мониторе.
Эта система намного меньше, чем полнофункциональные системы, такие как FreeRTOS и RT-Thread, и должна быть относительно проще для понимания. Даже если эта система содержит только один файл .C, она все равно обеспечивает эффективное управление памятью, библиотеку графического интерфейса с защитой от дребезга и другие полезные функции, которые не требуют дополнительной RAM!
Руководство по этой системе можно найти здесь.
Если вы хотите принять участие в разработке, ознакомьтесь с участием и кодексом поведения. Если вы хотите отправить запрос на вытягивание, используйте шаблон запроса на вытягивание . Это программное обеспечение является официальным продуктом EDI и находится в общественном достоянии. Все права, сохраняемые EDI, предоставляются в максимально возможной степени всем субъектам в соответствии со всеми применимыми законами.
Для тех, кто ищет абстрактный слой программного обеспечения для микроконтроллеров, предоставляемых производителями, обратитесь к программному репозиторию M0A00_Library.
Существующие операционные системы реального времени можно разделить на три категории: корпоративные, для хобби и учебные. Корпоративные системы обычно предназначены для развертывания на местах и являются очень продвинутыми. Однако, хотя их код может быть открытым исходным кодом или даже бесплатным, почти все их функциональные документы по безопасности и технические детали стоят очень дорого. Системы, созданные для хобби, наоборот, бесплатны, но им не хватает долгосрочного внимания и соответствующего контроля качества, и они часто заброшены. Учебные системы находятся между ними, но они предназначены для студенческих экспериментов, не имея доступа к высокоуровневому содержанию, такому как формальная верификация и безопасность функций.
Учитывая это, RMP стремится создать полностью открытую, функциональную и обучаемую сертифицированную систему. Этот проект можно использовать тремя способами: (1) модифицировать или развернуть его, (2) изучить его код и процесс разработки, или (3) отказаться от этой системы и разработать свою собственную новую систему.
Весь проект разделен на три этапа. Сначала мы не пишем формальную модель системы напрямую, а разрабатываем ее, как это делают любители. Мы переносим его на как можно больше странных и необычных аппаратных средств, чтобы проверить его гибкость абстракции, и запускаем на нем как можно больше типов приложений, чтобы убедиться в доступности его интерфейсов. Затем мы начинаем с стабильного прототипа и ментальной модели первого этапа, обращаем формальную модель желаемого поведения и доказываем, что модель обладает некоторыми хорошими свойствами. Наконец, мы разрабатываем семантику подмножества C на основе формальной модели, полученной на предыдущем этапе, переписываем все ядро и доказываем его правильность. На этом этапе также будут созданы все необходимые документы для функциональной безопасности (включая IEC 61508 SIL 4 и ISO 26262 ASIL D, возможно, включая EAL; приоритет отдается первому), и они будут открыты для общественного достояния (исключая стандартные документы сами по себе, поскольку этот проект не владеет ими).
У этого проекта нет фиксированного графика разработки. Работа над первым этапом уже завершена, и сейчас идет работа над вторым этапом. Если вам интересен этот проект, присоединяйтесь к нему. В отличие от других проектов, этот проект приветствует новичков.
Перейдите сюда, чтобы скомпилировать двоичный файл, который можно запустить на 32-разрядной версии Linux для x86, и посмотрите результаты теста производительности!
Загрузите «игру» из здесь, поместите ее в свой любимый эмулятор (или поддержите картридж расширения Namco 163 и вставьте его в реальную машину) и посмотрите на результаты тестов производительности!
Чип расширения Namco 163 необходим, потому что системе необходимо использовать внутренний счетчик прерываний чипа для измерения производительности. Из всех чипов расширения только Namco 163 поддерживает читаемый счетчик прерываний, и этот чип также использовался в таких известных играх, как «Звездные войны» и «Троецарствие II: Континент тирана». Чип расширения Namco 163 также известен как Namcot 163 или iNES Expansion 019.
Создание потока
RMP_Thd_Crt(&Thd_1 /* 线程控制块 */,
Func_1 /* 函数入口 */,
&Stack_1 /* 线程栈地址 */,
sizeof(Stack_1), /* 线程栈大小 */,
(void*)0x12345678 /* 参数 */,
1 /* 优先级 */,
5 /* 时间片 */);
Удаление потока
RMP_Thd_Del(&Thd_1 /* 线程控制块 */);
Приостановка потока
RMP_Thd_Suspend(&Thd_1 /* 线程控制块 */);
Возобновление приостановленного потока
*Примечание: в тексте запроса присутствуют фрагменты кода, которые невозможно перевести без потери смысла. Они оставлены без перевода.* **RMP_Thd_Resume(&Thd_1 /* 线程控制块 */);**
void Func_1(void* Param)
{
RMP_LOG_S("Parameter passed is ");
RMP_LOG_H((ptr_t)Param);
RMP_LOG_S("\r\n");
while(1)
{
RMP_Thd_Delay(30000);
RMP_LOG_S("Delayed 30000 cycles\r\n\r\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1, sizeof(Stack_1), (void*)0x12345678, 1, 5);
}
**Инициализация потока: запуск и приостановка**
В данном фрагменте кода происходит инициализация потока с помощью функции RMP_Thd_Crt. В качестве параметров этой функции передаются:
* указатель на структуру Thd_1 — это структура, которая содержит информацию о потоке;
* функция Func_1 — функция, которая будет выполняться в потоке;
* адрес стека Stack_1 — место, где будут храниться локальные переменные функции Func_1;
* размер стека — размер памяти, который будет выделен для стека;
* значение параметра — значение, которое будет передано в функцию Func_1 при её вызове;
* приоритет потока — число от 0 до 9, определяющее приоритет потока;
* количество потоков — количество копий функции Func_1, которые будут выполняться параллельно.
Далее в функции Func_1 происходит вывод информации о переданном параметре с помощью функций RMP_LOG_S и RMP_LOG_H. Затем выполняется бесконечный цикл, в котором поток ожидает 30 секунд с помощью вызова функции RMP_Thd_Delay. После ожидания поток выводит сообщение о том, что ожидание завершено.
**Примечание:** в тексте запроса присутствуют фрагменты кода, но не указано, к какой области разработки программного обеспечения они относятся. Поэтому перевод может быть неполным или неточным.
---
**// 线程延时**
****
```C
void Func_1(void* Param)
{
RMP_LOG_S("Parameter passed is ");
RMP_LOG_H((ptr_t)Param);
RMP_LOG_S("\r\n");
while(1)
{
RMP_Thd_Delay(30000);
RMP_LOG_S("Delayed 30000 cycles\r\n\r\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1, sizeof(Stack_1), (void*)0x12345678, 1, 5);
}
Функция задержки потока
Данный фрагмент кода представляет собой реализацию функции задержки потока. Функция Func_1 выполняет задержку потока на 30 секунд, используя функцию RMP_Thd_Delay, после чего выводит сообщение об успешной задержке.
// Отправка данных из одного потока в другой
void Func_1(void* Param)
{
ptr_t Time=0;
while(1)
{
RMP_Thd_Delay(30000);
RMP_Thd_Snd(&Thd_2, Time, RMP_SLICE_MAX);
Time++;
};
}
void Func_2(void* Param)
{
ptr_t Data;
while(1)
{
RMP_Thd_Rcv(&Data, RMP_SLICE_MAX);
RMP_LOG_S("Received ");
RMP_LOG_I(Data);
RMP_LOG_S("\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1, sizeof(Stack_1), (void*)0x12345678, 1, 5);
RMP_Thd_Crt(&Thd_2, Func_2, &Stack_2, sizeof(Stack_2), (void*)0x87654321, 1, 5);
}
Отправка и получение данных между потоками
Этот фрагмент кода демонстрирует использование функций RMP_Thd_Snd и RMP_Thd_Rcv для отправки и получения данных между двумя потоками. Функция Func_1 отправляет данные в поток Thd_2 с помощью функции RMP_Thd_Snd. Функция Func_2 получает данные из потока Thd_1 с помощью функции RMP_Thd_Rcv.
// Использование счётчика сигналов
void Func_1(void* Param)
{
while(1)
{
RMP_Thd_Delay(30000);
RMP_Sem_Post(&Sem_1, 1);
};
}
void Func_2(void* Param)
{
ptr_t Data;
while(1)
{
RMP_Sem_Pend(&Sem_1, RMP_SLICE_MAX);
RMP_LOG_S("Semaphore successfully acquired!\r\n\r\n");
};
}
void RMP_Init_Hook(void)
{
RMP_Sem_Crt(&Sem_1,0);
RMP_Thd_Crt(&Thd_1, Func_1, &Stack_1, sizeof(Stack_1), (void*)0x12345678, 1, 5);
RMP_Thd_Crt(&Thd_2, Func_2, &Stack_2, sizeof(Stack_2), (void*)0x87654321, 1, 5);
}
Использование счётчика сигналов для синхронизации потоков
Здесь демонстрируется использование счётчика сигналов (семафора) для синхронизации двух потоков. Функция Func_1 увеличивает счётчик сигналов с помощью функции RMP_Sem_Post. Функция Func_2 ожидает освобождения семафора с помощью функции RMP_Sem_Pend. Если семафор свободен, то функция успешно его захватывает и выводит соответствующее сообщение.
// Работа с пулом памяти
/* 初始化内存池 */
RMP_Mem_Init(Pool, Pool_Size);
/* 从内存池分配内存 */
Mem=RMP_Malloc(Pool, Alloc_Size);
/* 向内存池归还内存 */
RMP_Free(Pool, Mem);
Работа с пулом памяти
Фрагмент кода показывает, как можно использовать пул памяти для управления выделением и освобождением памяти. Сначала вызывается функция RMP_Mem_Init для инициализации пула памяти с заданным размером. Затем вызывается функция RMP_Malloc для выделения блока памяти заданного размера из пула. Наконец, вызывается функция RMP_Free для освобождения блока памяти обратно в пул.
Данный раздел описывает характеристики производительности системы на различных архитектурах. Он включает в себя следующие пункты:
Для каждой архитектуры приведены значения времени выполнения основных операций, таких как переключение контекста, отправка и получение сообщений, использование семафоров, работа с FIFO, обработка прерываний и т. д. Также указаны различия между операциями Mail и Msgq, а также между операциями Sem и Bmq.
Раздел завершается сравнением времени выполнения операций на различных архитектурах и указанием на то, что время обработки прерываний зависит от периода прерывания. |N/A |TBD | |ATMEGA1284P |... |... |437 |751 |717 |314 |1098 |1352 |637 |639 |921 |1087 |1680 |TBD | |ATMEGA2560 |... |... |449 |774 |736 |326 |1131 |1396 |656 |654 |942 |1117 |1686 |TБД | |R5F104PJ |RL78 |CCRL |261 |565 |520 |308 |924 |1225 |539 |500 |789 |964 |1854 |TБд | |PIC24FJ128 |PIC24F |XC16 |152 |334 |271 |168 |468 |654 |274 |213 |352 |461 |379 |Тбд | |DSPIC33EP512 |DSPIC33E |... |214 |447 |353 |219 |608 |851 |368 |278 |455 |602 |448 |Тбд | |MSP430F149 |MSP430 |CCS |312 |641 |573 |312 |985 |1278 |528 |487 |739 |898 |Н/Д |Тбд | |MSP430FR5994 |MSP430X |... |468 |1054 |891 |492 |1573 |2072 |891 |784 |1176 |1464 |3291 |Тбд | |STM32F030F4 |Cortex-M0 |Keil |362 |763 |666 |379 |1196 |1609 |689 |616 |950 |1211 |Н/Д |Тбд | |... |... |GCC |366 |802 |690 |396 |1246 |1685 |705 |622 |954 |1200 |Н/Д |Тбд | |HC32L136K8 |Cortex-M0+ |Keil |211 |422 |370 |219 |646 |873 |403 |350 |532 |673 |542 |Тбд | |STM32L071CB |Cortex-M0+ |Keil |335 |581 |532 |253 |892 |1167 |554 |524 |756 |945 |Н/Д |Тбд | |... |... |GCC |337 |656 |600 |284 |947 |1260 |578 |602 |794 |1003 |Н/Д |Тбд | |STM32F103RE |Cortex-M3 |Keil |203 |438 |385 |226 |684 |930 |392 |354 |542 |707 |518 |Тбд | |... |... |GCC |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд |Тбд | |STM32F405RG |Cortex-M4F |Keil |180 |345 |321 |180 |667 |886 |309 |302 |498 |626 |455 |Тбд | |... |... |GCC |196 |388 |345 |192 |677 |953 |381 |349 |566 |743 |411 |Тбд | |STM32F767IG |Cortex-M7F |Keil |176 |329 |277 |174 |510 |694 |328 |259 |413 |516 |334 |Тбд | |... |... |GCC |182 |335 |288 |156 |473 |643 |313 |264 |375 |514 |332 |Тбд | |TMS570LS0432 |Cortex-R4 |CCS |306 |493 |460 |193 |686 |897 |480 |464 |592 |736 |533 |Тбд | |TMS570LC4357 |Cortex-R5 |... |275 |479 |467 |216 |746 |998 |440 |435 |595 |763 |482 |Тбд | |TMS320F2812 |C28x |CCS |217 |493 |407 |229 |706 |954 |436 |381 |583 |727 |939 |Тбд | |TMS320F28335 |C28x/FPU32 |... |246 |513 |440 |235 |751 |1001 |440 |413 |622 |770 |946 |Тбд | |CH32V307VC |RV32IMAC |GCC |209 |386 |336 |172 |538 |698 |350 |306 |436 |555 |433 |Тбд | |... |RV32IMAFC |... |217 |398 |341 |172 |557 |705 |358 |307 |444 |556 |433 |Тбд | |Xeon 6326 |X86-LINUX |... |24к |24к |24к |46 |24к |24к |31к |30к |34к |53к |159 |Тбд | | 50% | 1789 | 1742 | 1857 | 1951 | 399% | 390 | 608 |
В качестве сравнения, RT-Linux 4.12 на Cortex-M7 имеет наилучшее время переключения потоков 25 000 тактовых циклов (оно слишком велико, чтобы работать только из FMC SDRAM, поэтому это сравнение фактически несправедливо). Это было измерено с использованием futex; результаты хуже при использовании других IPC, таких как каналы.
Все эксперименты не включают никаких мошеннических действий (например, агрессивную оптимизацию для конкретной цепочки инструментов, переключение потоков без использования планировщика, использование планировщиков со средним, но непредсказуемым временем выполнения или даже использование бесстековых сопрограмм RMS), и в тестовых заголовках сообщается о реальном наихудшем времени выполнения. Хотя мы включили средние значения для более общего сравнения, для RTOS наихудшее время выполнения является единственным значимым показателем, поэтому все, что способствует средней производительности за счёт наихудшего времени выполнения, не применяется. Если целью является максимальная скорость, невозможно иметь операционную систему быстрее, чем RMS или DOS, поскольку теоретическое время переключения RMS равно нулю (все сопрограммы встроены, и существует только одно состояние), а DOS как однозадачная операционная система вообще не имеет времени переключения.
Архитектура | Причина | Альтернативная реализация |
---|---|---|
PIC18 | Стек аппаратного обеспечения | Использование RMS State Machine OS |
AVR32 | Исчезает | Использование популярных Cortex-M и Cortex-R |
x86-64 | Высокоуровневые системы | Использование RME Microkernel OS |
Cortex-A | Высокоуровневые системы | Использование RME Microkernel OS |
RTOS в основном ориентирован на ограниченные ресурсы микроконтроллеры и не предоставляет поддержку микропроцессоров. Проект также не рассматривает многоядерную поддержку, поскольку многоядерные микроконтроллеры редко симметричны, и между ядрами нет поддержки атомарных операций или согласованности кэша, даже если RMP поддерживает их, параллельное программирование на них очень сложно. Для многоядерных микроконтроллеров рекомендуется запускать экземпляр RMP на каждом ядре, а экземпляры могут взаимодействовать через межпроцессорные прерывания (IPIs).
Следующие инструкции помогут вам быстро создать проект, который можно использовать для оценки и тестирования этой системы. Пожалуйста, обратитесь к документации системы на китайском языке для получения дополнительной информации.
Для запуска тестов вам потребуется плата разработки, содержащая перечисленные выше микроконтроллеры. Рекомендуется использовать платы серии STM32 Nucleo или MSP430 Launchpad. Не используйте эмулятор QEMU для тестирования системы, так как у QEMU есть много недостатков, которые не соответствуют реальному поведению оборудования.
Если у вас нет платы разработки, RMP также имеет x86-реализацию Linux . Однако этот перенос использует системные вызовы ptrace и сигналы, что приводит к снижению производительности, что видно из данных тестирования производительности.
Поддержка других платформ должна быть легко реализована, но в настоящее время её нет в планах. Для процессоров Cortex-A и с блоком управления памятью (MMU), таких как другие процессоры, можно использовать RME Real-Time Multicore Microkernel; RME также поддерживает часть Cortex-M и все Cortex-R.
Файлы Makefile, Keil, CCS и MPLAB для различных микроконтроллеров можно найти в папке Project. Ознакомьтесь с файлами проекта в каждой папке для получения информации о том, как компилировать и запускать проект. Некоторые проекты требуют дополнительной поддержки от сторонних библиотек аппаратных абстракций, которые можно найти в репозитории программного обеспечения M0A00_Library.
Чтобы запустить тесты, просто загрузите тест на соответствующую плату разработки и начните пошаговую отладку. В некоторых примерах используются два светодиода для индикации текущего состояния системы, и необходимо заполнить функции включения и выключения светодиодов для запуска примера.
Чтобы использовать встроенный графический интерфейс системы, обратитесь к соответствующему разделу руководства пользователя.
При развёртывании системы в производственной среде внимательно прочитайте прилагаемое руководство, чтобы убедиться, что все конфигурации верны. Руководство системы можно найти в папке Document.
Другие цепочки инструментов в настоящее время не рекомендуются или не поддерживаются, хотя добавление новой поддержки должно быть простым.
Пожалуйста, ознакомьтесь с документацией CONTRIBUTING.md для получения информации о поведении и отправке кода.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )