При использовании Pack от Миландр для Keil 5 можно заметить, что нет возможности подключить поставляемую вместе с Keil систему реального времени к 1986ВЕ1, так же легко, как это можно сделать для микроконтроллеров 1986ВЕ9х. При создании проекта для 1986ВЕ9х, RTOS выбирается одной галочкой в "Manage Runtime Environment".
Но, тем не менее, использовать RTOS в 1986ВЕ1 можно. Надо лишь самостоятельно подключить в проект необходимые файлы. Вот как выглядит дерево проекта при подключении RTOS к нашему примеру Hello World - светодиод.
Пути по которым лежат подключаемые файлы:
C:\Keil_v5\ARM\PACK\ARM\CMSIS\5.0.1\CMSIS\RTOS2\RTX\Source\rtx_lib.c C:\Keil_v5\ARM\PACK\ARM\CMSIS\5.0.1\CMSIS\RTOS2\RTX\Library\ARM\RTX_CM0.lib !Эти файлы лучше скопировать к себе в проект, как это делает среда для 1986ВЕ9х: C:\Keil_v5\ARM\PACK\ARM\CMSIS\5.0.1\CMSIS\RTOS2\RTX\Config RTX_Config.c RTX_Config.h и этот путь необходимо указать в закладке C/C++. RTE\CMSIS\ RTX_Config.c RTX_Config.h
Пути, которые необходимо подключить в проекте, закладка С/С++:
Можно заметить, что мы подключили библиотеку RTX_CM0.lib, а в папке по этому пути лежат также RTX_CM3.lib, RTX_CM4F.lib. То есть библиотеки к соответствующему ядру Cortex, а для Cortex-M1 отдельной библиотеки нет. Я думаю, это связано с тем, что ядра M0 и M1 имеют одну архитектуру ARMv6-M, а так же одинаковый набор инструкций. Убедиться в этом можно здесь ARM Cortex-M instruction variations. Кроме этого, применимость RTX_CM0.lib для ядра М1 обозначена в документации к RTOS CMSIS-RTOS RTX Library Files.
Для проверки работоспособности проекта реализуем мигание светодиодом, при этом слегка модифицируем код Hello World - светодиод для использования RTOS. Итоговый код "main.c":
#include <rtx_os.h> #include <MDR32F9Qx_port.h> #include <MDR32F9Qx_rst_clk.h> // Структура настроек для потока typedef struct { uint32_t Led_PortPin; uint32_t Led_Delay; } LED_ThreadCfg; // Задержка мигания светодиодов в миллисекундах #define Led_Delay_VD6 200 #define Led_Delay_VD7 400 #define Led_Delay_VD8 800 // Функция потока - исполняется в отдельном потоке void Thread_LED (void *argument) { // Структура для настройки портов PORT_InitTypeDef GPIOInitStruct; // Параметры для функции, задаются извне LED_ThreadCfg cfgThread = *(LED_ThreadCfg *)(argument); // Включение тактирования RST_CLK_PCLKcmd (RST_CLK_PCLK_PORTD, ENABLE); // Настройка вывода порта PORT_StructInit(&GPIOInitStruct); GPIOInitStruct.PORT_Pin = cfgThread.Led_PortPin; GPIOInitStruct.PORT_OE = PORT_OE_OUT; GPIOInitStruct.PORT_SPEED = PORT_SPEED_SLOW; GPIOInitStruct.PORT_MODE = PORT_MODE_DIGITAL; PORT_Init(MDR_PORTD, &GPIOInitStruct); // Цикл исполнения - мигание светодиодом while (1) { PORT_SetBits(MDR_PORTD, cfgThread.Led_PortPin); osDelay(cfgThread.Led_Delay); PORT_ResetBits(MDR_PORTD, cfgThread.Led_PortPin); osDelay(cfgThread.Led_Delay); } } int main(void) { // Настройки для потоков LED_ThreadCfg Cfg_Thread1 = {PORT_Pin_7, Led_Delay_VD6}; LED_ThreadCfg Cfg_Thread2 = {PORT_Pin_8, Led_Delay_VD7}; LED_ThreadCfg Cfg_Thread3 = {PORT_Pin_9, Led_Delay_VD8}; // Инициализация RTOS osKernelInitialize(); // Создание потоков мигания светодиодом osThreadNew (Thread_LED, &Cfg_Thread1, NULL); osThreadNew (Thread_LED, &Cfg_Thread2, NULL); osThreadNew (Thread_LED, &Cfg_Thread3, NULL); // Запуск RTOS osKernelStart(); }
Здесь мы создали три потока, в каждый из которых передали свою структуру, определяющую каким светодиодом и с каким периодом необходимо мигать.
На форуме можно найти примеры использования FreeRTOS для 1986ВЕ1, ссылка.