No recente Microsoft Build 2020 , o Azure RTOS foi mencionado repetidamente como um SO dedicado em tempo real para microcontroladores.
Neste material, descobriremos consistentemente que tipo de sistema operacional ele é, que lugar ele ocupa nos produtos da Microsoft para sistemas embarcados, e também instalaremos o agendador de SO em um dos microcontroladores STM32.
Para quem não se interessa pela revisão, mas precisa da parte prática, vá direto.
Afinal, o que Ă© isso?
Um microcontrolador Ă© um microcircuito especializado que combina um microprocessador, memĂłria e perifĂ©ricos em um pacote. Ao contrário de um computador "grande", ele tem quantidades limitadas dessa mesma memĂłria: os valores tĂpicos para RAM e ROM sĂŁo de dezenas a centenas de kilobytes.
Via de regra, o microcontrolador nĂŁo possui MMU (embora haja exceções, mas essas sĂŁo exatamente as exceções que seriam mais corretamente atribuĂdas a uma categoria completamente diferente de sistemas em um chip), ou seja, nĂŁo há suporte de hardware para o mecanismo de memĂłria virtual, que nĂŁo permite o uso de "full-fledged" SO mesmo ao expandir a memĂłria interna com microcircuitos externos.
, , IDE, . , , .. , , . , , , = = , , , (""). . , ThreadX, , — .
, . , , 128 ROM 64 RAM – . , "" , USB , , , "" .
, ""? - . . , , , . , "" .
, . , MMU ucLinux – "" Linux MMU ( , , ). , , ucLinux.
Microsoft?
Microsoft "" , Windows 10 IoT Enterprise LTSC, . Windows 10 IoT Enterprise ( ) . , Windows 10 IoT Core, UWP, : Raspberry Pi 2.
Windows Embedded Compact, , - . Compact – , "" Windows, . 2013- , , , .
Microsoft , , . , , .
.Net Micro Framework, C#. , – . , "Archive", 2018- . .Net Micro Framework C#, , . C# "" , — ( ). .Net Micro Framework.
C#: https://www.nanoframework.net/, https://www.wildernesslabs.co/. , ucLinux, , : , .
2019 Microsoft Express Logic, Microsoft Azure RTOS, X-WARE IoT Platform. Azure RTOS ThreadX , Azure IoT Hub Azure IoT Central. Azure RTOS Azure .
Azure RTOS :
- ThreadX, , , , ;
- TCP/IP NetX/NetX Duo;
- FAT FileX;
- USB Host/Device/OTG USBX;
- GUI: GUIX (GUIX Studio);
- - FileX: LevelX;
- TraceX;
- SDK Azure IoT NetX Duo – Azure.
: Azure Sphere. — . ( SoC) Linux, .
, , , .
, . , , - .
. – .
:
, , , , .
, , , . "" , , , .. .
ThreadX ? ThreadX : . , 100 .
, Azure RTOS — Microsoft. , ( ) Azure Sphere, , .
Azure RTOS
, ( 6 ). , , , , , , , .
Azure RTOS, , . , , ?
- . 2 ROM. .
- , , .
- ( 100 ), ( 120 ), , "".
- IDE .
- (Preemption threshold) — N , N, .. 0 (N — 1) , N (.. N ) . , . .
- (Event chaining) — , , (, ).
- (Priority inheritance) — . — , .
- ;
- (Modules). ThreadX "" "", . " " . , .
- . . , .. — . , .. , .
ThreadX FreeRTOS , , .
Azure RTOS — . .
- , , , , , , ;
- . 2020 , , issue, Microchip, NXP, Renesas, ST, Qualcomm;
- .
.
ThreadX STM32
Azure RTOS :

, ThreadX . ThreadX , , . , , , , , ( - C++, ).
ThreadX, , . , " " - , , .
STM32F4Discovery, , , STM32F103C8T6.
STM32F4Discovery , ST-Link, , (STM32F407VGT6) .

