RTOS do Azure. Parte 1: visão geral e lançamento (STM32 + CubeIDE + HAL)

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, .





, , , .



, . , , - .



. – .



:



  • Windows Embedded Compact — ;
  • Azure RTOS/ThreadX — ;
  • Azure Sphere — , (Azure Sphere OS) , .


, , , , .



, , , . "" , , , .. .



, , , , : , .



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);


:



  • , , , . . ThreadX , .
  • ( TX_AUTO_START).
  • TX_NO_TIME_SLICE time-slice . , , .
  • , .
  • ThreadX . . .


tx_application_define(), . , .





Azure RTOS () , FileX, NetX .. — .



, ThreadX , . Microsoft , Azure RTOS Microsoft — .



— , . sergant (at) quarta.ru.




All Articles