,
Windows 10 ( , 7).
STM32 HAL — API STM32. "", "" HAL. , HAL, "", . HAL , .
STM32CubeIDE — IDE STMicroelectronics .
ThreadX c GitHub. , , "" , : "Clone", "Download zip". UPD (. ): , , . , , Git , , , :
git clone https://github.com/azure-rtos/threadx.git
git checkout f8e91d4
threadx threadx-master.
STM32F4Discovery Mini-USB , "ST Link" . .

STM32CubeIDE. Workspace — .
, Start New STM32 Project.

1 STM32F4DISCOVERY, 2 ( ) Next (3):

, . threadx_test, , , .

"Copy only necessary files..." Finish.

Yes:


Project Explorer, . threadx_test.ioc ( ):

Clock Configuration , :

, SYSCLK = 168 , SysTick.
Pinout & Configuration, Connectivity, USB_OTG_FS (1) (2), (3) Reset_State (4).

USB OTG, HAL_Delay, , , . ThreadX, HAL ThreadX, . , USB OTG.
System Core SYS TIM7 Timebase Source Serial Wire Debug:

SysTick Timer ThreadX.
PA0, . User Manual , :

, . , . System Core — GPIO:

System Core — NVIC EXTI0:

Priority group "4 bits...":

! EXTI line0 interrupt Preemption priority 15 ( ). , , RTOS, , RTOS. .
, . , ThreadX , .
, Code Generation, Pendable request for system serivice, System tick timer, ThreadX Cortex-M4, :

.
threadx-master threadx_test\Middlewares workspace. Project Explorer F5 , :

threadx_test Properties. C/C++ General — Paths and Symbols. Add
Middlewares/threadx-master/ports/cortex_m4/gnu/inc
, :

, , ( cortex_m0, 3, 4, 7)
Middlewares/threadx-master/common/inc
! Source Location , Source folders on build path :
- /threadx_test/Core
- /threadx_test/Drivers
- /threadx_test/Middlewares
- — .
Apply and Close .
Middlewares/threadx-master/ports Project Explorer :
- cortex_m0
- cortex_m3
- cortex_m7
- cortex_m4/gnu/src/tx_vector_table_sample.S ( )
/ , Properties Exclude resource from build:

-.
( ):
- Middlewares/threadx-master/cmake
- Middlewares/threadx-master/docs
- Middlewares/threadx-master/samples
, :
- Middlewares/threadx-master/common
- Middlewares/threadx-master/ports/cortex_m4
STM32F407VGTX_FLASH.ld
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
(, )
. = ALIGN(8);
__RAM_segment_used_end__ = .;
ThreadX . .
RAM, STM32F407VGTX_RAM.ld.
Project Explorer Middlewares/threadx-master/ports/cortex_m4/gnu/src tx_initialize_low_level_sample.S.
SYSTEM_CLOCK = 6000000
6000000 168000000 SYSCLK.
SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1)
100 1000. 100 1000 : ThreadX, .
.
Core/Src/main.c
/* USER CODE BEGIN Includes */
#include "tx_api.h"
/* USER CODE END Includes */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
tx_kernel_enter();
.
Core/Startup/startup_stm32f407vgtx.s
.global Default_Handler
.global _vectors
g_pfnVectors:
_vectors:
ThreadX.
Core/Src/ demo_threadx.c .
#include "tx_api.h"
#include "main.h"
/* - */
#define DEMO_STACK_SIZE 1024
/* , -, */
#define DEMO_BYTE_POOL_SIZE 10240
/* - */
#define THREAD_COUNT 4
/* , (thread control block) */
TX_THREAD thread_x[THREAD_COUNT];
/* , */
TX_BYTE_POOL byte_pool_0;
/* */
TX_EVENT_FLAGS_GROUP evt_group;
/* TX_BYTE_POOL */
UCHAR memory_area[DEMO_BYTE_POOL_SIZE];
/* () N */
#define EVT_KEYPRESS_THREAD(n) (1 << n)
/* */
#define LED_PAUSE_AND_DEBOUNCE_TIME_MS 100
/* */
static struct
{
GPIO_TypeDef* GPIOx;
uint16_t GPIO_Pin;
uint32_t blink_delay_ms;
char thread_name[10];
} BoardLedsSettings[THREAD_COUNT] =
{
{ LD3_GPIO_Port, LD3_Pin, 250, "orange" },
{ LD4_GPIO_Port, LD4_Pin, 500, "green" },
{ LD5_GPIO_Port, LD5_Pin, 750, "red" },
{ LD6_GPIO_Port, LD6_Pin, 1000, "blue" }
};
/* Callback () */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0)
{
for (int i = 0; i < THREAD_COUNT; i++) tx_event_flags_set(&evt_group, EVT_KEYPRESS_THREAD(i), TX_OR);
}
}
/* -worker 4 */
void thread_entry(ULONG thread_input)
{
/* */
uint8_t led_state = GPIO_PIN_RESET;
uint32_t cur_delay_ms = BoardLedsSettings[thread_input].blink_delay_ms;
ULONG actual_flags_ptr;
while(1)
{
HAL_GPIO_WritePin(BoardLedsSettings[thread_input].GPIOx, BoardLedsSettings[thread_input].GPIO_Pin, led_state);
led_state = !led_state;
if (TX_SUCCESS == tx_event_flags_get(&evt_group, EVT_KEYPRESS_THREAD(thread_input),
TX_AND_CLEAR, &actual_flags_ptr, cur_delay_ms))
{
/* " ". */
HAL_GPIO_WritePin(BoardLedsSettings[thread_input].GPIOx, BoardLedsSettings[thread_input].GPIO_Pin, GPIO_PIN_RESET);
/* , , */
tx_thread_sleep(LED_PAUSE_AND_DEBOUNCE_TIME_MS);
/* , , () */
tx_event_flags_get(&evt_group, EVT_KEYPRESS_THREAD(thread_input), TX_AND_CLEAR, &actual_flags_ptr, TX_NO_WAIT);
/* */
led_state = GPIO_PIN_SET;
/* */
cur_delay_ms = (cur_delay_ms == BoardLedsSettings[thread_input].blink_delay_ms) ?
cur_delay_ms * 2 : BoardLedsSettings[thread_input].blink_delay_ms;
}
}
}
/* */
void tx_application_define(void *first_unused_memory)
{
CHAR *pointer = TX_NULL;
/* byte memory pool, */
tx_byte_pool_create(&byte_pool_0, "byte pool", memory_area, DEMO_BYTE_POOL_SIZE);
/* */
tx_event_flags_create(&evt_group, "event group");
/* 4 , BoardLedsSettings */
for (int i = 0; i < THREAD_COUNT; i++)
{
/* i */
tx_byte_allocate(&byte_pool_0, (void **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* i */
tx_thread_create(&thread_x[i], BoardLedsSettings[i].thread_name, thread_entry, i, pointer, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
}
}
4 , , , . . — . .
Project — Build All , .
Run — Debug Configurations, STM32 Cortex-M C/C++ New Configuration:

( ST-LINK ) Debug. .
HAL_Init();
F8, , . .
— " " RTOS. 4 , — , . RTOS (UPD: . ).
, RTOS. ( -callback HAL_GPIO_EXTI_Callback() ), . .
, , , . . , ( , ), . — .
(thread_entry), "" , (, , , ) BoardLedsSettings. : , , .
RTOS . , . , , . , , , . 1 .
tx_thread_create() . , , . , , ThreadX . (byte_pool_0),
tx_byte_pool_create(&byte_pool_0, "byte pool", memory_area, DEMO_BYTE_POOL_SIZE);
tx_byte_allocate(&byte_pool_0, (void **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
(pointer) :
tx_thread_create(&thread_x[i], BoardLedsSettings[i].thread_name, thread_entry, i, pointer, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
:
tx_application_define(), . , .
Azure RTOS () , FileX, NetX .. — .
, ThreadX , . Microsoft , Azure RTOS Microsoft — .
— , . sergant (at) quarta.ru.