Prechádzať zdrojové kódy

Добавил терминал в desk.

TelenkovDmitry 3 týždňov pred
rodič
commit
323189d7d9
41 zmenil súbory, kde vykonal 12788 pridanie a 3903 odobranie
  1. 0 0
      cube_example/usb_hid_example/.mxproject
  2. 7 38
      cube_example/usb_hid_example/Core/Inc/FreeRTOSConfig.h
  3. 16 0
      cube_example/usb_hid_example/Core/Inc/main.h
  4. 3 3
      cube_example/usb_hid_example/Core/Inc/stm32g4xx_hal_conf.h
  5. 1 1
      cube_example/usb_hid_example/Core/Inc/stm32g4xx_it.h
  6. 558 339
      cube_example/usb_hid_example/Core/Src/main.c
  7. 310 18
      cube_example/usb_hid_example/Core/Src/stm32g4xx_hal_msp.c
  8. 1263 1233
      cube_example/usb_hid_example/Drivers/CMSIS/Device/ST/STM32G4xx/Include/stm32g411xb.h
  9. 170 171
      cube_example/usb_hid_example/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h
  10. 781 806
      cube_example/usb_hid_example/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c
  11. 1727 0
      cube_example/usb_hid_example/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c
  12. 1026 0
      cube_example/usb_hid_example/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
  13. 236 238
      cube_example/usb_hid_example/USB_Device/App/usbd_custom_hid_if.c
  14. 5 5
      cube_example/usb_hid_example/usb_hid_example.ioc
  15. 1727 0
      desk/libs/thirdparty/freertos/CMSIS_RTOS/cmsis_os.c
  16. 1026 0
      desk/libs/thirdparty/freertos/CMSIS_RTOS/cmsis_os.h
  17. 2 0
      desk/libs/thirdparty/oled_ssd1327/i2c.c
  18. 745 0
      desk/modules/terminal/terminal.cpp
  19. 161 0
      desk/modules/terminal/terminal.h
  20. 173 0
      desk/modules/terminal/terminal_usartbridge.cpp
  21. 86 0
      desk/modules/terminal/terminal_usartbridge.h
  22. 153 0
      desk/modules/terminal/terminal_usbbridge.cpp
  23. 48 0
      desk/modules/terminal/terminal_usbbridge.h
  24. 167 0
      desk/modules/terminal/terminal_user.cpp
  25. 41 0
      desk/modules/terminal/terminal_user.h
  26. 171 171
      desk/user/FreeRTOSConfig.h
  27. 105 0
      desk/user/MicroRLConfig.h
  28. 26 0
      desk/user/hal_callback.cpp
  29. 6 0
      desk/user/hal_callback.h
  30. 22 17
      desk/user/main.cpp
  31. 2 2
      desk/user/stm32g4xx_hal_conf.h
  32. BIN
      project/ewarm/desk/Debug/Exe/desk.out
  33. BIN
      project/ewarm/desk/Debug/Exe/desk.sim
  34. 716 480
      project/ewarm/desk/Debug/List/desk.map
  35. 416 351
      project/ewarm/desk/desk.dep
  36. 28 2
      project/ewarm/desk/desk.ewp
  37. 27 3
      project/ewarm/desk/desk.ewt
  38. 14 14
      project/ewarm/desk/settings/desk.dnx
  39. 11 11
      project/ewarm/robot/robot.dep
  40. 684 0
      thirdparty_libs/microrl/microrl.c
  41. 128 0
      thirdparty_libs/microrl/microrl.h

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
cube_example/usb_hid_example/.mxproject


+ 7 - 38
cube_example/usb_hid_example/Core/Inc/FreeRTOSConfig.h

@@ -53,31 +53,24 @@
   extern uint32_t SystemCoreClock;
   void xPortSysTickHandler(void);
 #endif
-#ifndef CMSIS_device_header
-#define CMSIS_device_header "stm32g4xx.h"
-#endif /* CMSIS_device_header */
-
 #define configENABLE_FPU                         0
 #define configENABLE_MPU                         0
 
 #define configUSE_PREEMPTION                     1
-#define configSUPPORT_STATIC_ALLOCATION          1
+#define configSUPPORT_STATIC_ALLOCATION          0
 #define configSUPPORT_DYNAMIC_ALLOCATION         1
 #define configUSE_IDLE_HOOK                      0
 #define configUSE_TICK_HOOK                      0
 #define configCPU_CLOCK_HZ                       ( SystemCoreClock )
 #define configTICK_RATE_HZ                       ((TickType_t)1000)
-#define configMAX_PRIORITIES                     ( 56 )
+#define configMAX_PRIORITIES                     ( 7 )
 #define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
 #define configTOTAL_HEAP_SIZE                    ((size_t)3072)
 #define configMAX_TASK_NAME_LEN                  ( 16 )
-#define configUSE_TRACE_FACILITY                 1
 #define configUSE_16_BIT_TICKS                   0
 #define configUSE_MUTEXES                        1
 #define configQUEUE_REGISTRY_SIZE                8
-#define configUSE_RECURSIVE_MUTEXES              1
-#define configUSE_COUNTING_SEMAPHORES            1
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION  1
 /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
 /* Defaults to size_t for backward compatibility, but can be changed
    if lengths will always be less than the number of bytes in a size_t. */
@@ -88,20 +81,6 @@
 #define configUSE_CO_ROUTINES                    0
 #define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )
 
-/* Software timer definitions. */
-#define configUSE_TIMERS                         1
-#define configTIMER_TASK_PRIORITY                ( 2 )
-#define configTIMER_QUEUE_LENGTH                 10
-#define configTIMER_TASK_STACK_DEPTH             256
-
-/* CMSIS-RTOS V2 flags */
-#define configUSE_OS2_THREAD_SUSPEND_RESUME  1
-#define configUSE_OS2_THREAD_ENUMERATE       1
-#define configUSE_OS2_EVENTFLAGS_FROM_ISR    1
-#define configUSE_OS2_THREAD_FLAGS           1
-#define configUSE_OS2_TIMER                  1
-#define configUSE_OS2_MUTEX                  1
-
 /* Set the following definitions to 1 to include the API function, or zero
 to exclude the API function. */
 #define INCLUDE_vTaskPrioritySet             1
@@ -109,20 +88,9 @@ to exclude the API function. */
 #define INCLUDE_vTaskDelete                  1
 #define INCLUDE_vTaskCleanUpResources        0
 #define INCLUDE_vTaskSuspend                 1
-#define INCLUDE_vTaskDelayUntil              1
+#define INCLUDE_vTaskDelayUntil              0
 #define INCLUDE_vTaskDelay                   1
 #define INCLUDE_xTaskGetSchedulerState       1
-#define INCLUDE_xTimerPendFunctionCall       1
-#define INCLUDE_xQueueGetMutexHolder         1
-#define INCLUDE_uxTaskGetStackHighWaterMark  1
-#define INCLUDE_xTaskGetCurrentTaskHandle    1
-#define INCLUDE_eTaskGetState                1
-
-/*
- * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
- * by the application thus the correct define need to be enabled below
- */
-#define USE_FreeRTOS_HEAP_4
 
 /* Cortex-M specific definitions. */
 #ifdef __NVIC_PRIO_BITS
@@ -160,9 +128,10 @@ standard names. */
 #define vPortSVCHandler    SVC_Handler
 #define xPortPendSVHandler PendSV_Handler
 
-/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
+/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
+              to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
 
-#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1
+/* #define xPortSysTickHandler SysTick_Handler */
 
 /* USER CODE BEGIN Defines */
 /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */

+ 16 - 0
cube_example/usb_hid_example/Core/Inc/main.h

@@ -57,6 +57,22 @@ void Error_Handler(void);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
+#define Encoder_button_Pin GPIO_PIN_4
+#define Encoder_button_GPIO_Port GPIOA
+#define Reset_screen_Pin GPIO_PIN_5
+#define Reset_screen_GPIO_Port GPIOA
+#define DC_screen_Pin GPIO_PIN_6
+#define DC_screen_GPIO_Port GPIOA
+#define CS_screen_Pin GPIO_PIN_7
+#define CS_screen_GPIO_Port GPIOA
+#define DC_Screen_Pin GPIO_PIN_0
+#define DC_Screen_GPIO_Port GPIOB
+#define Reset_Screen_Pin GPIO_PIN_1
+#define Reset_Screen_GPIO_Port GPIOB
+#define Beeper_Pin GPIO_PIN_2
+#define Beeper_GPIO_Port GPIOB
+#define Board_Blue_LED_Pin GPIO_PIN_6
+#define Board_Blue_LED_GPIO_Port GPIOC
 
 /* USER CODE BEGIN Private defines */
 

+ 3 - 3
cube_example/usb_hid_example/Core/Inc/stm32g4xx_hal_conf.h

@@ -47,7 +47,7 @@
 /*#define HAL_HRTIM_MODULE_ENABLED   */
 /*#define HAL_IRDA_MODULE_ENABLED   */
 /*#define HAL_IWDG_MODULE_ENABLED   */
-/*#define HAL_I2C_MODULE_ENABLED   */
+#define HAL_I2C_MODULE_ENABLED
 /*#define HAL_I2S_MODULE_ENABLED   */
 /*#define HAL_LPTIM_MODULE_ENABLED   */
 /*#define HAL_NAND_MODULE_ENABLED   */
@@ -62,8 +62,8 @@
 /*#define HAL_SMBUS_MODULE_ENABLED   */
 /*#define HAL_SPI_MODULE_ENABLED   */
 /*#define HAL_SRAM_MODULE_ENABLED   */
-/*#define HAL_TIM_MODULE_ENABLED   */
-/*#define HAL_UART_MODULE_ENABLED   */
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
 /*#define HAL_USART_MODULE_ENABLED   */
 /*#define HAL_WWDG_MODULE_ENABLED   */
 #define HAL_GPIO_MODULE_ENABLED

+ 1 - 1
cube_example/usb_hid_example/Core/Inc/stm32g4xx_it.h

@@ -22,7 +22,7 @@
 #define __STM32G4xx_IT_H
 
 #ifdef __cplusplus
- extern "C" {
+extern "C" {
 #endif
 
 /* Private includes ----------------------------------------------------------*/

+ 558 - 339
cube_example/usb_hid_example/Core/Src/main.c

@@ -1,339 +1,558 @@
-/* USER CODE BEGIN Header */
-/**
-  ******************************************************************************
-  * @file           : main.c
-  * @brief          : Main program body
-  ******************************************************************************
-  * @attention
-  *
-  * Copyright (c) 2025 STMicroelectronics.
-  * All rights reserved.
-  *
-  * This software is licensed under terms that can be found in the LICENSE file
-  * in the root directory of this software component.
-  * If no LICENSE file comes with this software, it is provided AS-IS.
-  *
-  ******************************************************************************
-  */
-/* USER CODE END Header */
-/* Includes ------------------------------------------------------------------*/
-#include "main.h"
-#include "cmsis_os.h"
-#include "usb_device.h"
-#include "custom_hid_test.h"    
-
-/* Private includes ----------------------------------------------------------*/
-/* USER CODE BEGIN Includes */
-extern USBD_HandleTypeDef hUsbDeviceFS; 
-
-/* USER CODE END Includes */
-
-/* Private typedef -----------------------------------------------------------*/
-/* USER CODE BEGIN PTD */
-
-/* USER CODE END PTD */
-
-/* Private define ------------------------------------------------------------*/
-/* USER CODE BEGIN PD */
-
-/* USER CODE END PD */
-
-/* Private macro -------------------------------------------------------------*/
-/* USER CODE BEGIN PM */
-
-/* USER CODE END PM */
-
-/* Private variables ---------------------------------------------------------*/
-RTC_HandleTypeDef hrtc;
-
-/* Definitions for defaultTask */
-osThreadId_t defaultTaskHandle;
-const osThreadAttr_t defaultTask_attributes = {
-  .name = "defaultTask",
-  .priority = (osPriority_t) osPriorityNormal,
-  .stack_size = 128 * 4
-};
-/* USER CODE BEGIN PV */
-
-/* USER CODE END PV */
-
-/* Private function prototypes -----------------------------------------------*/
-void SystemClock_Config(void);
-static void MX_GPIO_Init(void);
-static void MX_RTC_Init(void);
-void StartDefaultTask(void *argument);
-
-/* USER CODE BEGIN PFP */
-
-/* USER CODE END PFP */
-
-/* Private user code ---------------------------------------------------------*/
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
-/**
-  * @brief  The application entry point.
-  * @retval int
-  */
-int main(void)
-{
-
-  /* USER CODE BEGIN 1 */
-
-  /* USER CODE END 1 */
-
-  /* MCU Configuration--------------------------------------------------------*/
-
-  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
-  HAL_Init();
-
-  /* USER CODE BEGIN Init */
-
-  /* USER CODE END Init */
-
-  /* Configure the system clock */
-  SystemClock_Config();
-
-  /* USER CODE BEGIN SysInit */
-
-  /* USER CODE END SysInit */
-
-  /* Initialize all configured peripherals */
-  MX_GPIO_Init();
-  MX_RTC_Init();
-  /* USER CODE BEGIN 2 */
-
-  /* USER CODE END 2 */
-
-  /* Init scheduler */
-  osKernelInitialize();
-
-  /* USER CODE BEGIN RTOS_MUTEX */
-  /* add mutexes, ... */
-  /* USER CODE END RTOS_MUTEX */
-
-  /* USER CODE BEGIN RTOS_SEMAPHORES */
-  /* add semaphores, ... */
-  /* USER CODE END RTOS_SEMAPHORES */
-
-  /* USER CODE BEGIN RTOS_TIMERS */
-  /* start timers, add new ones, ... */
-  /* USER CODE END RTOS_TIMERS */
-
-  /* USER CODE BEGIN RTOS_QUEUES */
-  /* add queues, ... */
-  /* USER CODE END RTOS_QUEUES */
-
-  /* Create the thread(s) */
-  /* creation of defaultTask */
-  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
-
-  
-  usb_test_init();
-  
-  /* USER CODE BEGIN RTOS_THREADS */
-  /* add threads, ... */
-  /* USER CODE END RTOS_THREADS */
-
-  /* USER CODE BEGIN RTOS_EVENTS */
-  /* add events, ... */
-  /* USER CODE END RTOS_EVENTS */
-
-  /* Start scheduler */
-  osKernelStart();
-
-  /* We should never get here as control is now taken by the scheduler */
-
-  /* Infinite loop */
-  /* USER CODE BEGIN WHILE */
-  while (1)
-  {
-    /* USER CODE END WHILE */
-
-    /* USER CODE BEGIN 3 */
-  }
-  /* USER CODE END 3 */
-}
-
-/**
-  * @brief System Clock Configuration
-  * @retval None
-  */
-void SystemClock_Config(void)
-{
-  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
-  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
-
-  /** Configure the main internal regulator output voltage
-  */
-  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
-
-  /** Configure LSE Drive Capability
-  */
-  HAL_PWR_EnableBkUpAccess();
-  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
-
-  /** Initializes the RCC Oscillators according to the specified parameters
-  * in the RCC_OscInitTypeDef structure.
-  */
-  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE
-                              |RCC_OSCILLATORTYPE_LSE;
-  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
-  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
-  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
-  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
-  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
-  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
-  RCC_OscInitStruct.PLL.PLLN = 85;
-  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
-  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
-  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
-  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
-  {
-    Error_Handler();
-  }
-
-  /** Initializes the CPU, AHB and APB buses clocks
-  */
-  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
-                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
-  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
-  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
-  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
-  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
-  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
-  {
-    Error_Handler();
-  }
-}
-
-/**
-  * @brief RTC Initialization Function
-  * @param None
-  * @retval None
-  */
-static void MX_RTC_Init(void)
-{
-
-  /* USER CODE BEGIN RTC_Init 0 */
-
-  /* USER CODE END RTC_Init 0 */
-
-  /* USER CODE BEGIN RTC_Init 1 */
-
-  /* USER CODE END RTC_Init 1 */
-
-  /** Initialize RTC Only
-  */
-  hrtc.Instance = RTC;
-  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
-  hrtc.Init.AsynchPrediv = 127;
-  hrtc.Init.SynchPrediv = 255;
-  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
-  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
-  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
-  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
-  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
-  if (HAL_RTC_Init(&hrtc) != HAL_OK)
-  {
-    Error_Handler();
-  }
-  /* USER CODE BEGIN RTC_Init 2 */
-
-  /* USER CODE END RTC_Init 2 */
-
-}
-
-/**
-  * @brief GPIO Initialization Function
-  * @param None
-  * @retval None
-  */
-static void MX_GPIO_Init(void)
-{
-  GPIO_InitTypeDef GPIO_InitStruct = {0};
-/* USER CODE BEGIN MX_GPIO_Init_1 */
-/* USER CODE END MX_GPIO_Init_1 */
-
-  /* GPIO Ports Clock Enable */
-  __HAL_RCC_GPIOC_CLK_ENABLE();
-  __HAL_RCC_GPIOF_CLK_ENABLE();
-  __HAL_RCC_GPIOA_CLK_ENABLE();
-
-  /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
-
-  /*Configure GPIO pin : PC13 */
-  GPIO_InitStruct.Pin = GPIO_PIN_13;
-  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-
-  /*Configure GPIO pin : PC6 */
-  GPIO_InitStruct.Pin = GPIO_PIN_6;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-
-/* USER CODE BEGIN MX_GPIO_Init_2 */
-/* USER CODE END MX_GPIO_Init_2 */
-}
-
-/* USER CODE BEGIN 4 */
-
-/* USER CODE END 4 */
-
-/* USER CODE BEGIN Header_StartDefaultTask */
-/**
-  * @brief  Function implementing the defaultTask thread.
-  * @param  argument: Not used
-  * @retval None
-  */
-/* USER CODE END Header_StartDefaultTask */
-void StartDefaultTask(void *argument)
-{
-  /* init code for USB_Device */
-  MX_USB_Device_Init();
-  /* USER CODE BEGIN 5 */
-  /* Infinite loop */
-  for(;;)
-  {
-    osDelay(1);
-  }
-  /* USER CODE END 5 */
-}
-
-/**
-  * @brief  This function is executed in case of error occurrence.
-  * @retval None
-  */
-void Error_Handler(void)
-{
-  /* USER CODE BEGIN Error_Handler_Debug */
-  /* User can add his own implementation to report the HAL error return state */
-  __disable_irq();
-  while (1)
-  {
-  }
-  /* USER CODE END Error_Handler_Debug */
-}
-
-#ifdef  USE_FULL_ASSERT
-/**
-  * @brief  Reports the name of the source file and the source line number
-  *         where the assert_param error has occurred.
-  * @param  file: pointer to the source file name
-  * @param  line: assert_param error line source number
-  * @retval None
-  */
-void assert_failed(uint8_t *file, uint32_t line)
-{
-  /* USER CODE BEGIN 6 */
-  /* User can add his own implementation to report the file name and line number,
-     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
-  /* USER CODE END 6 */
-}
-#endif /* USE_FULL_ASSERT */
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : main.c
+  * @brief          : Main program body
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2025 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "cmsis_os.h"
+#include "usb_device.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+extern USBD_HandleTypeDef hUsbDeviceFS; 
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+I2C_HandleTypeDef hi2c2;
+
+RTC_HandleTypeDef hrtc;
+
+TIM_HandleTypeDef htim2;
+
+UART_HandleTypeDef huart2;
+UART_HandleTypeDef huart3;
+
+osThreadId defaultTaskHandle;
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+void SystemClock_Config(void);
+static void MX_GPIO_Init(void);
+static void MX_RTC_Init(void);
+static void MX_I2C2_Init(void);
+static void MX_TIM2_Init(void);
+static void MX_USART2_UART_Init(void);
+static void MX_USART3_UART_Init(void);
+void StartDefaultTask(void const * argument);
+
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+  * @brief  The application entry point.
+  * @retval int
+  */
+int main(void)
+{
+
+  /* USER CODE BEGIN 1 */
+
+  /* USER CODE END 1 */
+
+  /* MCU Configuration--------------------------------------------------------*/
+
+  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+  HAL_Init();
+
+  /* USER CODE BEGIN Init */
+
+  /* USER CODE END Init */
+
+  /* Configure the system clock */
+  SystemClock_Config();
+
+  /* USER CODE BEGIN SysInit */
+
+  /* USER CODE END SysInit */
+
+  /* Initialize all configured peripherals */
+  MX_GPIO_Init();
+  MX_RTC_Init();
+  MX_I2C2_Init();
+  MX_TIM2_Init();
+  MX_USART2_UART_Init();
+  MX_USART3_UART_Init();
+  /* USER CODE BEGIN 2 */
+
+  /* USER CODE END 2 */
+
+  /* USER CODE BEGIN RTOS_MUTEX */
+  /* add mutexes, ... */
+  /* USER CODE END RTOS_MUTEX */
+
+  /* USER CODE BEGIN RTOS_SEMAPHORES */
+  /* add semaphores, ... */
+  /* USER CODE END RTOS_SEMAPHORES */
+
+  /* USER CODE BEGIN RTOS_TIMERS */
+  /* start timers, add new ones, ... */
+  /* USER CODE END RTOS_TIMERS */
+
+  /* USER CODE BEGIN RTOS_QUEUES */
+  /* add queues, ... */
+  /* USER CODE END RTOS_QUEUES */
+
+  /* Create the thread(s) */
+  /* definition and creation of defaultTask */
+  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
+  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
+
+  /* USER CODE BEGIN RTOS_THREADS */
+  /* add threads, ... */
+  /* USER CODE END RTOS_THREADS */
+
+  /* Start scheduler */
+  osKernelStart();
+
+  /* We should never get here as control is now taken by the scheduler */
+
+  /* Infinite loop */
+  /* USER CODE BEGIN WHILE */
+  while (1)
+  {
+    /* USER CODE END WHILE */
+
+    /* USER CODE BEGIN 3 */
+  }
+  /* USER CODE END 3 */
+}
+
+/**
+  * @brief System Clock Configuration
+  * @retval None
+  */
+void SystemClock_Config(void)
+{
+  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+  /** Configure the main internal regulator output voltage
+  */
+  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
+
+  /** Configure LSE Drive Capability
+  */
+  HAL_PWR_EnableBkUpAccess();
+  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
+
+  /** Initializes the RCC Oscillators according to the specified parameters
+  * in the RCC_OscInitTypeDef structure.
+  */
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE
+                              |RCC_OSCILLATORTYPE_LSE;
+  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
+  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
+  RCC_OscInitStruct.PLL.PLLN = 85;
+  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
+  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
+  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+  /** Initializes the CPU, AHB and APB buses clocks
+  */
+  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
+  {
+    Error_Handler();
+  }
+}
+
+/**
+  * @brief I2C2 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_I2C2_Init(void)
+{
+
+  /* USER CODE BEGIN I2C2_Init 0 */
+
+  /* USER CODE END I2C2_Init 0 */
+
+  /* USER CODE BEGIN I2C2_Init 1 */
+
+  /* USER CODE END I2C2_Init 1 */
+  hi2c2.Instance = I2C2;
+  hi2c2.Init.Timing = 0x40B285C2;
+  hi2c2.Init.OwnAddress1 = 0;
+  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+  hi2c2.Init.OwnAddress2 = 0;
+  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
+  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+  /** Configure Analogue filter
+  */
+  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+  /** Configure Digital filter
+  */
+  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN I2C2_Init 2 */
+
+  /* USER CODE END I2C2_Init 2 */
+
+}
+
+/**
+  * @brief RTC Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_RTC_Init(void)
+{
+
+  /* USER CODE BEGIN RTC_Init 0 */
+
+  /* USER CODE END RTC_Init 0 */
+
+  /* USER CODE BEGIN RTC_Init 1 */
+
+  /* USER CODE END RTC_Init 1 */
+
+  /** Initialize RTC Only
+  */
+  hrtc.Instance = RTC;
+  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
+  hrtc.Init.AsynchPrediv = 127;
+  hrtc.Init.SynchPrediv = 255;
+  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
+  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
+  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
+  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
+  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
+  if (HAL_RTC_Init(&hrtc) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN RTC_Init 2 */
+
+  /* USER CODE END RTC_Init 2 */
+
+}
+
+/**
+  * @brief TIM2 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_TIM2_Init(void)
+{
+
+  /* USER CODE BEGIN TIM2_Init 0 */
+
+  /* USER CODE END TIM2_Init 0 */
+
+  TIM_Encoder_InitTypeDef sConfig = {0};
+  TIM_MasterConfigTypeDef sMasterConfig = {0};
+
+  /* USER CODE BEGIN TIM2_Init 1 */
+
+  /* USER CODE END TIM2_Init 1 */
+  htim2.Instance = TIM2;
+  htim2.Init.Prescaler = 0;
+  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
+  htim2.Init.Period = 4294967295;
+  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
+  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
+  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
+  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
+  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
+  sConfig.IC1Filter = 0;
+  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
+  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
+  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
+  sConfig.IC2Filter = 0;
+  if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN TIM2_Init 2 */
+
+  /* USER CODE END TIM2_Init 2 */
+
+}
+
+/**
+  * @brief USART2 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_USART2_UART_Init(void)
+{
+
+  /* USER CODE BEGIN USART2_Init 0 */
+
+  /* USER CODE END USART2_Init 0 */
+
+  /* USER CODE BEGIN USART2_Init 1 */
+
+  /* USER CODE END USART2_Init 1 */
+  huart2.Instance = USART2;
+  huart2.Init.BaudRate = 115200;
+  huart2.Init.WordLength = UART_WORDLENGTH_8B;
+  huart2.Init.StopBits = UART_STOPBITS_1;
+  huart2.Init.Parity = UART_PARITY_NONE;
+  huart2.Init.Mode = UART_MODE_TX_RX;
+  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
+  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
+  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+  if (HAL_RS485Ex_Init(&huart2, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN USART2_Init 2 */
+
+  /* USER CODE END USART2_Init 2 */
+
+}
+
+/**
+  * @brief USART3 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_USART3_UART_Init(void)
+{
+
+  /* USER CODE BEGIN USART3_Init 0 */
+
+  /* USER CODE END USART3_Init 0 */
+
+  /* USER CODE BEGIN USART3_Init 1 */
+
+  /* USER CODE END USART3_Init 1 */
+  huart3.Instance = USART3;
+  huart3.Init.BaudRate = 115200;
+  huart3.Init.WordLength = UART_WORDLENGTH_8B;
+  huart3.Init.StopBits = UART_STOPBITS_1;
+  huart3.Init.Parity = UART_PARITY_NONE;
+  huart3.Init.Mode = UART_MODE_TX_RX;
+  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
+  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+  huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
+  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+  if (HAL_UART_Init(&huart3) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN USART3_Init 2 */
+
+  /* USER CODE END USART3_Init 2 */
+
+}
+
+/**
+  * @brief GPIO Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_GPIO_Init(void)
+{
+  GPIO_InitTypeDef GPIO_InitStruct = {0};
+  /* USER CODE BEGIN MX_GPIO_Init_1 */
+  /* USER CODE END MX_GPIO_Init_1 */
+
+  /* GPIO Ports Clock Enable */
+  __HAL_RCC_GPIOC_CLK_ENABLE();
+  __HAL_RCC_GPIOF_CLK_ENABLE();
+  __HAL_RCC_GPIOA_CLK_ENABLE();
+  __HAL_RCC_GPIOB_CLK_ENABLE();
+
+  /*Configure GPIO pin Output Level */
+  HAL_GPIO_WritePin(GPIOA, Reset_screen_Pin|DC_screen_Pin|CS_screen_Pin, GPIO_PIN_RESET);
+
+  /*Configure GPIO pin Output Level */
+  HAL_GPIO_WritePin(GPIOB, DC_Screen_Pin|Reset_Screen_Pin|Beeper_Pin, GPIO_PIN_RESET);
+
+  /*Configure GPIO pin Output Level */
+  HAL_GPIO_WritePin(Board_Blue_LED_GPIO_Port, Board_Blue_LED_Pin, GPIO_PIN_RESET);
+
+  /*Configure GPIO pin : PC13 */
+  GPIO_InitStruct.Pin = GPIO_PIN_13;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+  /*Configure GPIO pin : Encoder_button_Pin */
+  GPIO_InitStruct.Pin = Encoder_button_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(Encoder_button_GPIO_Port, &GPIO_InitStruct);
+
+  /*Configure GPIO pins : Reset_screen_Pin DC_screen_Pin CS_screen_Pin */
+  GPIO_InitStruct.Pin = Reset_screen_Pin|DC_screen_Pin|CS_screen_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+  /*Configure GPIO pins : DC_Screen_Pin Reset_Screen_Pin Beeper_Pin */
+  GPIO_InitStruct.Pin = DC_Screen_Pin|Reset_Screen_Pin|Beeper_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+  /*Configure GPIO pin : Board_Blue_LED_Pin */
+  GPIO_InitStruct.Pin = Board_Blue_LED_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(Board_Blue_LED_GPIO_Port, &GPIO_InitStruct);
+
+  /* USER CODE BEGIN MX_GPIO_Init_2 */
+  /* USER CODE END MX_GPIO_Init_2 */
+}
+
+/* USER CODE BEGIN 4 */
+
+/* USER CODE END 4 */
+
+/* USER CODE BEGIN Header_StartDefaultTask */
+/**
+  * @brief  Function implementing the defaultTask thread.
+  * @param  argument: Not used
+  * @retval None
+  */
+/* USER CODE END Header_StartDefaultTask */
+void StartDefaultTask(void const * argument)
+{
+  /* init code for USB_Device */
+  MX_USB_Device_Init();
+  /* USER CODE BEGIN 5 */
+  /* Infinite loop */
+  for(;;)
+  {
+    osDelay(1);
+  }
+  /* USER CODE END 5 */
+}
+
+/**
+  * @brief  This function is executed in case of error occurrence.
+  * @retval None
+  */
+void Error_Handler(void)
+{
+  /* USER CODE BEGIN Error_Handler_Debug */
+  /* User can add his own implementation to report the HAL error return state */
+  __disable_irq();
+  while (1)
+  {
+  }
+  /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef  USE_FULL_ASSERT
+/**
+  * @brief  Reports the name of the source file and the source line number
+  *         where the assert_param error has occurred.
+  * @param  file: pointer to the source file name
+  * @param  line: assert_param error line source number
+  * @retval None
+  */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+  /* USER CODE BEGIN 6 */
+  /* User can add his own implementation to report the file name and line number,
+     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+  /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */

+ 310 - 18
cube_example/usb_hid_example/Core/Src/stm32g4xx_hal_msp.c

@@ -84,19 +84,105 @@ void HAL_MspInit(void)
 }
 
 /**
-* @brief RTC MSP Initialization
-* This function configures the hardware resources used in this example
-* @param hrtc: RTC handle pointer
-* @retval None
-*/
+  * @brief I2C MSP Initialization
+  * This function configures the hardware resources used in this example
+  * @param hi2c: I2C handle pointer
+  * @retval None
+  */
+void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
+{
+  GPIO_InitTypeDef GPIO_InitStruct = {0};
+  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+  if(hi2c->Instance==I2C2)
+  {
+    /* USER CODE BEGIN I2C2_MspInit 0 */
+
+    /* USER CODE END I2C2_MspInit 0 */
+
+  /** Initializes the peripherals clocks
+  */
+    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
+    PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
+    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+    {
+      Error_Handler();
+    }
+
+    __HAL_RCC_GPIOC_CLK_ENABLE();
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    /**I2C2 GPIO Configuration
+    PC4     ------> I2C2_SCL
+    PA8     ------> I2C2_SDA
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_4;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
+    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_8;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+    /* Peripheral clock enable */
+    __HAL_RCC_I2C2_CLK_ENABLE();
+    /* USER CODE BEGIN I2C2_MspInit 1 */
+
+    /* USER CODE END I2C2_MspInit 1 */
+
+  }
+
+}
+
+/**
+  * @brief I2C MSP De-Initialization
+  * This function freeze the hardware resources used in this example
+  * @param hi2c: I2C handle pointer
+  * @retval None
+  */
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
+{
+  if(hi2c->Instance==I2C2)
+  {
+    /* USER CODE BEGIN I2C2_MspDeInit 0 */
+
+    /* USER CODE END I2C2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_I2C2_CLK_DISABLE();
+
+    /**I2C2 GPIO Configuration
+    PC4     ------> I2C2_SCL
+    PA8     ------> I2C2_SDA
+    */
+    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4);
+
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);
+
+    /* USER CODE BEGIN I2C2_MspDeInit 1 */
+
+    /* USER CODE END I2C2_MspDeInit 1 */
+  }
+
+}
+
+/**
+  * @brief RTC MSP Initialization
+  * This function configures the hardware resources used in this example
+  * @param hrtc: RTC handle pointer
+  * @retval None
+  */
 void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
 {
   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
   if(hrtc->Instance==RTC)
   {
-  /* USER CODE BEGIN RTC_MspInit 0 */
+    /* USER CODE BEGIN RTC_MspInit 0 */
 
-  /* USER CODE END RTC_MspInit 0 */
+    /* USER CODE END RTC_MspInit 0 */
 
   /** Initializes the peripherals clocks
   */
@@ -111,33 +197,239 @@ void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
     /* Peripheral clock enable */
     __HAL_RCC_RTC_ENABLE();
     __HAL_RCC_RTCAPB_CLK_ENABLE();
-  /* USER CODE BEGIN RTC_MspInit 1 */
+    /* USER CODE BEGIN RTC_MspInit 1 */
 
-  /* USER CODE END RTC_MspInit 1 */
+    /* USER CODE END RTC_MspInit 1 */
 
   }
 
 }
 
 /**
-* @brief RTC MSP De-Initialization
-* This function freeze the hardware resources used in this example
-* @param hrtc: RTC handle pointer
-* @retval None
-*/
+  * @brief RTC MSP De-Initialization
+  * This function freeze the hardware resources used in this example
+  * @param hrtc: RTC handle pointer
+  * @retval None
+  */
 void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
 {
   if(hrtc->Instance==RTC)
   {
-  /* USER CODE BEGIN RTC_MspDeInit 0 */
+    /* USER CODE BEGIN RTC_MspDeInit 0 */
 
-  /* USER CODE END RTC_MspDeInit 0 */
+    /* USER CODE END RTC_MspDeInit 0 */
     /* Peripheral clock disable */
     __HAL_RCC_RTC_DISABLE();
     __HAL_RCC_RTCAPB_CLK_DISABLE();
-  /* USER CODE BEGIN RTC_MspDeInit 1 */
+    /* USER CODE BEGIN RTC_MspDeInit 1 */
+
+    /* USER CODE END RTC_MspDeInit 1 */
+  }
+
+}
+
+/**
+  * @brief TIM_Encoder MSP Initialization
+  * This function configures the hardware resources used in this example
+  * @param htim_encoder: TIM_Encoder handle pointer
+  * @retval None
+  */
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder)
+{
+  GPIO_InitTypeDef GPIO_InitStruct = {0};
+  if(htim_encoder->Instance==TIM2)
+  {
+    /* USER CODE BEGIN TIM2_MspInit 0 */
+
+    /* USER CODE END TIM2_MspInit 0 */
+    /* Peripheral clock enable */
+    __HAL_RCC_TIM2_CLK_ENABLE();
+
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+    /**TIM2 GPIO Configuration
+    PA0     ------> TIM2_CH1
+    PB3     ------> TIM2_CH2
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_0;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_3;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+    /* USER CODE BEGIN TIM2_MspInit 1 */
+
+    /* USER CODE END TIM2_MspInit 1 */
+
+  }
+
+}
+
+/**
+  * @brief TIM_Encoder MSP De-Initialization
+  * This function freeze the hardware resources used in this example
+  * @param htim_encoder: TIM_Encoder handle pointer
+  * @retval None
+  */
+void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef* htim_encoder)
+{
+  if(htim_encoder->Instance==TIM2)
+  {
+    /* USER CODE BEGIN TIM2_MspDeInit 0 */
+
+    /* USER CODE END TIM2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_TIM2_CLK_DISABLE();
+
+    /**TIM2 GPIO Configuration
+    PA0     ------> TIM2_CH1
+    PB3     ------> TIM2_CH2
+    */
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
+
+    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3);
+
+    /* USER CODE BEGIN TIM2_MspDeInit 1 */
+
+    /* USER CODE END TIM2_MspDeInit 1 */
+  }
+
+}
+
+/**
+  * @brief UART MSP Initialization
+  * This function configures the hardware resources used in this example
+  * @param huart: UART handle pointer
+  * @retval None
+  */
+void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+  GPIO_InitTypeDef GPIO_InitStruct = {0};
+  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+  if(huart->Instance==USART2)
+  {
+    /* USER CODE BEGIN USART2_MspInit 0 */
+
+    /* USER CODE END USART2_MspInit 0 */
+
+  /** Initializes the peripherals clocks
+  */
+    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
+    PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
+    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+    {
+      Error_Handler();
+    }
+
+    /* Peripheral clock enable */
+    __HAL_RCC_USART2_CLK_ENABLE();
+
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    /**USART2 GPIO Configuration
+    PA1     ------> USART2_DE
+    PA2     ------> USART2_TX
+    PA3     ------> USART2_RX
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+    /* USER CODE BEGIN USART2_MspInit 1 */
+
+    /* USER CODE END USART2_MspInit 1 */
+  }
+  else if(huart->Instance==USART3)
+  {
+    /* USER CODE BEGIN USART3_MspInit 0 */
+
+    /* USER CODE END USART3_MspInit 0 */
+
+  /** Initializes the peripherals clocks
+  */
+    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
+    PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
+    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+    {
+      Error_Handler();
+    }
+
+    /* Peripheral clock enable */
+    __HAL_RCC_USART3_CLK_ENABLE();
+
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+    /**USART3 GPIO Configuration
+    PB10     ------> USART3_TX
+    PB11     ------> USART3_RX
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+    /* USER CODE BEGIN USART3_MspInit 1 */
+
+    /* USER CODE END USART3_MspInit 1 */
+  }
+
+}
+
+/**
+  * @brief UART MSP De-Initialization
+  * This function freeze the hardware resources used in this example
+  * @param huart: UART handle pointer
+  * @retval None
+  */
+void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+{
+  if(huart->Instance==USART2)
+  {
+    /* USER CODE BEGIN USART2_MspDeInit 0 */
+
+    /* USER CODE END USART2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_USART2_CLK_DISABLE();
+
+    /**USART2 GPIO Configuration
+    PA1     ------> USART2_DE
+    PA2     ------> USART2_TX
+    PA3     ------> USART2_RX
+    */
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
+
+    /* USER CODE BEGIN USART2_MspDeInit 1 */
+
+    /* USER CODE END USART2_MspDeInit 1 */
+  }
+  else if(huart->Instance==USART3)
+  {
+    /* USER CODE BEGIN USART3_MspDeInit 0 */
+
+    /* USER CODE END USART3_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_USART3_CLK_DISABLE();
+
+    /**USART3 GPIO Configuration
+    PB10     ------> USART3_TX
+    PB11     ------> USART3_RX
+    */
+    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
+
+    /* USER CODE BEGIN USART3_MspDeInit 1 */
 
-  /* USER CODE END RTC_MspDeInit 1 */
+    /* USER CODE END USART3_MspDeInit 1 */
   }
 
 }

+ 1263 - 1233
cube_example/usb_hid_example/Drivers/CMSIS/Device/ST/STM32G4xx/Include/stm32g411xb.h

@@ -1,1247 +1,1277 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project>
-    <fileVersion>3</fileVersion>
-    <configuration>
-        <name>usb_hid_example</name>
-        <toolchain>
-            <name>ARM</name>
-        </toolchain>
+  <fileVersion>3</fileVersion>
+  <configuration>
+    <name>usb_hid_example</name>
+    <toolchain>
+      <name>ARM</name>
+    </toolchain>
+    <debug>1</debug>
+    <settings>
+      <name>General</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <version>31</version>
+        <wantNonLocal>1</wantNonLocal>
         <debug>1</debug>
-        <settings>
-            <name>General</name>
-            <archiveVersion>3</archiveVersion>
-            <data>
-                <version>31</version>
-                <wantNonLocal>1</wantNonLocal>
-                <debug>1</debug>
-                <option>
-                    <name>ExePath</name>
-                    <state>usb_hid_example/Exe</state>
-                </option>
-                <option>
-                    <name>ObjPath</name>
-                    <state>usb_hid_example/Obj</state>
-                </option>
-                <option>
-                    <name>ListPath</name>
-                    <state>usb_hid_example/List</state>
-                </option>
-                <option>
-                    <name>GEndianMode</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>Input description</name>
-                    <state>Full formatting, without multibyte support.</state>
-                </option>
-                <option>
-                    <name>Output description</name>
-                    <state>Full formatting, without multibyte support.</state>
-                </option>
-                <option>
-                    <name>GOutputBinary</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OGCoreOrChip</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>GRuntimeLibSelect</name>
-                    <version>0</version>
-                    <state>2</state>
-                </option>
-                <option>
-                    <name>GRuntimeLibSelectSlave</name>
-                    <version>0</version>
-                    <state>2</state>
-                </option>
-                <option>
-                    <name>RTDescription</name>
-                    <state>Use the full configuration of the C/C++ runtime library. Full locale interface, C locale, file descriptor support, multibytes in printf and scanf, and hex floats in strtod.</state>
-                </option>
-                <option>
-                    <name>OGProductVersion</name>
-                    <state>5.10.0.159</state>
-                </option>
-                <option>
-                    <name>OGLastSavedByProductVersion</name>
-                    <state>8.40.1.21529</state>
-                </option>
-                <option>
-                    <name>GeneralEnableMisra</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GeneralMisraVerbose</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OGChipSelectEditMenu</name>
-                    <state>STM32G431C8	ST STM32G431C8</state>
-                </option>
-                <option>
-                    <name>GenLowLevelInterface</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>GEndianModeBE</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OGBufferedTerminalOutput</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GenStdoutInterface</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GeneralMisraRules98</name>
-                    <version>0</version>
-                    <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
-                </option>
-                <option>
-                    <name>GeneralMisraVer</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GeneralMisraRules04</name>
-                    <version>0</version>
-                    <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
-                </option>
-                <option>
-                    <name>RTConfigPath2</name>
-                    <state>$TOOLKIT_DIR$\inc\c\DLib_Config_Full.h</state>
-                </option>
-                <option>
-                    <name>GBECoreSlave</name>
-                    <version>27</version>
-                    <state>39</state>
-                </option>
-                <option>
-                    <name>OGUseCmsis</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OGUseCmsisDspLib</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GRuntimeLibThreads</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CoreVariant</name>
-                    <version>27</version>
-                    <state>39</state>
-                </option>
-                <option>
-                    <name>GFPUDeviceSlave</name>
-                    <state>STM32G431C8	ST STM32G431C8</state>
-                </option>
-                <option>
-                    <name>FPU2</name>
-                    <version>0</version>
-                    <state>4</state>
-                </option>
-                <option>
-                    <name>NrRegs</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>NEON</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GFPUCoreSlave2</name>
-                    <version>27</version>
-                    <state>39</state>
-                </option>
-                <option>
-                    <name>OGCMSISPackSelectDevice</name>
-                </option>
-                <option>
-                    <name>OgLibHeap</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OGLibAdditionalLocale</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OGPrintfVariant</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OGPrintfMultibyteSupport</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OGScanfVariant</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OGScanfMultibyteSupport</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>GenLocaleTags</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>GenLocaleDisplayOnly</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>DSPExtension</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>TrustZone</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>TrustZoneModes</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-            </data>
-        </settings>
-        <settings>
-            <name>ICCARM</name>
-            <archiveVersion>2</archiveVersion>
-            <data>
-                <version>35</version>
-                <wantNonLocal>1</wantNonLocal>
-                <debug>1</debug>
-                <option>
-                    <name>CCOptimizationNoSizeConstraints</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCDefines</name>
-                    <state>USE_HAL_DRIVER</state>
-                    <state>STM32G431xx</state>
-                </option>
-                <option>
-                    <name>CCPreprocFile</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCPreprocComments</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCPreprocLine</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCListCFile</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCListCMnemonics</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCListCMessages</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCListAssFile</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCListAssSource</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCEnableRemarks</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCDiagSuppress</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CCDiagRemark</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CCDiagWarning</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CCDiagError</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CCObjPrefix</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCAllowList</name>
-                    <version>1</version>
-                    <state>11111110</state>
-                </option>
-                <option>
-                    <name>CCDebugInfo</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IEndianMode</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IProcessor</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IExtraOptionsCheck</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IExtraOptions</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CCLangConformance</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCSignedPlainChar</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCRequirePrototypes</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCDiagWarnAreErr</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCCompilerRuntimeInfo</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IFpuProcessor</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OutputFile</name>
-                    <state>$FILE_BNAME$.o</state>
-                </option>
-                <option>
-                    <name>CCLibConfigHeader</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>PreInclude</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CompilerMisraOverride</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCIncludePath2</name>
-                    <state>$PROJ_DIR$/../Core/Inc</state>
-                    <state>$PROJ_DIR$/../modules</state>
-                    <state>$PROJ_DIR$/../USB_Device/App</state>
-                    <state>$PROJ_DIR$/../USB_Device/Target</state>
-                    <state>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Inc</state>
-                    <state>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy</state>
-                    <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/include</state>
-                    <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2</state>
-                    <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/portable/IAR/ARM_CM4F</state>
-                    <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Core/Inc</state>
-                    <state>$PROJ_DIR$/../Drivers/CMSIS/Device/ST/STM32G4xx/Include</state>
-                    <state>$PROJ_DIR$/../Drivers/CMSIS/Include</state>
-                    <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc</state>
-                </option>
-                <option>
-                    <name>CCStdIncCheck</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCCodeSection</name>
-                    <state>.text</state>
-                </option>
-                <option>
-                    <name>IProcessorMode2</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCOptLevel</name>
-                    <state>3</state>
-                </option>
-                <option>
-                    <name>CCOptStrategy</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCOptLevelSlave</name>
-                    <state>3</state>
-                </option>
-                <option>
-                    <name>CompilerMisraRules98</name>
-                    <version>0</version>
-                    <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
-                </option>
-                <option>
-                    <name>CompilerMisraRules04</name>
-                    <version>0</version>
-                    <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
-                </option>
-                <option>
-                    <name>CCPosIndRopi</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCPosIndRwpi</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCPosIndNoDynInit</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IccLang</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IccCDialect</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IccAllowVLA</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IccStaticDestr</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IccCppInlineSemantics</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IccCmsis</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IccFloatSemantics</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCNoLiteralPool</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCOptStrategySlave</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCGuardCalls</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCEncSource</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCEncOutput</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CCEncOutputBom</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CCEncInput</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IccExceptions2</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IccRTTI2</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OICompilerExtraOption</name>
-                    <state>1</state>
-                </option>
-            </data>
-        </settings>
-        <settings>
-            <name>AARM</name>
-            <archiveVersion>2</archiveVersion>
-            <data>
-                <version>10</version>
-                <wantNonLocal>1</wantNonLocal>
-                <debug>1</debug>
-                <option>
-                    <name>AObjPrefix</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>AEndian</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>ACaseSensitivity</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>MacroChars</name>
-                    <version>0</version>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AWarnEnable</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AWarnWhat</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AWarnOne</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>AWarnRange1</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>AWarnRange2</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>ADebug</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>AltRegisterNames</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>ADefines</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>AList</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AListHeader</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>AListing</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>Includes</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>MacDefs</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>MacExps</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>MacExec</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>OnlyAssed</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>MultiLine</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>PageLengthCheck</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>PageLength</name>
-                    <state>80</state>
-                </option>
-                <option>
-                    <name>TabSpacing</name>
-                    <state>8</state>
-                </option>
-                <option>
-                    <name>AXRef</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AXRefDefines</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AXRefInternal</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AXRefDual</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AProcessor</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>AFpuProcessor</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>AOutputFile</name>
-                    <state>$FILE_BNAME$.o</state>
-                </option>
-                <option>
-                    <name>ALimitErrorsCheck</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>ALimitErrorsEdit</name>
-                    <state>100</state>
-                </option>
-                <option>
-                    <name>AIgnoreStdInclude</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AUserIncludes</name>
-                    <state>$PROJ_DIR$/../Core/Inc</state>
-                </option>
-                <option>
-                    <name>AExtraOptionsCheckV2</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>AExtraOptionsV2</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>AsmNoLiteralPool</name>
-                    <state>0</state>
-                </option>
-            </data>
-        </settings>
-        <settings>
-            <name>OBJCOPY</name>
-            <archiveVersion>0</archiveVersion>
-            <data>
-                <version>1</version>
-                <wantNonLocal>1</wantNonLocal>
-                <debug>1</debug>
-                <option>
-                    <name>OOCOutputFormat</name>
-                    <version>3</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OCOutputOverride</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OOCOutputFile</name>
-                    <state>usb_hid_example.hex</state>
-                </option>
-                <option>
-                    <name>OOCCommandLineProducer</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>OOCObjCopyEnable</name>
-                    <state>1</state>
-                </option>
-            </data>
-        </settings>
-        <settings>
-            <name>CUSTOM</name>
-            <archiveVersion>3</archiveVersion>
-            <data>
-                <extensions></extensions>
-                <cmdline></cmdline>
-                <hasPrio>0</hasPrio>
-            </data>
-        </settings>
-        <settings>
-            <name>BICOMP</name>
-            <archiveVersion>0</archiveVersion>
-            <data />
-        </settings>
-        <settings>
-            <name>BUILDACTION</name>
-            <archiveVersion>1</archiveVersion>
-            <data>
-                <prebuild></prebuild>
-                <postbuild></postbuild>
-            </data>
-        </settings>
-        <settings>
-            <name>ILINK</name>
-            <archiveVersion>0</archiveVersion>
-            <data>
-                <version>23</version>
-                <wantNonLocal>1</wantNonLocal>
-                <debug>1</debug>
-                <option>
-                    <name>IlinkOutputFile</name>
-                    <state>usb_hid_example.out</state>
-                </option>
-                <option>
-                    <name>IlinkLibIOConfig</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>XLinkMisraHandler</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkInputFileSlave</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkDebugInfoEnable</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkKeepSymbols</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinaryFile</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinarySymbol</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinarySegment</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinaryAlign</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkDefines</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkConfigDefines</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkMapFile</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkLogFile</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogInitialization</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogModule</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogSection</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogVeneer</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkIcfOverride</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkIcfFile</name>
-                    <state>$PROJ_DIR$/stm32g431xx_flash.icf</state>
-                </option>
-                <option>
-                    <name>IlinkIcfFileSlave</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkEnableRemarks</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkSuppressDiags</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkTreatAsRem</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkTreatAsWarn</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkTreatAsErr</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkWarningsAreErrors</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkUseExtraOptions</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkExtraOptions</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkLowLevelInterfaceSlave</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkAutoLibEnable</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkAdditionalLibs</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkOverrideProgramEntryLabel</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkProgramEntryLabelSelect</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkProgramEntryLabel</name>
-                    <state>__iar_program_start</state>
-                </option>
-                <option>
-                    <name>DoFill</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>FillerByte</name>
-                    <state>0xFF</state>
-                </option>
-                <option>
-                    <name>FillerStart</name>
-                    <state>0x0</state>
-                </option>
-                <option>
-                    <name>FillerEnd</name>
-                    <state>0x0</state>
-                </option>
-                <option>
-                    <name>CrcSize</name>
-                    <version>0</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CrcAlign</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CrcPoly</name>
-                    <state>0x11021</state>
-                </option>
-                <option>
-                    <name>CrcCompl</name>
-                    <version>0</version>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CrcBitOrder</name>
-                    <version>0</version>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>CrcInitialValue</name>
-                    <state>0x0</state>
-                </option>
-                <option>
-                    <name>DoCrc</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkBE8Slave</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkBufferedTerminalOutput</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkStdoutInterfaceSlave</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CrcFullSize</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkIElfToolPostProcess</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogAutoLibSelect</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogRedirSymbols</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkLogUnusedFragments</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkCrcReverseByteOrder</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkCrcUseAsInput</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkOptInline</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkOptExceptionsAllow</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkOptExceptionsForce</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkCmsis</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkOptMergeDuplSections</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkOptUseVfe</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkOptForceVfe</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkStackAnalysisEnable</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkStackControlFile</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkStackCallGraphFile</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>CrcAlgorithm</name>
-                    <version>1</version>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>CrcUnitSize</name>
-                    <version>0</version>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkThreadsSlave</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkLogCallGraph</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkIcfFile_AltDefault</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkEncInput</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkEncOutput</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IlinkEncOutputBom</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkHeapSelect</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkLocaleSelect</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkTrustzoneImportLibraryOut</name>
-                    <state>usb_hid_example_import_lib.o</state>
-                </option>
-                <option>
-                    <name>OILinkExtraOption</name>
-                    <state>1</state>
-                </option>
-                <option>
-                    <name>IlinkRawBinaryFile2</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinarySymbol2</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinarySegment2</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IlinkRawBinaryAlign2</name>
-                    <state></state>
-                </option>
-            </data>
-        </settings>
-        <settings>
-            <name>IARCHIVE</name>
-            <archiveVersion>0</archiveVersion>
-            <data>
-                <version>0</version>
-                <wantNonLocal>1</wantNonLocal>
-                <debug>1</debug>
-                <option>
-                    <name>IarchiveInputs</name>
-                    <state></state>
-                </option>
-                <option>
-                    <name>IarchiveOverride</name>
-                    <state>0</state>
-                </option>
-                <option>
-                    <name>IarchiveOutput</name>
-                    <state>###Unitialized###</state>
-                </option>
-            </data>
-        </settings>
-        <settings>
-            <name>BILINK</name>
-            <archiveVersion>0</archiveVersion>
-            <data />
-        </settings>
-        <settings>
-            <name>Coder</name>
-            <archiveVersion>0</archiveVersion>
-            <data />
-        </settings>
-    </configuration>
+        <option>
+          <name>ExePath</name>
+          <state>usb_hid_example/Exe</state>
+        </option>
+        <option>
+          <name>ObjPath</name>
+          <state>usb_hid_example/Obj</state>
+        </option>
+        <option>
+          <name>ListPath</name>
+          <state>usb_hid_example/List</state>
+        </option>
+        <option>
+          <name>GEndianMode</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input description</name>
+          <state>Full formatting, without multibyte support.</state>
+        </option>
+        <option>
+          <name>Output description</name>
+          <state>Full formatting, without multibyte support.</state>
+        </option>
+        <option>
+          <name>GOutputBinary</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGCoreOrChip</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelect</name>
+          <version>0</version>
+          <state>2</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelectSlave</name>
+          <version>0</version>
+          <state>2</state>
+        </option>
+        <option>
+          <name>RTDescription</name>
+          <state>Use the full configuration of the C/C++ runtime library. Full locale interface, C locale, file descriptor support, multibytes in printf and scanf, and hex floats in strtod.</state>
+        </option>
+        <option>
+          <name>OGProductVersion</name>
+          <state>5.10.0.159</state>
+        </option>
+        <option>
+          <name>OGLastSavedByProductVersion</name>
+          <state>8.40.1.21529</state>
+        </option>
+        <option>
+          <name>GeneralEnableMisra</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraVerbose</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGChipSelectEditMenu</name>
+          <state>STM32G431C8	ST STM32G431C8</state>
+        </option>
+        <option>
+          <name>GenLowLevelInterface</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GEndianModeBE</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGBufferedTerminalOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenStdoutInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>GeneralMisraVer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>RTConfigPath2</name>
+          <state>$TOOLKIT_DIR$\inc\c\DLib_Config_Full.h</state>
+        </option>
+        <option>
+          <name>GBECoreSlave</name>
+          <version>27</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>OGUseCmsis</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGUseCmsisDspLib</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GRuntimeLibThreads</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CoreVariant</name>
+          <version>27</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>GFPUDeviceSlave</name>
+          <state>STM32G431C8	ST STM32G431C8</state>
+        </option>
+        <option>
+          <name>FPU2</name>
+          <version>0</version>
+          <state>4</state>
+        </option>
+        <option>
+          <name>NrRegs</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>NEON</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GFPUCoreSlave2</name>
+          <version>27</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>OGCMSISPackSelectDevice</name>
+        </option>
+        <option>
+          <name>OgLibHeap</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGLibAdditionalLocale</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGPrintfVariant</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGPrintfMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGScanfVariant</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGScanfMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenLocaleTags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>GenLocaleDisplayOnly</name>
+          <state></state>
+        </option>
+        <option>
+          <name>DSPExtension</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>TrustZone</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>TrustZoneModes</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>ICCARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>35</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>CCOptimizationNoSizeConstraints</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDefines</name>
+          <state>USE_HAL_DRIVER</state>
+          <state>STM32G431xx</state>
+        </option>
+        <option>
+          <name>CCPreprocFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocComments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMnemonics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMessages</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagSuppress</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagRemark</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagWarning</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagError</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCAllowList</name>
+          <version>1</version>
+          <state>11111110</state>
+        </option>
+        <option>
+          <name>CCDebugInfo</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IEndianMode</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IExtraOptionsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLangConformance</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCSignedPlainChar</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCRequirePrototypes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagWarnAreErr</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCompilerRuntimeInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>CCLibConfigHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>PreInclude</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CompilerMisraOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCIncludePath2</name>
+          <state>$PROJ_DIR$/../Core/Inc</state>
+          <state>$PROJ_DIR$/../modules</state>
+          <state>$PROJ_DIR$/../USB_Device/App</state>
+          <state>$PROJ_DIR$/../USB_Device/Target</state>
+          <state>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Inc</state>
+          <state>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy</state>
+          <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/include</state>
+          <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/portable/IAR/ARM_CM4F</state>
+          <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Core/Inc</state>
+          <state>$PROJ_DIR$/../Drivers/CMSIS/Device/ST/STM32G4xx/Include</state>
+          <state>$PROJ_DIR$/../Drivers/CMSIS/Include</state>
+          <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc</state>
+          <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS</state>
+        </option>
+        <option>
+          <name>CCStdIncCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCodeSection</name>
+          <state>.text</state>
+        </option>
+        <option>
+          <name>IProcessorMode2</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevel</name>
+          <state>3</state>
+        </option>
+        <option>
+          <name>CCOptStrategy</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevelSlave</name>
+          <state>3</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>CCPosIndRopi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndRwpi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndNoDynInit</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccLang</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccAllowVLA</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccStaticDestr</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppInlineSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccFloatSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCNoLiteralPool</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategySlave</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCGuardCalls</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCEncSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEncOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEncOutputBom</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCEncInput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccExceptions2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccRTTI2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OICompilerExtraOption</name>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>AARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>10</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>AObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AEndian</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>ACaseSensitivity</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacroChars</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnWhat</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnOne</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange1</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>ADebug</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AltRegisterNames</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ADefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AList</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AListHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AListing</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Includes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacDefs</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacExps</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacExec</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OnlyAssed</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MultiLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLengthCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLength</name>
+          <state>80</state>
+        </option>
+        <option>
+          <name>TabSpacing</name>
+          <state>8</state>
+        </option>
+        <option>
+          <name>AXRef</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDefines</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefInternal</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDual</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AOutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>ALimitErrorsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsEdit</name>
+          <state>100</state>
+        </option>
+        <option>
+          <name>AIgnoreStdInclude</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AUserIncludes</name>
+          <state>$PROJ_DIR$/../Core/Inc</state>
+          <state>$PROJ_DIR$/../USB_Device/App</state>
+          <state>$PROJ_DIR$/../USB_Device/Target</state>
+          <state>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Inc</state>
+          <state>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy</state>
+          <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/include</state>
+          <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS</state>
+          <state>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/portable/IAR/ARM_CM4F</state>
+          <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Core/Inc</state>
+          <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc</state>
+          <state>$PROJ_DIR$/../Drivers/CMSIS/Device/ST/STM32G4xx/Include</state>
+          <state>$PROJ_DIR$/../Drivers/CMSIS/Include</state>
+        </option>
+        <option>
+          <name>AExtraOptionsCheckV2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AExtraOptionsV2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AsmNoLiteralPool</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>OBJCOPY</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>1</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>OOCOutputFormat</name>
+          <version>3</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OCOutputOverride</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCOutputFile</name>
+          <state>usb_hid_example.hex</state>
+        </option>
+        <option>
+          <name>OOCCommandLineProducer</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCObjCopyEnable</name>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>CUSTOM</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <extensions></extensions>
+        <cmdline></cmdline>
+        <hasPrio>0</hasPrio>
+      </data>
+    </settings>
+    <settings>
+      <name>BICOMP</name>
+      <archiveVersion>0</archiveVersion>
+      <data></data>
+    </settings>
+    <settings>
+      <name>BUILDACTION</name>
+      <archiveVersion>1</archiveVersion>
+      <data>
+        <prebuild></prebuild>
+        <postbuild></postbuild>
+      </data>
+    </settings>
+    <settings>
+      <name>ILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>23</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IlinkOutputFile</name>
+          <state>usb_hid_example.out</state>
+        </option>
+        <option>
+          <name>IlinkLibIOConfig</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>XLinkMisraHandler</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkInputFileSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkDebugInfoEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkKeepSymbols</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkConfigDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkMapFile</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLogFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogInitialization</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogModule</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogSection</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogVeneer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfOverride</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile</name>
+          <state>$PROJ_DIR$/stm32g431xx_flash.icf</state>
+        </option>
+        <option>
+          <name>IlinkIcfFileSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkSuppressDiags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsRem</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsWarn</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsErr</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkWarningsAreErrors</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkUseExtraOptions</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkLowLevelInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAutoLibEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAdditionalLibs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkOverrideProgramEntryLabel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabelSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabel</name>
+          <state>__iar_program_start</state>
+        </option>
+        <option>
+          <name>DoFill</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FillerByte</name>
+          <state>0xFF</state>
+        </option>
+        <option>
+          <name>FillerStart</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>FillerEnd</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>CrcSize</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcAlign</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcPoly</name>
+          <state>0x11021</state>
+        </option>
+        <option>
+          <name>CrcCompl</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcBitOrder</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcInitialValue</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>DoCrc</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkBE8Slave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkBufferedTerminalOutput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkStdoutInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcFullSize</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIElfToolPostProcess</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogAutoLibSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogRedirSymbols</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogUnusedFragments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcReverseByteOrder</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcUseAsInput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptInline</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsAllow</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsForce</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptMergeDuplSections</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptUseVfe</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptForceVfe</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackAnalysisEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackControlFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkStackCallGraphFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CrcAlgorithm</name>
+          <version>1</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcUnitSize</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkThreadsSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLogCallGraph</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile_AltDefault</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEncInput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkEncOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkEncOutputBom</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkHeapSelect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLocaleSelect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkTrustzoneImportLibraryOut</name>
+          <state>usb_hid_example_import_lib.o</state>
+        </option>
+        <option>
+          <name>OILinkExtraOption</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign2</name>
+          <state></state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>IARCHIVE</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>0</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IarchiveInputs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IarchiveOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IarchiveOutput</name>
+          <state>###Unitialized###</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>BILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data></data>
+    </settings>
+    <settings>
+      <name>Coder</name>
+      <archiveVersion>0</archiveVersion>
+      <data></data>
+    </settings>
+  </configuration>
+  <group>
+    <name>Application</name>
     <group>
-        <name>Application</name>
-        <group>
-            <name>EWARM</name>
-            <file>
-                <name>$PROJ_DIR$\startup_stm32g431xx.s</name>
-            </file>
-        </group>
-        <group>
-            <name>User</name>
-            <group>
-                <name>Core</name>
-                <file>
-                    <name>$PROJ_DIR$\..\Core\Src\app_freertos.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\Core\Src\main.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\Core\Src\stm32g4xx_hal_msp.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\Core\Src\stm32g4xx_it.c</name>
-                </file>
-            </group>
-            <group>
-                <name>modules</name>
-                <file>
-                    <name>$PROJ_DIR$\..\modules\custom_hid_test.c</name>
-                </file>
-            </group>
-            <group>
-                <name>USB_Device</name>
-                <group>
-                    <name>App</name>
-                    <file>
-                        <name>$PROJ_DIR$\..\USB_Device\App\usb_device.c</name>
-                    </file>
-                    <file>
-                        <name>$PROJ_DIR$\..\USB_Device\App\usbd_custom_hid_if.c</name>
-                    </file>
-                    <file>
-                        <name>$PROJ_DIR$\..\USB_Device\App\usbd_desc.c</name>
-                    </file>
-                </group>
-                <group>
-                    <name>Target</name>
-                    <file>
-                        <name>$PROJ_DIR$\..\USB_Device\Target\usbd_conf.c</name>
-                    </file>
-                </group>
-            </group>
-        </group>
+      <name>EWARM</name>
+      <file>
+        <name>$PROJ_DIR$\startup_stm32g431xx.s</name>
+      </file>
     </group>
     <group>
-        <name>Drivers</name>
+      <name>User</name>
+      <group>
+        <name>Core</name>
+        <file>
+          <name>$PROJ_DIR$\..\Core\Src\main.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\Core\Src\app_freertos.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\Core\Src\stm32g4xx_it.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\Core\Src\stm32g4xx_hal_msp.c</name>
+        </file>
+      </group>
+      <group>
+        <name>modules</name>
+        <file>
+          <name>$PROJ_DIR$\..\modules\custom_hid_test.c</name>
+        </file>
+      </group>
+      <group>
+        <name>USB_Device</name>
         <group>
-            <name>CMSIS</name>
-            <file>
-                <name>$PROJ_DIR$\..\Core\Src\system_stm32g4xx.c</name>
-            </file>
+          <name>App</name>
+          <file>
+            <name>$PROJ_DIR$\..\USB_Device\App\usb_device.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\USB_Device\App\usbd_desc.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\USB_Device\App\usbd_custom_hid_if.c</name>
+          </file>
         </group>
         <group>
-            <name>STM32G4xx_HAL_Driver</name>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pcd.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pcd_ex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rtc.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rtc_ex.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_usb.c</name>
-            </file>
+          <name>Target</name>
+          <file>
+            <name>$PROJ_DIR$\..\USB_Device\Target\usbd_conf.c</name>
+          </file>
         </group>
+      </group>
     </group>
+  </group>
+  <group>
+    <name>Drivers</name>
     <group>
-        <name>Middlewares</name>
-        <group>
-            <name>FreeRTOS</name>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS_V2\cmsis_os2.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\list.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\portable\IAR\ARM_CM4F\port.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\portable\IAR\ARM_CM4F\portasm.s</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\queue.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\timers.c</name>
-            </file>
-        </group>
-        <group>
-            <name>USB_Device_Library</name>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_core.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ctlreq.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Class\CustomHID\Src\usbd_customhid.c</name>
-            </file>
-            <file>
-                <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ioreq.c</name>
-            </file>
-        </group>
+      <name>CMSIS</name>
+      <file>
+        <name>$PROJ_DIR$\..\Core\Src\system_stm32g4xx.c</name>
+      </file>
+    </group>
+    <group>
+      <name>STM32G4xx_HAL_Driver</name>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pcd.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pcd_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_usb.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_i2c.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_i2c_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rtc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rtc_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c</name>
+      </file>
+    </group>
+  </group>
+  <group>
+    <name>Middlewares</name>
+    <group>
+      <name>FreeRTOS</name>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\croutine.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\event_groups.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\list.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\queue.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\stream_buffer.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\tasks.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\timers.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$/../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\portable\MemMang\heap_4.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\portable\IAR\ARM_CM4F\port.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\Third_Party\FreeRTOS\Source\portable\IAR\ARM_CM4F\portasm.s</name>
+      </file>
+    </group>
+    <group>
+      <name>USB_Device_Library</name>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_core.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ctlreq.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ioreq.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\Middlewares\ST\STM32_USB_Device_Library\Class\CustomHID\Src\usbd_customhid.c</name>
+      </file>
     </group>
+  </group>
 </project>
+

+ 170 - 171
cube_example/usb_hid_example/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h

@@ -1,171 +1,170 @@
-/**
-  ******************************************************************************
-  * @file    usbd_customhid.h
-  * @author  MCD Application Team
-  * @brief   header file for the usbd_customhid.c file.
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under Ultimate Liberty license
-  * SLA0044, the "License"; You may not use this file except in compliance with
-  * the License. You may obtain a copy of the License at:
-  *                      www.st.com/SLA0044
-  *
-  ******************************************************************************
-  */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __USB_CUSTOMHID_H
-#define __USB_CUSTOMHID_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include  "usbd_ioreq.h"
-
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-/** @defgroup USBD_CUSTOM_HID
-  * @brief This file is the Header file for USBD_customhid.c
-  * @{
-  */
-
-
-/** @defgroup USBD_CUSTOM_HID_Exported_Defines
-  * @{
-  */
-#define CUSTOM_HID_EPIN_ADDR                         0x81U
-
-#ifndef CUSTOM_HID_EPIN_SIZE
-#define CUSTOM_HID_EPIN_SIZE                         0x40U
-#endif
-
-#define CUSTOM_HID_EPOUT_ADDR                        0x01U
-
-#ifndef CUSTOM_HID_EPOUT_SIZE
-#define CUSTOM_HID_EPOUT_SIZE                        0x40U
-#endif
-
-#define USB_CUSTOM_HID_CONFIG_DESC_SIZ               41U
-#define USB_CUSTOM_HID_DESC_SIZ                      9U
-
-#ifndef CUSTOM_HID_HS_BINTERVAL
-#define CUSTOM_HID_HS_BINTERVAL                      0x05U
-#endif /* CUSTOM_HID_HS_BINTERVAL */
-
-#ifndef CUSTOM_HID_FS_BINTERVAL
-#define CUSTOM_HID_FS_BINTERVAL                      0x05U
-#endif /* CUSTOM_HID_FS_BINTERVAL */
-
-#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
-#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE            0x02U
-#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */
-
-#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
-#define USBD_CUSTOM_HID_REPORT_DESC_SIZE             163U
-#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */
-
-#define CUSTOM_HID_DESCRIPTOR_TYPE                   0x21U
-#define CUSTOM_HID_REPORT_DESC                       0x22U
-
-#define CUSTOM_HID_REQ_SET_PROTOCOL                  0x0BU
-#define CUSTOM_HID_REQ_GET_PROTOCOL                  0x03U
-
-#define CUSTOM_HID_REQ_SET_IDLE                      0x0AU
-#define CUSTOM_HID_REQ_GET_IDLE                      0x02U
-
-#define CUSTOM_HID_REQ_SET_REPORT                    0x09U
-#define CUSTOM_HID_REQ_GET_REPORT                    0x01U
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_CORE_Exported_TypesDefinitions
-  * @{
-  */
-typedef enum
-{
-  CUSTOM_HID_IDLE = 0U,
-  CUSTOM_HID_BUSY,
-} CUSTOM_HID_StateTypeDef;
-
-typedef struct _USBD_CUSTOM_HID_Itf
-{
-  uint8_t *pReport;
-  int8_t (* Init)(void);
-  int8_t (* DeInit)(void);
-  int8_t (* OutEvent)(uint8_t *state);
-  //int8_t (* OutEvent)(uint8_t event_idx, uint8_t state);
-
-} USBD_CUSTOM_HID_ItfTypeDef;
-
-typedef struct
-{
-  uint8_t  Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
-  uint32_t Protocol;
-  uint32_t IdleState;
-  uint32_t AltSetting;
-  uint32_t IsReportAvailable;
-  CUSTOM_HID_StateTypeDef state;
-} USBD_CUSTOM_HID_HandleTypeDef;
-/**
-  * @}
-  */
-
-
-
-/** @defgroup USBD_CORE_Exported_Macros
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CORE_Exported_Variables
-  * @{
-  */
-
-extern USBD_ClassTypeDef USBD_CUSTOM_HID;
-#define USBD_CUSTOM_HID_CLASS &USBD_CUSTOM_HID
-/**
-  * @}
-  */
-
-/** @defgroup USB_CORE_Exported_Functions
-  * @{
-  */
-uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
-                                   uint8_t *report, uint16_t len);
-
-uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
-
-uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
-                                          USBD_CUSTOM_HID_ItfTypeDef *fops);
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* __USB_CUSTOMHID_H */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+/**
+  ******************************************************************************
+  * @file    usbd_customhid.h
+  * @author  MCD Application Team
+  * @brief   header file for the usbd_customhid.c file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                      www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CUSTOMHID_H
+#define __USB_CUSTOMHID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBD_CUSTOM_HID
+  * @brief This file is the Header file for USBD_customhid.c
+  * @{
+  */
+
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Defines
+  * @{
+  */
+#define CUSTOM_HID_EPIN_ADDR                         0x81U
+
+#ifndef CUSTOM_HID_EPIN_SIZE
+#define CUSTOM_HID_EPIN_SIZE                         0x02U
+#endif
+
+#define CUSTOM_HID_EPOUT_ADDR                        0x01U
+
+#ifndef CUSTOM_HID_EPOUT_SIZE
+#define CUSTOM_HID_EPOUT_SIZE                        0x02U
+#endif
+
+#define USB_CUSTOM_HID_CONFIG_DESC_SIZ               41U
+#define USB_CUSTOM_HID_DESC_SIZ                      9U
+
+#ifndef CUSTOM_HID_HS_BINTERVAL
+#define CUSTOM_HID_HS_BINTERVAL                      0x05U
+#endif /* CUSTOM_HID_HS_BINTERVAL */
+
+#ifndef CUSTOM_HID_FS_BINTERVAL
+#define CUSTOM_HID_FS_BINTERVAL                      0x05U
+#endif /* CUSTOM_HID_FS_BINTERVAL */
+
+#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
+#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE            0x02U
+#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */
+
+#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
+#define USBD_CUSTOM_HID_REPORT_DESC_SIZE             163U
+#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */
+
+#define CUSTOM_HID_DESCRIPTOR_TYPE                   0x21U
+#define CUSTOM_HID_REPORT_DESC                       0x22U
+
+#define CUSTOM_HID_REQ_SET_PROTOCOL                  0x0BU
+#define CUSTOM_HID_REQ_GET_PROTOCOL                  0x03U
+
+#define CUSTOM_HID_REQ_SET_IDLE                      0x0AU
+#define CUSTOM_HID_REQ_GET_IDLE                      0x02U
+
+#define CUSTOM_HID_REQ_SET_REPORT                    0x09U
+#define CUSTOM_HID_REQ_GET_REPORT                    0x01U
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+  * @{
+  */
+typedef enum
+{
+  CUSTOM_HID_IDLE = 0U,
+  CUSTOM_HID_BUSY,
+} CUSTOM_HID_StateTypeDef;
+
+typedef struct _USBD_CUSTOM_HID_Itf
+{
+  uint8_t *pReport;
+  int8_t (* Init)(void);
+  int8_t (* DeInit)(void);
+  int8_t (* OutEvent)(uint8_t event_idx, uint8_t state);
+
+} USBD_CUSTOM_HID_ItfTypeDef;
+
+typedef struct
+{
+  uint8_t  Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
+  uint32_t Protocol;
+  uint32_t IdleState;
+  uint32_t AltSetting;
+  uint32_t IsReportAvailable;
+  CUSTOM_HID_StateTypeDef state;
+} USBD_CUSTOM_HID_HandleTypeDef;
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CORE_Exported_Variables
+  * @{
+  */
+
+extern USBD_ClassTypeDef USBD_CUSTOM_HID;
+#define USBD_CUSTOM_HID_CLASS &USBD_CUSTOM_HID
+/**
+  * @}
+  */
+
+/** @defgroup USB_CORE_Exported_Functions
+  * @{
+  */
+uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
+                                   uint8_t *report, uint16_t len);
+
+uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
+
+uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
+                                          USBD_CUSTOM_HID_ItfTypeDef *fops);
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __USB_CUSTOMHID_H */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 781 - 806
cube_example/usb_hid_example/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c

@@ -1,806 +1,781 @@
-/**
-  ******************************************************************************
-  * @file    usbd_customhid.c
-  * @author  MCD Application Team
-  * @brief   This file provides the CUSTOM_HID core functions.
-  *
-  * @verbatim
-  *
-  *          ===================================================================
-  *                                CUSTOM_HID Class  Description
-  *          ===================================================================
-  *           This module manages the CUSTOM_HID class V1.11 following the "Device Class Definition
-  *           for Human Interface Devices (CUSTOM_HID) Version 1.11 Jun 27, 2001".
-  *           This driver implements the following aspects of the specification:
-  *             - The Boot Interface Subclass
-  *             - Usage Page : Generic Desktop
-  *             - Usage : Vendor
-  *             - Collection : Application
-  *
-  * @note     In HS mode and when the DMA is used, all variables and data structures
-  *           dealing with the DMA during the transaction process should be 32-bit aligned.
-  *
-  *
-  *  @endverbatim
-  *
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under Ultimate Liberty license
-  * SLA0044, the "License"; You may not use this file except in compliance with
-  * the License. You may obtain a copy of the License at:
-  *                      www.st.com/SLA0044
-  *
-  ******************************************************************************
-  */
-
-/* BSPDependencies
-- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
-- "stm32xxxxx_{eval}{discovery}_io.c"
-EndBSPDependencies */
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_customhid.h"
-#include "usbd_ctlreq.h"
-
-
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-
-/** @defgroup USBD_CUSTOM_HID
-  * @brief usbd core module
-  * @{
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_CUSTOM_HID_Private_Defines
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_CUSTOM_HID_Private_Macros
-  * @{
-  */
-/**
-  * @}
-  */
-/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes
-  * @{
-  */
-
-static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
-static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
-static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
-
-static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
-static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
-static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef  *pdev);
-
-static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length);
-static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length);
-static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length);
-static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length);
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_Variables
-  * @{
-  */
-
-USBD_ClassTypeDef  USBD_CUSTOM_HID =
-{
-  USBD_CUSTOM_HID_Init,
-  USBD_CUSTOM_HID_DeInit,
-  USBD_CUSTOM_HID_Setup,
-  NULL, /*EP0_TxSent*/
-  USBD_CUSTOM_HID_EP0_RxReady, /*EP0_RxReady*/ /* STATUS STAGE IN */
-  USBD_CUSTOM_HID_DataIn, /*DataIn*/
-  USBD_CUSTOM_HID_DataOut,
-  NULL, /*SOF */
-  NULL,
-  NULL,
-  USBD_CUSTOM_HID_GetHSCfgDesc,
-  USBD_CUSTOM_HID_GetFSCfgDesc,
-  USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
-  USBD_CUSTOM_HID_GetDeviceQualifierDesc,
-};
-
-/* USB CUSTOM_HID device FS Configuration Descriptor */
-__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
-{
-  0x09,                                               /* bLength: Configuration Descriptor size */
-  USB_DESC_TYPE_CONFIGURATION,                        /* bDescriptorType: Configuration */
-  USB_CUSTOM_HID_CONFIG_DESC_SIZ,                     /* wTotalLength: Bytes returned */
-  0x00,
-  0x01,                                               /* bNumInterfaces: 1 interface */
-  0x01,                                               /* bConfigurationValue: Configuration value */
-  0x00,                                               /* iConfiguration: Index of string descriptor describing the configuration */
-#if (USBD_SELF_POWERED == 1U)
-  0xC0,                                               /* bmAttributes: Bus Powered according to user configuration */
-#else
-  0x80,                                               /* bmAttributes: Bus Powered according to user configuration */
-#endif
-  USBD_MAX_POWER,                                     /* MaxPower 100 mA: this current is used for detecting Vbus */
-
-  /************** Descriptor of CUSTOM HID interface ****************/
-  /* 09 */
-  0x09,                                               /* bLength: Interface Descriptor size*/
-  USB_DESC_TYPE_INTERFACE,                            /* bDescriptorType: Interface descriptor type */
-  0x00,                                               /* bInterfaceNumber: Number of Interface */
-  0x00,                                               /* bAlternateSetting: Alternate setting */
-  0x02,                                               /* bNumEndpoints*/
-  0x03,                                               /* bInterfaceClass: CUSTOM_HID */
-  0x00,                                               /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-  0x00,                                               /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-  0x00,                                               /* iInterface: Index of string descriptor */
-  /******************** Descriptor of CUSTOM_HID *************************/
-  /* 18 */
-  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
-  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
-  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
-  0x01,
-  0x00,                                               /* bCountryCode: Hardware target country */
-  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
-  0x22,                                               /* bDescriptorType */
-  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
-  0x00,
-  /******************** Descriptor of Custom HID endpoints ********************/
-  /* 27 */
-  0x07,                                               /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
-
-  CUSTOM_HID_EPIN_ADDR,                               /* bEndpointAddress: Endpoint Address (IN) */
-  0x03,                                               /* bmAttributes: Interrupt endpoint */
-  CUSTOM_HID_EPIN_SIZE,                               /* wMaxPacketSize: 2 Byte max */
-  0x00,
-  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
-  /* 34 */
-
-  0x07,                                               /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
-  CUSTOM_HID_EPOUT_ADDR,                              /* bEndpointAddress: Endpoint Address (OUT) */
-  0x03,                                               /* bmAttributes: Interrupt endpoint */
-  CUSTOM_HID_EPOUT_SIZE,                              /* wMaxPacketSize: 2 Bytes max  */
-  0x00,
-  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
-  /* 41 */
-};
-
-/* USB CUSTOM_HID device HS Configuration Descriptor */
-__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
-{
-  0x09,                                               /* bLength: Configuration Descriptor size */
-  USB_DESC_TYPE_CONFIGURATION,                        /* bDescriptorType: Configuration */
-  USB_CUSTOM_HID_CONFIG_DESC_SIZ,                     /* wTotalLength: Bytes returned */
-  0x00,
-  0x01,                                               /* bNumInterfaces: 1 interface */
-  0x01,                                               /* bConfigurationValue: Configuration value */
-  0x00,                                               /* iConfiguration: Index of string descriptor describing the configuration */
-#if (USBD_SELF_POWERED == 1U)
-  0xC0,                                               /* bmAttributes: Bus Powered according to user configuration */
-#else
-  0x80,                                               /* bmAttributes: Bus Powered according to user configuration */
-#endif
-  USBD_MAX_POWER,                                     /* MaxPower 100 mA: this current is used for detecting Vbus */
-
-  /************** Descriptor of CUSTOM HID interface ****************/
-  /* 09 */
-  0x09,                                               /* bLength: Interface Descriptor size */
-  USB_DESC_TYPE_INTERFACE,                            /* bDescriptorType: Interface descriptor type */
-  0x00,                                               /* bInterfaceNumber: Number of Interface */
-  0x00,                                               /* bAlternateSetting: Alternate setting */
-  0x02,                                               /* bNumEndpoints */
-  0x03,                                               /* bInterfaceClass: CUSTOM_HID */
-  0x00,                                               /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-  0x00,                                               /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-  0,                                                  /* iInterface: Index of string descriptor */
-  /******************** Descriptor of CUSTOM_HID *************************/
-  /* 18 */
-  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
-  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
-  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
-  0x01,
-  0x00,                                               /* bCountryCode: Hardware target country */
-  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
-  0x22,                                               /* bDescriptorType */
-  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
-  0x00,
-  /******************** Descriptor of Custom HID endpoints ********************/
-  /* 27 */
-  0x07,                                               /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
-
-  CUSTOM_HID_EPIN_ADDR,                               /* bEndpointAddress: Endpoint Address (IN) */
-  0x03,                                               /* bmAttributes: Interrupt endpoint */
-  CUSTOM_HID_EPIN_SIZE,                               /* wMaxPacketSize: 2 Byte max */
-  0x00,
-  CUSTOM_HID_HS_BINTERVAL,                            /* bInterval: Polling Interval */
-  /* 34 */
-
-  0x07,                                               /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
-  CUSTOM_HID_EPOUT_ADDR,                              /* bEndpointAddress: Endpoint Address (OUT) */
-  0x03,                                               /* bmAttributes: Interrupt endpoint */
-  CUSTOM_HID_EPOUT_SIZE,                              /* wMaxPacketSize: 2 Bytes max  */
-  0x00,
-  CUSTOM_HID_HS_BINTERVAL,                            /* bInterval: Polling Interval */
-  /* 41 */
-};
-
-/* USB CUSTOM_HID device Other Speed Configuration Descriptor */
-__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
-{
-  0x09,                                               /* bLength: Configuration Descriptor size */
-  USB_DESC_TYPE_CONFIGURATION,                        /* bDescriptorType: Configuration */
-  USB_CUSTOM_HID_CONFIG_DESC_SIZ,                     /* wTotalLength: Bytes returned */
-  0x00,
-  0x01,                                               /* bNumInterfaces: 1 interface */
-  0x01,                                               /* bConfigurationValue: Configuration value */
-  0x00,                                               /* iConfiguration: Index of string descriptor describing the configuration */
-#if (USBD_SELF_POWERED == 1U)
-  0xC0,                                               /* bmAttributes: Bus Powered according to user configuration */
-#else
-  0x80,                                               /* bmAttributes: Bus Powered according to user configuration */
-#endif
-  USBD_MAX_POWER,                                     /* MaxPower 100 mA: this current is used for detecting Vbus */
-
-  /************** Descriptor of CUSTOM HID interface ****************/
-  /* 09 */
-  0x09,                                               /* bLength: Interface Descriptor size */
-  USB_DESC_TYPE_INTERFACE,                            /* bDescriptorType: Interface descriptor type */
-  0x00,                                               /* bInterfaceNumber: Number of Interface */
-  0x00,                                               /* bAlternateSetting: Alternate setting */
-  0x02,                                               /* bNumEndpoints */
-  0x03,                                               /* bInterfaceClass: CUSTOM_HID */
-  0x00,                                               /* bInterfaceSubClass : 1=BOOT, 0=no boot */
-  0x00,                                               /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
-  0,                                                  /* iInterface: Index of string descriptor */
-  /******************** Descriptor of CUSTOM_HID *************************/
-  /* 18 */
-  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
-  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
-  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
-  0x01,
-  0x00,                                               /* bCountryCode: Hardware target country */
-  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
-  0x22,                                               /* bDescriptorType */
-  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
-  0x00,
-  /******************** Descriptor of Custom HID endpoints ********************/
-  /* 27 */
-  0x07,                                               /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
-
-  CUSTOM_HID_EPIN_ADDR,                               /* bEndpointAddress: Endpoint Address (IN) */
-  0x03,                                               /* bmAttributes: Interrupt endpoint */
-  CUSTOM_HID_EPIN_SIZE,                               /* wMaxPacketSize: 2 Bytes max */
-  0x00,
-  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
-  /* 34 */
-
-  0x07,                                               /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
-  CUSTOM_HID_EPOUT_ADDR,                              /* bEndpointAddress: Endpoint Address (OUT) */
-  0x03,                                               /* bmAttributes: Interrupt endpoint */
-  CUSTOM_HID_EPOUT_SIZE,                              /* wMaxPacketSize: 2 Bytes max */
-  0x00,
-  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
-  /* 41 */
-};
-
-/* USB CUSTOM_HID device Configuration Descriptor */
-__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
-{
-  /* 18 */
-  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
-  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
-  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
-  0x01,
-  0x00,                                               /* bCountryCode: Hardware target country */
-  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
-  0x22,                                               /* bDescriptorType */
-  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
-  0x00,
-};
-
-/* USB Standard Device Descriptor */
-__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
-{
-  USB_LEN_DEV_QUALIFIER_DESC,
-  USB_DESC_TYPE_DEVICE_QUALIFIER,
-  0x00,
-  0x02,
-  0x00,
-  0x00,
-  0x00,
-  0x40,
-  0x01,
-  0x00,
-};
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_Functions
-  * @{
-  */
-
-/**
-  * @brief  USBD_CUSTOM_HID_Init
-  *         Initialize the CUSTOM_HID interface
-  * @param  pdev: device instance
-  * @param  cfgidx: Configuration index
-  * @retval status
-  */
-static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
-{
-  UNUSED(cfgidx);
-  USBD_CUSTOM_HID_HandleTypeDef *hhid;
-
-  hhid = USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef));
-
-  if (hhid == NULL)
-  {
-    pdev->pClassData = NULL;
-    return (uint8_t)USBD_EMEM;
-  }
-
-  pdev->pClassData = (void *)hhid;
-
-  if (pdev->dev_speed == USBD_SPEED_HIGH)
-  {
-    pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
-    pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
-  }
-  else   /* LOW and FULL-speed endpoints */
-  {
-    pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
-    pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
-  }
-
-  /* Open EP IN */
-  (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR,
-                       CUSTOM_HID_EPIN_SIZE);
-
-  pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 1U;
-
-  /* Open EP OUT */
-  (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR,
-                       CUSTOM_HID_EPOUT_SIZE);
-
-  pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 1U;
-
-  hhid->state = CUSTOM_HID_IDLE;
-
-  ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init();
-
-  /* Prepare Out endpoint to receive 1st packet */
-  (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
-                               USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
-
-  return (uint8_t)USBD_OK;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_Init
-  *         DeInitialize the CUSTOM_HID layer
-  * @param  pdev: device instance
-  * @param  cfgidx: Configuration index
-  * @retval status
-  */
-static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
-{
-  UNUSED(cfgidx);
-
-  /* Close CUSTOM_HID EP IN */
-  (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPIN_ADDR);
-  pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 0U;
-  pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = 0U;
-
-  /* Close CUSTOM_HID EP OUT */
-  (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPOUT_ADDR);
-  pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 0U;
-  pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = 0U;
-
-  /* Free allocated memory */
-  if (pdev->pClassData != NULL)
-  {
-    ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit();
-    USBD_free(pdev->pClassData);
-    pdev->pClassData = NULL;
-  }
-
-  return (uint8_t)USBD_OK;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_Setup
-  *         Handle the CUSTOM_HID specific requests
-  * @param  pdev: instance
-  * @param  req: usb requests
-  * @retval status
-  */
-static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
-                                     USBD_SetupReqTypedef *req)
-{
-  USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-  uint16_t len = 0U;
-  uint8_t  *pbuf = NULL;
-  uint16_t status_info = 0U;
-  USBD_StatusTypeDef ret = USBD_OK;
-
-  if (hhid == NULL)
-  {
-    return (uint8_t)USBD_FAIL;
-  }
-
-  switch (req->bmRequest & USB_REQ_TYPE_MASK)
-  {
-    case USB_REQ_TYPE_CLASS:
-      switch (req->bRequest)
-      {
-        case CUSTOM_HID_REQ_SET_PROTOCOL:
-          hhid->Protocol = (uint8_t)(req->wValue);
-          break;
-
-        case CUSTOM_HID_REQ_GET_PROTOCOL:
-          (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
-          break;
-
-        case CUSTOM_HID_REQ_SET_IDLE:
-          hhid->IdleState = (uint8_t)(req->wValue >> 8);
-          break;
-
-        case CUSTOM_HID_REQ_GET_IDLE:
-          (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
-          break;
-
-        case CUSTOM_HID_REQ_SET_REPORT:
-          hhid->IsReportAvailable = 1U;
-          (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength);
-          break;
-
-        default:
-          USBD_CtlError(pdev, req);
-          ret = USBD_FAIL;
-          break;
-      }
-      break;
-
-    case USB_REQ_TYPE_STANDARD:
-      switch (req->bRequest)
-      {
-        case USB_REQ_GET_STATUS:
-          if (pdev->dev_state == USBD_STATE_CONFIGURED)
-          {
-            (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
-          }
-          else
-          {
-            USBD_CtlError(pdev, req);
-            ret = USBD_FAIL;
-          }
-          break;
-
-        case USB_REQ_GET_DESCRIPTOR:
-          if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC)
-          {
-            len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength);
-            pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport;
-          }
-          else
-          {
-            if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE)
-            {
-              pbuf = USBD_CUSTOM_HID_Desc;
-              len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength);
-            }
-          }
-
-          (void)USBD_CtlSendData(pdev, pbuf, len);
-          break;
-
-        case USB_REQ_GET_INTERFACE:
-          if (pdev->dev_state == USBD_STATE_CONFIGURED)
-          {
-            (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
-          }
-          else
-          {
-            USBD_CtlError(pdev, req);
-            ret = USBD_FAIL;
-          }
-          break;
-
-        case USB_REQ_SET_INTERFACE:
-          if (pdev->dev_state == USBD_STATE_CONFIGURED)
-          {
-            hhid->AltSetting = (uint8_t)(req->wValue);
-          }
-          else
-          {
-            USBD_CtlError(pdev, req);
-            ret = USBD_FAIL;
-          }
-          break;
-
-        case USB_REQ_CLEAR_FEATURE:
-          break;
-
-        default:
-          USBD_CtlError(pdev, req);
-          ret = USBD_FAIL;
-          break;
-      }
-      break;
-
-    default:
-      USBD_CtlError(pdev, req);
-      ret = USBD_FAIL;
-      break;
-  }
-  return (uint8_t)ret;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_SendReport
-  *         Send CUSTOM_HID Report
-  * @param  pdev: device instance
-  * @param  buff: pointer to report
-  * @retval status
-  */
-uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
-                                   uint8_t *report, uint16_t len)
-{
-  USBD_CUSTOM_HID_HandleTypeDef *hhid;
-
-  if (pdev->pClassData == NULL)
-  {
-    return (uint8_t)USBD_FAIL;
-  }
-
-  hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-
-  if (pdev->dev_state == USBD_STATE_CONFIGURED)
-  {
-    if (hhid->state == CUSTOM_HID_IDLE)
-    {
-      hhid->state = CUSTOM_HID_BUSY;
-      (void)USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len);
-    }
-    else
-    {
-      return (uint8_t)USBD_BUSY;
-    }
-  }
-  return (uint8_t)USBD_OK;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_GetFSCfgDesc
-  *         return FS configuration descriptor
-  * @param  speed : current device speed
-  * @param  length : pointer data length
-  * @retval pointer to descriptor buffer
-  */
-static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
-{
-  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgFSDesc);
-
-  return USBD_CUSTOM_HID_CfgFSDesc;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_GetHSCfgDesc
-  *         return HS configuration descriptor
-  * @param  speed : current device speed
-  * @param  length : pointer data length
-  * @retval pointer to descriptor buffer
-  */
-static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length)
-{
-  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgHSDesc);
-
-  return USBD_CUSTOM_HID_CfgHSDesc;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_GetOtherSpeedCfgDesc
-  *         return other speed configuration descriptor
-  * @param  speed : current device speed
-  * @param  length : pointer data length
-  * @retval pointer to descriptor buffer
-  */
-static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length)
-{
-  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc);
-
-  return USBD_CUSTOM_HID_OtherSpeedCfgDesc;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_DataIn
-  *         handle data IN Stage
-  * @param  pdev: device instance
-  * @param  epnum: endpoint index
-  * @retval status
-  */
-static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
-{
-  UNUSED(epnum);
-
-  /* Ensure that the FIFO is empty before a new transfer, this condition could
-  be caused by  a new transfer before the end of the previous transfer */
-  ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData)->state = CUSTOM_HID_IDLE;
-
-  return (uint8_t)USBD_OK;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_DataOut
-  *         handle data OUT Stage
-  * @param  pdev: device instance
-  * @param  epnum: endpoint index
-  * @retval status
-  */
-static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
-{
-#if 0  
-  UNUSED(epnum);
-  USBD_CUSTOM_HID_HandleTypeDef *hhid;
-
-  if (pdev->pClassData == NULL)
-  {
-    return (uint8_t)USBD_FAIL;
-  }
-
-  hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-
-  /* USB data will be immediately processed, this allow next USB traffic being
-  NAKed till the end of the application processing */
-  ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
-                                                            hhid->Report_buf[1]);
-
-  return (uint8_t)USBD_OK;
-#endif 
- 
-#if 1  
-  USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-
-  ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf);
-
-  USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
-                         USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
-
-  return USBD_OK;
-#endif  
-}
-
-
-/**
-  * @brief  USBD_CUSTOM_HID_ReceivePacket
-  *         prepare OUT Endpoint for reception
-  * @param  pdev: device instance
-  * @retval status
-  */
-uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
-{
-  USBD_CUSTOM_HID_HandleTypeDef *hhid;
-
-  if (pdev->pClassData == NULL)
-  {
-    return (uint8_t)USBD_FAIL;
-  }
-
-  hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-
-  /* Resume USB Out process */
-  (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
-                               USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
-
-  return (uint8_t)USBD_OK;
-}
-
-
-/**
-  * @brief  USBD_CUSTOM_HID_EP0_RxReady
-  *         Handles control request data.
-  * @param  pdev: device instance
-  * @retval status
-  */
-static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
-{
-#if 0  
-  USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-
-  if (hhid == NULL)
-  {
-    return (uint8_t)USBD_FAIL;
-  }
-
-  if (hhid->IsReportAvailable == 1U)
-  {
-    ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
-                                                              hhid->Report_buf[1]);
-    hhid->IsReportAvailable = 0U;
-  }
-
-  return (uint8_t)USBD_OK;
-#endif
-
-      USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
-
-  if (hhid->IsReportAvailable == 1U)
-  {
-    ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf);
-    hhid->IsReportAvailable = 0U;
-  }
-
-  return USBD_OK;
-}
-
-/**
-  * @brief  DeviceQualifierDescriptor
-  *         return Device Qualifier descriptor
-  * @param  length : pointer data length
-  * @retval pointer to descriptor buffer
-  */
-static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length)
-{
-  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc);
-
-  return USBD_CUSTOM_HID_DeviceQualifierDesc;
-}
-
-/**
-  * @brief  USBD_CUSTOM_HID_RegisterInterface
-  * @param  pdev: device instance
-  * @param  fops: CUSTOMHID Interface callback
-  * @retval status
-  */
-uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
-                                          USBD_CUSTOM_HID_ItfTypeDef *fops)
-{
-  if (fops == NULL)
-  {
-    return (uint8_t)USBD_FAIL;
-  }
-
-  pdev->pUserData = fops;
-
-  return (uint8_t)USBD_OK;
-}
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+/**
+  ******************************************************************************
+  * @file    usbd_customhid.c
+  * @author  MCD Application Team
+  * @brief   This file provides the CUSTOM_HID core functions.
+  *
+  * @verbatim
+  *
+  *          ===================================================================
+  *                                CUSTOM_HID Class  Description
+  *          ===================================================================
+  *           This module manages the CUSTOM_HID class V1.11 following the "Device Class Definition
+  *           for Human Interface Devices (CUSTOM_HID) Version 1.11 Jun 27, 2001".
+  *           This driver implements the following aspects of the specification:
+  *             - The Boot Interface Subclass
+  *             - Usage Page : Generic Desktop
+  *             - Usage : Vendor
+  *             - Collection : Application
+  *
+  * @note     In HS mode and when the DMA is used, all variables and data structures
+  *           dealing with the DMA during the transaction process should be 32-bit aligned.
+  *
+  *
+  *  @endverbatim
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                      www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_customhid.h"
+#include "usbd_ctlreq.h"
+
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_CUSTOM_HID
+  * @brief usbd core module
+  * @{
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_CUSTOM_HID_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_CUSTOM_HID_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes
+  * @{
+  */
+
+static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+
+static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef  *pdev);
+
+static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length);
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Variables
+  * @{
+  */
+
+USBD_ClassTypeDef  USBD_CUSTOM_HID =
+{
+  USBD_CUSTOM_HID_Init,
+  USBD_CUSTOM_HID_DeInit,
+  USBD_CUSTOM_HID_Setup,
+  NULL, /*EP0_TxSent*/
+  USBD_CUSTOM_HID_EP0_RxReady, /*EP0_RxReady*/ /* STATUS STAGE IN */
+  USBD_CUSTOM_HID_DataIn, /*DataIn*/
+  USBD_CUSTOM_HID_DataOut,
+  NULL, /*SOF */
+  NULL,
+  NULL,
+  USBD_CUSTOM_HID_GetHSCfgDesc,
+  USBD_CUSTOM_HID_GetFSCfgDesc,
+  USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
+  USBD_CUSTOM_HID_GetDeviceQualifierDesc,
+};
+
+/* USB CUSTOM_HID device FS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+  0x09,                                               /* bLength: Configuration Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION,                        /* bDescriptorType: Configuration */
+  USB_CUSTOM_HID_CONFIG_DESC_SIZ,                     /* wTotalLength: Bytes returned */
+  0x00,
+  0x01,                                               /* bNumInterfaces: 1 interface */
+  0x01,                                               /* bConfigurationValue: Configuration value */
+  0x00,                                               /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+  0xC0,                                               /* bmAttributes: Bus Powered according to user configuration */
+#else
+  0x80,                                               /* bmAttributes: Bus Powered according to user configuration */
+#endif
+  USBD_MAX_POWER,                                     /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+  /************** Descriptor of CUSTOM HID interface ****************/
+  /* 09 */
+  0x09,                                               /* bLength: Interface Descriptor size*/
+  USB_DESC_TYPE_INTERFACE,                            /* bDescriptorType: Interface descriptor type */
+  0x00,                                               /* bInterfaceNumber: Number of Interface */
+  0x00,                                               /* bAlternateSetting: Alternate setting */
+  0x02,                                               /* bNumEndpoints*/
+  0x03,                                               /* bInterfaceClass: CUSTOM_HID */
+  0x00,                                               /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+  0x00,                                               /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+  0x00,                                               /* iInterface: Index of string descriptor */
+  /******************** Descriptor of CUSTOM_HID *************************/
+  /* 18 */
+  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
+  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
+  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+  0x01,
+  0x00,                                               /* bCountryCode: Hardware target country */
+  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+  0x22,                                               /* bDescriptorType */
+  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
+  0x00,
+  /******************** Descriptor of Custom HID endpoints ********************/
+  /* 27 */
+  0x07,                                               /* bLength: Endpoint Descriptor size */
+  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
+
+  CUSTOM_HID_EPIN_ADDR,                               /* bEndpointAddress: Endpoint Address (IN) */
+  0x03,                                               /* bmAttributes: Interrupt endpoint */
+  CUSTOM_HID_EPIN_SIZE,                               /* wMaxPacketSize: 2 Byte max */
+  0x00,
+  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
+  /* 34 */
+
+  0x07,                                               /* bLength: Endpoint Descriptor size */
+  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
+  CUSTOM_HID_EPOUT_ADDR,                              /* bEndpointAddress: Endpoint Address (OUT) */
+  0x03,                                               /* bmAttributes: Interrupt endpoint */
+  CUSTOM_HID_EPOUT_SIZE,                              /* wMaxPacketSize: 2 Bytes max  */
+  0x00,
+  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
+  /* 41 */
+};
+
+/* USB CUSTOM_HID device HS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+  0x09,                                               /* bLength: Configuration Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION,                        /* bDescriptorType: Configuration */
+  USB_CUSTOM_HID_CONFIG_DESC_SIZ,                     /* wTotalLength: Bytes returned */
+  0x00,
+  0x01,                                               /* bNumInterfaces: 1 interface */
+  0x01,                                               /* bConfigurationValue: Configuration value */
+  0x00,                                               /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+  0xC0,                                               /* bmAttributes: Bus Powered according to user configuration */
+#else
+  0x80,                                               /* bmAttributes: Bus Powered according to user configuration */
+#endif
+  USBD_MAX_POWER,                                     /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+  /************** Descriptor of CUSTOM HID interface ****************/
+  /* 09 */
+  0x09,                                               /* bLength: Interface Descriptor size */
+  USB_DESC_TYPE_INTERFACE,                            /* bDescriptorType: Interface descriptor type */
+  0x00,                                               /* bInterfaceNumber: Number of Interface */
+  0x00,                                               /* bAlternateSetting: Alternate setting */
+  0x02,                                               /* bNumEndpoints */
+  0x03,                                               /* bInterfaceClass: CUSTOM_HID */
+  0x00,                                               /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+  0x00,                                               /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+  0,                                                  /* iInterface: Index of string descriptor */
+  /******************** Descriptor of CUSTOM_HID *************************/
+  /* 18 */
+  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
+  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
+  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+  0x01,
+  0x00,                                               /* bCountryCode: Hardware target country */
+  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+  0x22,                                               /* bDescriptorType */
+  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
+  0x00,
+  /******************** Descriptor of Custom HID endpoints ********************/
+  /* 27 */
+  0x07,                                               /* bLength: Endpoint Descriptor size */
+  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
+
+  CUSTOM_HID_EPIN_ADDR,                               /* bEndpointAddress: Endpoint Address (IN) */
+  0x03,                                               /* bmAttributes: Interrupt endpoint */
+  CUSTOM_HID_EPIN_SIZE,                               /* wMaxPacketSize: 2 Byte max */
+  0x00,
+  CUSTOM_HID_HS_BINTERVAL,                            /* bInterval: Polling Interval */
+  /* 34 */
+
+  0x07,                                               /* bLength: Endpoint Descriptor size */
+  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
+  CUSTOM_HID_EPOUT_ADDR,                              /* bEndpointAddress: Endpoint Address (OUT) */
+  0x03,                                               /* bmAttributes: Interrupt endpoint */
+  CUSTOM_HID_EPOUT_SIZE,                              /* wMaxPacketSize: 2 Bytes max  */
+  0x00,
+  CUSTOM_HID_HS_BINTERVAL,                            /* bInterval: Polling Interval */
+  /* 41 */
+};
+
+/* USB CUSTOM_HID device Other Speed Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+  0x09,                                               /* bLength: Configuration Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION,                        /* bDescriptorType: Configuration */
+  USB_CUSTOM_HID_CONFIG_DESC_SIZ,                     /* wTotalLength: Bytes returned */
+  0x00,
+  0x01,                                               /* bNumInterfaces: 1 interface */
+  0x01,                                               /* bConfigurationValue: Configuration value */
+  0x00,                                               /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+  0xC0,                                               /* bmAttributes: Bus Powered according to user configuration */
+#else
+  0x80,                                               /* bmAttributes: Bus Powered according to user configuration */
+#endif
+  USBD_MAX_POWER,                                     /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+  /************** Descriptor of CUSTOM HID interface ****************/
+  /* 09 */
+  0x09,                                               /* bLength: Interface Descriptor size */
+  USB_DESC_TYPE_INTERFACE,                            /* bDescriptorType: Interface descriptor type */
+  0x00,                                               /* bInterfaceNumber: Number of Interface */
+  0x00,                                               /* bAlternateSetting: Alternate setting */
+  0x02,                                               /* bNumEndpoints */
+  0x03,                                               /* bInterfaceClass: CUSTOM_HID */
+  0x00,                                               /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+  0x00,                                               /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+  0,                                                  /* iInterface: Index of string descriptor */
+  /******************** Descriptor of CUSTOM_HID *************************/
+  /* 18 */
+  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
+  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
+  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+  0x01,
+  0x00,                                               /* bCountryCode: Hardware target country */
+  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+  0x22,                                               /* bDescriptorType */
+  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
+  0x00,
+  /******************** Descriptor of Custom HID endpoints ********************/
+  /* 27 */
+  0x07,                                               /* bLength: Endpoint Descriptor size */
+  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
+
+  CUSTOM_HID_EPIN_ADDR,                               /* bEndpointAddress: Endpoint Address (IN) */
+  0x03,                                               /* bmAttributes: Interrupt endpoint */
+  CUSTOM_HID_EPIN_SIZE,                               /* wMaxPacketSize: 2 Bytes max */
+  0x00,
+  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
+  /* 34 */
+
+  0x07,                                               /* bLength: Endpoint Descriptor size */
+  USB_DESC_TYPE_ENDPOINT,                             /* bDescriptorType: */
+  CUSTOM_HID_EPOUT_ADDR,                              /* bEndpointAddress: Endpoint Address (OUT) */
+  0x03,                                               /* bmAttributes: Interrupt endpoint */
+  CUSTOM_HID_EPOUT_SIZE,                              /* wMaxPacketSize: 2 Bytes max */
+  0x00,
+  CUSTOM_HID_FS_BINTERVAL,                            /* bInterval: Polling Interval */
+  /* 41 */
+};
+
+/* USB CUSTOM_HID device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
+{
+  /* 18 */
+  0x09,                                               /* bLength: CUSTOM_HID Descriptor size */
+  CUSTOM_HID_DESCRIPTOR_TYPE,                         /* bDescriptorType: CUSTOM_HID */
+  0x11,                                               /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+  0x01,
+  0x00,                                               /* bCountryCode: Hardware target country */
+  0x01,                                               /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+  0x22,                                               /* bDescriptorType */
+  USBD_CUSTOM_HID_REPORT_DESC_SIZE,                   /* wItemLength: Total length of Report descriptor */
+  0x00,
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+{
+  USB_LEN_DEV_QUALIFIER_DESC,
+  USB_DESC_TYPE_DEVICE_QUALIFIER,
+  0x00,
+  0x02,
+  0x00,
+  0x00,
+  0x00,
+  0x40,
+  0x01,
+  0x00,
+};
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  USBD_CUSTOM_HID_Init
+  *         Initialize the CUSTOM_HID interface
+  * @param  pdev: device instance
+  * @param  cfgidx: Configuration index
+  * @retval status
+  */
+static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+  UNUSED(cfgidx);
+  USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+  hhid = USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef));
+
+  if (hhid == NULL)
+  {
+    pdev->pClassData = NULL;
+    return (uint8_t)USBD_EMEM;
+  }
+
+  pdev->pClassData = (void *)hhid;
+
+  if (pdev->dev_speed == USBD_SPEED_HIGH)
+  {
+    pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
+    pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
+  }
+  else   /* LOW and FULL-speed endpoints */
+  {
+    pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
+    pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
+  }
+
+  /* Open EP IN */
+  (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPIN_ADDR, USBD_EP_TYPE_INTR,
+                       CUSTOM_HID_EPIN_SIZE);
+
+  pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 1U;
+
+  /* Open EP OUT */
+  (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_EPOUT_ADDR, USBD_EP_TYPE_INTR,
+                       CUSTOM_HID_EPOUT_SIZE);
+
+  pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 1U;
+
+  hhid->state = CUSTOM_HID_IDLE;
+
+  ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init();
+
+  /* Prepare Out endpoint to receive 1st packet */
+  (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
+                               USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
+
+  return (uint8_t)USBD_OK;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_Init
+  *         DeInitialize the CUSTOM_HID layer
+  * @param  pdev: device instance
+  * @param  cfgidx: Configuration index
+  * @retval status
+  */
+static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+  UNUSED(cfgidx);
+
+  /* Close CUSTOM_HID EP IN */
+  (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPIN_ADDR);
+  pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].is_used = 0U;
+  pdev->ep_in[CUSTOM_HID_EPIN_ADDR & 0xFU].bInterval = 0U;
+
+  /* Close CUSTOM_HID EP OUT */
+  (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_EPOUT_ADDR);
+  pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 0U;
+  pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = 0U;
+
+  /* Free allocated memory */
+  if (pdev->pClassData != NULL)
+  {
+    ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit();
+    USBD_free(pdev->pClassData);
+    pdev->pClassData = NULL;
+  }
+
+  return (uint8_t)USBD_OK;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_Setup
+  *         Handle the CUSTOM_HID specific requests
+  * @param  pdev: instance
+  * @param  req: usb requests
+  * @retval status
+  */
+static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
+                                     USBD_SetupReqTypedef *req)
+{
+  USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
+  uint16_t len = 0U;
+  uint8_t  *pbuf = NULL;
+  uint16_t status_info = 0U;
+  USBD_StatusTypeDef ret = USBD_OK;
+
+  if (hhid == NULL)
+  {
+    return (uint8_t)USBD_FAIL;
+  }
+
+  switch (req->bmRequest & USB_REQ_TYPE_MASK)
+  {
+    case USB_REQ_TYPE_CLASS:
+      switch (req->bRequest)
+      {
+        case CUSTOM_HID_REQ_SET_PROTOCOL:
+          hhid->Protocol = (uint8_t)(req->wValue);
+          break;
+
+        case CUSTOM_HID_REQ_GET_PROTOCOL:
+          (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
+          break;
+
+        case CUSTOM_HID_REQ_SET_IDLE:
+          hhid->IdleState = (uint8_t)(req->wValue >> 8);
+          break;
+
+        case CUSTOM_HID_REQ_GET_IDLE:
+          (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
+          break;
+
+        case CUSTOM_HID_REQ_SET_REPORT:
+          hhid->IsReportAvailable = 1U;
+          (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength);
+          break;
+
+        default:
+          USBD_CtlError(pdev, req);
+          ret = USBD_FAIL;
+          break;
+      }
+      break;
+
+    case USB_REQ_TYPE_STANDARD:
+      switch (req->bRequest)
+      {
+        case USB_REQ_GET_STATUS:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED)
+          {
+            (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case USB_REQ_GET_DESCRIPTOR:
+          if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC)
+          {
+            len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength);
+            pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport;
+          }
+          else
+          {
+            if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE)
+            {
+              pbuf = USBD_CUSTOM_HID_Desc;
+              len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength);
+            }
+          }
+
+          (void)USBD_CtlSendData(pdev, pbuf, len);
+          break;
+
+        case USB_REQ_GET_INTERFACE:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED)
+          {
+            (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case USB_REQ_SET_INTERFACE:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED)
+          {
+            hhid->AltSetting = (uint8_t)(req->wValue);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case USB_REQ_CLEAR_FEATURE:
+          break;
+
+        default:
+          USBD_CtlError(pdev, req);
+          ret = USBD_FAIL;
+          break;
+      }
+      break;
+
+    default:
+      USBD_CtlError(pdev, req);
+      ret = USBD_FAIL;
+      break;
+  }
+  return (uint8_t)ret;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_SendReport
+  *         Send CUSTOM_HID Report
+  * @param  pdev: device instance
+  * @param  buff: pointer to report
+  * @retval status
+  */
+uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
+                                   uint8_t *report, uint16_t len)
+{
+  USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+  if (pdev->pClassData == NULL)
+  {
+    return (uint8_t)USBD_FAIL;
+  }
+
+  hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
+
+  if (pdev->dev_state == USBD_STATE_CONFIGURED)
+  {
+    if (hhid->state == CUSTOM_HID_IDLE)
+    {
+      hhid->state = CUSTOM_HID_BUSY;
+      (void)USBD_LL_Transmit(pdev, CUSTOM_HID_EPIN_ADDR, report, len);
+    }
+    else
+    {
+      return (uint8_t)USBD_BUSY;
+    }
+  }
+  return (uint8_t)USBD_OK;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_GetFSCfgDesc
+  *         return FS configuration descriptor
+  * @param  speed : current device speed
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
+{
+  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgFSDesc);
+
+  return USBD_CUSTOM_HID_CfgFSDesc;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_GetHSCfgDesc
+  *         return HS configuration descriptor
+  * @param  speed : current device speed
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length)
+{
+  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgHSDesc);
+
+  return USBD_CUSTOM_HID_CfgHSDesc;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_GetOtherSpeedCfgDesc
+  *         return other speed configuration descriptor
+  * @param  speed : current device speed
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc);
+
+  return USBD_CUSTOM_HID_OtherSpeedCfgDesc;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_DataIn
+  *         handle data IN Stage
+  * @param  pdev: device instance
+  * @param  epnum: endpoint index
+  * @retval status
+  */
+static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+  UNUSED(epnum);
+
+  /* Ensure that the FIFO is empty before a new transfer, this condition could
+  be caused by  a new transfer before the end of the previous transfer */
+  ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData)->state = CUSTOM_HID_IDLE;
+
+  return (uint8_t)USBD_OK;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_DataOut
+  *         handle data OUT Stage
+  * @param  pdev: device instance
+  * @param  epnum: endpoint index
+  * @retval status
+  */
+static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+  UNUSED(epnum);
+  USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+  if (pdev->pClassData == NULL)
+  {
+    return (uint8_t)USBD_FAIL;
+  }
+
+  hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
+
+  /* USB data will be immediately processed, this allow next USB traffic being
+  NAKed till the end of the application processing */
+  ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
+                                                            hhid->Report_buf[1]);
+
+  return (uint8_t)USBD_OK;
+}
+
+
+/**
+  * @brief  USBD_CUSTOM_HID_ReceivePacket
+  *         prepare OUT Endpoint for reception
+  * @param  pdev: device instance
+  * @retval status
+  */
+uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
+{
+  USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+  if (pdev->pClassData == NULL)
+  {
+    return (uint8_t)USBD_FAIL;
+  }
+
+  hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
+
+  /* Resume USB Out process */
+  (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf,
+                               USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
+
+  return (uint8_t)USBD_OK;
+}
+
+
+/**
+  * @brief  USBD_CUSTOM_HID_EP0_RxReady
+  *         Handles control request data.
+  * @param  pdev: device instance
+  * @retval status
+  */
+static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+  USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData;
+
+  if (hhid == NULL)
+  {
+    return (uint8_t)USBD_FAIL;
+  }
+
+  if (hhid->IsReportAvailable == 1U)
+  {
+    ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],
+                                                              hhid->Report_buf[1]);
+    hhid->IsReportAvailable = 0U;
+  }
+
+  return (uint8_t)USBD_OK;
+}
+
+/**
+  * @brief  DeviceQualifierDescriptor
+  *         return Device Qualifier descriptor
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length)
+{
+  *length = (uint16_t)sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc);
+
+  return USBD_CUSTOM_HID_DeviceQualifierDesc;
+}
+
+/**
+  * @brief  USBD_CUSTOM_HID_RegisterInterface
+  * @param  pdev: device instance
+  * @param  fops: CUSTOMHID Interface callback
+  * @retval status
+  */
+uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
+                                          USBD_CUSTOM_HID_ItfTypeDef *fops)
+{
+  if (fops == NULL)
+  {
+    return (uint8_t)USBD_FAIL;
+  }
+
+  pdev->pUserData = fops;
+
+  return (uint8_t)USBD_OK;
+}
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 1727 - 0
cube_example/usb_hid_example/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c

@@ -0,0 +1,1727 @@
+/* ----------------------------------------------------------------------
+ * $Date:        5. February 2013
+ * $Revision:    V1.02
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.c
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedef's
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ *    
+ *  
+ *----------------------------------------------------------------------------
+ *
+ * Portions Copyright © 2016 STMicroelectronics International N.V. All rights reserved.
+ * Portions Copyright (c) 2013 ARM LIMITED
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include <string.h>
+#include "cmsis_os.h"
+
+/*
+ * ARM Compiler 4/5
+ */
+#if   defined ( __CC_ARM )
+
+  #define __ASM            __asm                                      
+  #define __INLINE         __inline                                     
+  #define __STATIC_INLINE  static __inline
+
+  #include "cmsis_armcc.h"
+
+/*
+ * GNU Compiler
+ */
+#elif defined ( __GNUC__ )
+
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+  #include "cmsis_gcc.h"
+
+
+/*
+ * IAR Compiler
+ */
+#elif defined ( __ICCARM__ )
+
+  #ifndef   __ASM
+    #define __ASM                     __asm
+  #endif
+  #ifndef   __INLINE
+    #define __INLINE                  inline
+  #endif
+  #ifndef   __STATIC_INLINE
+    #define __STATIC_INLINE           static inline
+  #endif
+
+  #include <cmsis_iar.h>
+#endif
+
+extern void xPortSysTickHandler(void);
+
+/* Convert from CMSIS type osPriority to FreeRTOS priority number */
+static unsigned portBASE_TYPE makeFreeRtosPriority (osPriority priority)
+{
+  unsigned portBASE_TYPE fpriority = tskIDLE_PRIORITY;
+  
+  if (priority != osPriorityError) {
+    fpriority += (priority - osPriorityIdle);
+  }
+  
+  return fpriority;
+}
+
+#if (INCLUDE_uxTaskPriorityGet == 1)
+/* Convert from FreeRTOS priority number to CMSIS type osPriority */
+static osPriority makeCmsisPriority (unsigned portBASE_TYPE fpriority)
+{
+  osPriority priority = osPriorityError;
+  
+  if ((fpriority - tskIDLE_PRIORITY) <= (osPriorityRealtime - osPriorityIdle)) {
+    priority = (osPriority)((int)osPriorityIdle + (int)(fpriority - tskIDLE_PRIORITY));
+  }
+  
+  return priority;
+}
+#endif
+
+
+/* Determine whether we are in thread mode or handler mode. */
+static int inHandlerMode (void)
+{
+  return __get_IPSR() != 0;
+}
+
+/*********************** Kernel Control Functions *****************************/
+/**
+* @brief  Initialize the RTOS Kernel for creating objects.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osKernelInitialize (void);
+
+/**
+* @brief  Start the RTOS Kernel with executing the specified thread.
+* @param  thread_def    thread definition referenced with \ref osThread.
+* @param  argument      pointer that is passed to the thread function as start argument.
+* @retval status code that indicates the execution status of the function
+* @note   MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osKernelStart (void)
+{
+  vTaskStartScheduler();
+  
+  return osOK;
+}
+
+/**
+* @brief  Check if the RTOS kernel is already started
+* @param  None
+* @retval (0) RTOS is not started
+*         (1) RTOS is started
+*         (-1) if this feature is disabled in FreeRTOSConfig.h 
+* @note  MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osKernelRunning(void)
+{
+#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
+  if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
+    return 0;
+  else
+    return 1;
+#else
+	return (-1);
+#endif	
+}
+
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+/**
+* @brief  Get the value of the Kernel SysTick timer
+* @param  None
+* @retval None
+* @note   MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+*/
+uint32_t osKernelSysTick(void)
+{
+  if (inHandlerMode()) {
+    return xTaskGetTickCountFromISR();
+  }
+  else {
+    return xTaskGetTickCount();
+  }
+}
+#endif    // System Timer available
+/*********************** Thread Management *****************************/
+/**
+* @brief  Create a thread and add it to Active Threads and set it to state READY.
+* @param  thread_def    thread definition referenced with \ref osThread.
+* @param  argument      pointer that is passed to the thread function as start argument.
+* @retval thread ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
+*/
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)
+{
+  TaskHandle_t handle;
+  
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) &&  ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+  if((thread_def->buffer != NULL) && (thread_def->controlblock != NULL)) {
+    handle = xTaskCreateStatic((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+              thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+              thread_def->buffer, thread_def->controlblock);
+  }
+  else {
+    if (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+              thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+              &handle) != pdPASS)  {
+      return NULL;
+    } 
+  }
+#elif( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+    handle = xTaskCreateStatic((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+              thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+              thread_def->buffer, thread_def->controlblock);
+#else
+  if (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+                   thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+                   &handle) != pdPASS)  {
+    return NULL;
+  }     
+#endif
+  
+  return handle;
+}
+
+/**
+* @brief  Return the thread ID of the current running thread.
+* @retval thread ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
+*/
+osThreadId osThreadGetId (void)
+{
+#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
+  return xTaskGetCurrentTaskHandle();
+#else
+	return NULL;
+#endif
+}
+
+/**
+* @brief  Terminate execution of a thread and remove it from Active Threads.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osThreadTerminate (osThreadId thread_id)
+{
+#if (INCLUDE_vTaskDelete == 1)
+  vTaskDelete(thread_id);
+  return osOK;
+#else
+  return osErrorOS;
+#endif
+}
+
+/**
+* @brief  Pass control to next thread that is in state \b READY.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osThreadYield (void)
+{
+  taskYIELD();
+  
+  return osOK;
+}
+
+/**
+* @brief   Change priority of an active thread.
+* @param   thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @param   priority      new priority value for the thread function.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority)
+{
+#if (INCLUDE_vTaskPrioritySet == 1)
+  vTaskPrioritySet(thread_id, makeFreeRtosPriority(priority));
+  return osOK;
+#else
+  return osErrorOS;
+#endif
+}
+
+/**
+* @brief   Get current priority of an active thread.
+* @param   thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  current priority value of the thread function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
+*/
+osPriority osThreadGetPriority (osThreadId thread_id)
+{
+#if (INCLUDE_uxTaskPriorityGet == 1)
+  if (inHandlerMode())
+  {
+    return makeCmsisPriority(uxTaskPriorityGetFromISR(thread_id));  
+  }
+  else
+  {  
+    return makeCmsisPriority(uxTaskPriorityGet(thread_id));
+  }
+#else
+  return osPriorityError;
+#endif
+}
+
+/*********************** Generic Wait Functions *******************************/
+/**
+* @brief   Wait for Timeout (Time Delay)
+* @param   millisec      time delay value
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osDelay (uint32_t millisec)
+{
+#if INCLUDE_vTaskDelay
+  TickType_t ticks = millisec / portTICK_PERIOD_MS;
+  
+  vTaskDelay(ticks ? ticks : 1);          /* Minimum delay = 1 tick */
+  
+  return osOK;
+#else
+  (void) millisec;
+  
+  return osErrorResource;
+#endif
+}
+
+#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0)) /* Generic Wait available */
+/**
+* @brief  Wait for Signal, Message, Mail, or Timeout
+* @param   millisec  timeout value or 0 in case of no time-out
+* @retval  event that contains signal, message, or mail information or error code.
+* @note   MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osWait (uint32_t millisec);
+
+#endif  /* Generic Wait available */
+
+/***********************  Timer Management Functions ***************************/
+/**
+* @brief  Create a timer.
+* @param  timer_def     timer object referenced with \ref osTimer.
+* @param  type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+* @param  argument      argument to the timer call back function.
+* @retval  timer ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
+*/
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument)
+{
+#if (configUSE_TIMERS == 1)
+
+#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 
+  if(timer_def->controlblock != NULL) {
+    return xTimerCreateStatic((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer,
+                      (StaticTimer_t *)timer_def->controlblock);
+  }
+  else {
+    return xTimerCreate((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer);
+ }
+#elif( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xTimerCreateStatic((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer,
+                      (StaticTimer_t *)timer_def->controlblock);  
+#else
+  return xTimerCreate((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer);
+#endif
+
+#else 
+	return NULL;
+#endif
+}
+
+/**
+* @brief  Start or restart a timer.
+* @param  timer_id      timer ID obtained by \ref osTimerCreate.
+* @param  millisec      time delay value of the timer.
+* @retval  status code that indicates the execution status of the function
+* @note   MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec)
+{
+  osStatus result = osOK;
+#if (configUSE_TIMERS == 1)  
+  portBASE_TYPE taskWoken = pdFALSE;
+  TickType_t ticks = millisec / portTICK_PERIOD_MS;
+
+  if (ticks == 0)
+    ticks = 1;
+    
+  if (inHandlerMode()) 
+  {
+    if (xTimerChangePeriodFromISR(timer_id, ticks, &taskWoken) != pdPASS)
+    {
+      result = osErrorOS;
+    }
+    else
+    {
+      portEND_SWITCHING_ISR(taskWoken);     
+    }
+  }
+  else 
+  {
+    if (xTimerChangePeriod(timer_id, ticks, 0) != pdPASS)
+      result = osErrorOS;
+  }
+
+#else 
+  result = osErrorOS;
+#endif
+  return result;
+}
+
+/**
+* @brief  Stop a timer.
+* @param  timer_id      timer ID obtained by \ref osTimerCreate
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osTimerStop (osTimerId timer_id)
+{
+  osStatus result = osOK;
+#if (configUSE_TIMERS == 1)  
+  portBASE_TYPE taskWoken = pdFALSE;
+
+  if (inHandlerMode()) {
+    if (xTimerStopFromISR(timer_id, &taskWoken) != pdPASS) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xTimerStop(timer_id, 0) != pdPASS) {
+      result = osErrorOS;
+    }
+  }
+#else 
+  result = osErrorOS;
+#endif 
+  return result;
+}
+
+/**
+* @brief  Delete a timer.
+* @param  timer_id      timer ID obtained by \ref osTimerCreate
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osTimerDelete (osTimerId timer_id)
+{
+osStatus result = osOK;
+
+#if (configUSE_TIMERS == 1)
+
+   if (inHandlerMode()) {
+     return osErrorISR;
+  }
+  else { 
+    if ((xTimerDelete(timer_id, osWaitForever )) != pdPASS) {
+      result = osErrorOS;
+    }
+  } 
+    
+#else 
+  result = osErrorOS;
+#endif 
+ 
+  return result;
+}
+
+/***************************  Signal Management ********************************/
+/**
+* @brief  Set the specified Signal Flags of an active thread.
+* @param  thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @param  signals       specifies the signal flags of the thread that should be set.
+* @retval previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+* @note   MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osSignalSet (osThreadId thread_id, int32_t signal)
+{
+#if( configUSE_TASK_NOTIFICATIONS == 1 )	
+  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+  uint32_t ulPreviousNotificationValue = 0;
+  
+  if (inHandlerMode())
+  {
+    if(xTaskGenericNotifyFromISR( thread_id , (uint32_t)signal, eSetBits, &ulPreviousNotificationValue, &xHigherPriorityTaskWoken ) != pdPASS )
+      return 0x80000000;
+    
+    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+  }  
+  else if(xTaskGenericNotify( thread_id , (uint32_t)signal, eSetBits, &ulPreviousNotificationValue) != pdPASS )
+    return 0x80000000;
+  
+  return ulPreviousNotificationValue;
+#else
+  (void) thread_id;
+  (void) signal;
+
+  return 0x80000000; /* Task Notification not supported */ 	
+#endif
+}
+
+/**
+* @brief  Clear the specified Signal Flags of an active thread.
+* @param  thread_id  thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @param  signals    specifies the signal flags of the thread that shall be cleared.
+* @retval  previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+* @note   MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osSignalClear (osThreadId thread_id, int32_t signal);
+
+/**
+* @brief  Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+* @param  signals   wait until all specified signal flags set or 0 for any single signal flag.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval  event flag information or error code.
+* @note   MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osSignalWait (int32_t signals, uint32_t millisec)
+{
+  osEvent ret;
+
+#if( configUSE_TASK_NOTIFICATIONS == 1 )
+	
+  TickType_t ticks;
+
+  ret.value.signals = 0;  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }  
+  
+  if (inHandlerMode())
+  {
+    ret.status = osErrorISR;  /*Not allowed in ISR*/
+  }
+  else
+  {
+    if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)
+    {
+      if(ticks == 0)  ret.status = osOK;
+      else  ret.status = osEventTimeout;
+    }
+    else if(ret.value.signals < 0)
+    {
+      ret.status =  osErrorValue;     
+    }
+    else  ret.status =  osEventSignal;
+  }
+#else
+  (void) signals;
+  (void) millisec;
+	
+  ret.status =  osErrorOS;	/* Task Notification not supported */
+#endif
+  
+  return ret;
+}
+
+/****************************  Mutex Management ********************************/
+/**
+* @brief  Create and Initialize a Mutex object
+* @param  mutex_def     mutex definition referenced with \ref osMutex.
+* @retval  mutex ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
+*/
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def)
+{
+#if ( configUSE_MUTEXES == 1)
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  if (mutex_def->controlblock != NULL) {
+    return xSemaphoreCreateMutexStatic( mutex_def->controlblock );
+     }
+  else {
+    return xSemaphoreCreateMutex(); 
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xSemaphoreCreateMutexStatic( mutex_def->controlblock );
+#else  
+    return xSemaphoreCreateMutex(); 
+#endif
+#else
+  return NULL;
+#endif
+}
+
+/**
+* @brief Wait until a Mutex becomes available
+* @param mutex_id      mutex ID obtained by \ref osMutexCreate.
+* @param millisec      timeout value or 0 in case of no time-out.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec)
+{
+  TickType_t ticks;
+  portBASE_TYPE taskWoken = pdFALSE;  
+  
+  
+  if (mutex_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreTakeFromISR(mutex_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+	portEND_SWITCHING_ISR(taskWoken);
+  } 
+  else if (xSemaphoreTake(mutex_id, ticks) != pdTRUE) {
+    return osErrorOS;
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Release a Mutex that was obtained by \ref osMutexWait
+* @param mutex_id      mutex ID obtained by \ref osMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMutexRelease (osMutexId mutex_id)
+{
+  osStatus result = osOK;
+  portBASE_TYPE taskWoken = pdFALSE;
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreGiveFromISR(mutex_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else if (xSemaphoreGive(mutex_id) != pdTRUE) 
+  {
+    result = osErrorOS;
+  }
+  return result;
+}
+
+/**
+* @brief Delete a Mutex
+* @param mutex_id  mutex ID obtained by \ref osMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMutexDelete (osMutexId mutex_id)
+{
+  if (inHandlerMode()) {
+    return osErrorISR;
+  }
+
+  vQueueDelete(mutex_id);
+
+  return osOK;
+}
+
+/********************  Semaphore Management Functions **************************/
+
+#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))
+
+/**
+* @brief Create and Initialize a Semaphore object used for managing resources
+* @param semaphore_def semaphore definition referenced with \ref osSemaphore.
+* @param count         number of available resources.
+* @retval  semaphore ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
+*/
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count)
+{ 
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  osSemaphoreId sema;
+  
+  if (semaphore_def->controlblock != NULL){
+    if (count == 1) {
+      return xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
+    }
+    else {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )
+      return xSemaphoreCreateCountingStatic( count, count, semaphore_def->controlblock );
+#else
+      return NULL;
+#endif
+    }
+  }
+  else {
+    if (count == 1) {
+      vSemaphoreCreateBinary(sema);
+      return sema;
+    }
+    else {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )	
+      return xSemaphoreCreateCounting(count, count);
+#else
+      return NULL;
+#endif    
+    }
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 ) // configSUPPORT_DYNAMIC_ALLOCATION == 0
+  if(count == 1) {
+    return xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
+  }
+  else
+  {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )
+      return xSemaphoreCreateCountingStatic( count, count, semaphore_def->controlblock );
+#else
+      return NULL;
+#endif    
+  }
+#else  // configSUPPORT_STATIC_ALLOCATION == 0  && configSUPPORT_DYNAMIC_ALLOCATION == 1
+  osSemaphoreId sema;
+ 
+  if (count == 1) {
+    vSemaphoreCreateBinary(sema);
+    return sema;
+  }
+  else {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )	
+    return xSemaphoreCreateCounting(count, count);
+#else
+    return NULL;
+#endif
+  }
+#endif
+}
+
+/**
+* @brief Wait until a Semaphore token becomes available
+* @param  semaphore_id  semaphore object referenced with \ref osSemaphore.
+* @param  millisec      timeout value or 0 in case of no time-out.
+* @retval  number of available tokens, or -1 in case of incorrect parameters.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
+{
+  TickType_t ticks;
+  portBASE_TYPE taskWoken = pdFALSE;  
+  
+  
+  if (semaphore_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreTakeFromISR(semaphore_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+	portEND_SWITCHING_ISR(taskWoken);
+  }  
+  else if (xSemaphoreTake(semaphore_id, ticks) != pdTRUE) {
+    return osErrorOS;
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Release a Semaphore token
+* @param  semaphore_id  semaphore object referenced with \ref osSemaphore.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
+{
+  osStatus result = osOK;
+  portBASE_TYPE taskWoken = pdFALSE;
+  
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreGiveFromISR(semaphore_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xSemaphoreGive(semaphore_id) != pdTRUE) {
+      result = osErrorOS;
+    }
+  }
+  
+  return result;
+}
+
+/**
+* @brief Delete a Semaphore
+* @param  semaphore_id  semaphore object referenced with \ref osSemaphore.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id)
+{
+  if (inHandlerMode()) {
+    return osErrorISR;
+  }
+
+  vSemaphoreDelete(semaphore_id);
+
+  return osOK; 
+}
+
+#endif    /* Use Semaphores */
+
+/*******************   Memory Pool Management Functions  ***********************/
+
+#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0)) 
+
+//TODO
+//This is a primitive and inefficient wrapper around the existing FreeRTOS memory management.
+//A better implementation will have to modify heap_x.c!
+
+
+typedef struct os_pool_cb {
+  void *pool;
+  uint8_t *markers;
+  uint32_t pool_sz;
+  uint32_t item_sz;
+  uint32_t currentIndex;
+} os_pool_cb_t;
+
+
+/**
+* @brief Create and Initialize a memory pool
+* @param  pool_def      memory pool definition referenced with \ref osPool.
+* @retval  memory pool ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
+*/
+osPoolId osPoolCreate (const osPoolDef_t *pool_def)
+{
+#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+  osPoolId thePool;
+  int itemSize = 4 * ((pool_def->item_sz + 3) / 4);
+  uint32_t i;
+  
+  /* First have to allocate memory for the pool control block. */
+ thePool = pvPortMalloc(sizeof(os_pool_cb_t));
+
+  
+  if (thePool) {
+    thePool->pool_sz = pool_def->pool_sz;
+    thePool->item_sz = itemSize;
+    thePool->currentIndex = 0;
+    
+    /* Memory for markers */
+    thePool->markers = pvPortMalloc(pool_def->pool_sz);
+   
+    if (thePool->markers) {
+      /* Now allocate the pool itself. */
+     thePool->pool = pvPortMalloc(pool_def->pool_sz * itemSize);
+      
+      if (thePool->pool) {
+        for (i = 0; i < pool_def->pool_sz; i++) {
+          thePool->markers[i] = 0;
+        }
+      }
+      else {
+        vPortFree(thePool->markers);
+        vPortFree(thePool);
+        thePool = NULL;
+      }
+    }
+    else {
+      vPortFree(thePool);
+      thePool = NULL;
+    }
+  }
+
+  return thePool;
+ 
+#else
+  return NULL;
+#endif
+}
+
+/**
+* @brief Allocate a memory block from a memory pool
+* @param pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+* @retval  address of the allocated memory block or NULL in case of no memory available.
+* @note   MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osPoolAlloc (osPoolId pool_id)
+{
+  int dummy = 0;
+  void *p = NULL;
+  uint32_t i;
+  uint32_t index;
+  
+  if (inHandlerMode()) {
+    dummy = portSET_INTERRUPT_MASK_FROM_ISR();
+  }
+  else {
+    vPortEnterCritical();
+  }
+  
+  for (i = 0; i < pool_id->pool_sz; i++) {
+    index = (pool_id->currentIndex + i) % pool_id->pool_sz;
+    
+    if (pool_id->markers[index] == 0) {
+      pool_id->markers[index] = 1;
+      p = (void *)((uint32_t)(pool_id->pool) + (index * pool_id->item_sz));
+      pool_id->currentIndex = index;
+      break;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    portCLEAR_INTERRUPT_MASK_FROM_ISR(dummy);
+  }
+  else {
+    vPortExitCritical();
+  }
+  
+  return p;
+}
+
+/**
+* @brief Allocate a memory block from a memory pool and set memory block to zero
+* @param  pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+* @retval  address of the allocated memory block or NULL in case of no memory available.
+* @note   MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osPoolCAlloc (osPoolId pool_id)
+{
+  void *p = osPoolAlloc(pool_id);
+  
+  if (p != NULL)
+  {
+    memset(p, 0, sizeof(pool_id->pool_sz));
+  }
+  
+  return p;
+}
+
+/**
+* @brief Return an allocated memory block back to a specific memory pool
+* @param  pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+* @param  block         address of the allocated memory block that is returned to the memory pool.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osPoolFree (osPoolId pool_id, void *block)
+{
+  uint32_t index;
+  
+  if (pool_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  if (block == NULL) {
+    return osErrorParameter;
+  }
+  
+  if (block < pool_id->pool) {
+    return osErrorParameter;
+  }
+  
+  index = (uint32_t)block - (uint32_t)(pool_id->pool);
+  if (index % pool_id->item_sz) {
+    return osErrorParameter;
+  }
+  index = index / pool_id->item_sz;
+  if (index >= pool_id->pool_sz) {
+    return osErrorParameter;
+  }
+  
+  pool_id->markers[index] = 0;
+  
+  return osOK;
+}
+
+
+#endif   /* Use Memory Pool Management */
+
+/*******************   Message Queue Management Functions  *********************/
+
+#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0)) /* Use Message Queues */
+
+/**
+* @brief Create and Initialize a Message Queue
+* @param queue_def     queue definition referenced with \ref osMessageQ.
+* @param  thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+* @retval  message queue ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
+*/
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id)
+{
+  (void) thread_id;
+  
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  if ((queue_def->buffer != NULL) && (queue_def->controlblock != NULL)) {
+    return xQueueCreateStatic(queue_def->queue_sz, queue_def->item_sz, queue_def->buffer, queue_def->controlblock);
+  }
+  else {
+    return xQueueCreate(queue_def->queue_sz, queue_def->item_sz);
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xQueueCreateStatic(queue_def->queue_sz, queue_def->item_sz, queue_def->buffer, queue_def->controlblock);
+#else  
+  return xQueueCreate(queue_def->queue_sz, queue_def->item_sz);
+#endif
+}
+
+/**
+* @brief Put a Message to a Queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  info      message information.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec)
+{
+  portBASE_TYPE taskWoken = pdFALSE;
+  TickType_t ticks;
+  
+  ticks = millisec / portTICK_PERIOD_MS;
+  if (ticks == 0) {
+    ticks = 1;
+  }
+  
+  if (inHandlerMode()) {
+    if (xQueueSendFromISR(queue_id, &info, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueSend(queue_id, &info, ticks) != pdTRUE) {
+      return osErrorOS;
+    }
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Get a Message or Wait for a Message from a Queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval event information that includes status code.
+* @note   MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec)
+{
+  portBASE_TYPE taskWoken;
+  TickType_t ticks;
+  osEvent event;
+  
+  event.def.message_id = queue_id;
+  event.value.v = 0;
+  
+  if (queue_id == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+  
+  taskWoken = pdFALSE;
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xQueueReceiveFromISR(queue_id, &event.value.v, &taskWoken) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMessage;
+    }
+    else {
+      event.status = osOK;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueReceive(queue_id, &event.value.v, ticks) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMessage;
+    }
+    else {
+      event.status = (ticks == 0) ? osOK : osEventTimeout;
+    }
+  }
+  
+  return event;
+}
+
+#endif     /* Use Message Queues */
+
+/********************   Mail Queue Management Functions  ***********************/
+#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))  /* Use Mail Queues */
+
+
+typedef struct os_mailQ_cb {
+  const osMailQDef_t *queue_def;
+  QueueHandle_t handle;
+  osPoolId pool;
+} os_mailQ_cb_t;
+
+/**
+* @brief Create and Initialize mail queue
+* @param  queue_def     reference to the mail queue definition obtain with \ref osMailQ
+* @param   thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+* @retval mail queue ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
+*/
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id)
+{
+#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+  (void) thread_id;
+  
+  osPoolDef_t pool_def = {queue_def->queue_sz, queue_def->item_sz, NULL};
+  
+  /* Create a mail queue control block */
+
+  *(queue_def->cb) = pvPortMalloc(sizeof(struct os_mailQ_cb));
+
+  if (*(queue_def->cb) == NULL) {
+    return NULL;
+  }
+  (*(queue_def->cb))->queue_def = queue_def;
+  
+  /* Create a queue in FreeRTOS */
+  (*(queue_def->cb))->handle = xQueueCreate(queue_def->queue_sz, sizeof(void *));
+
+
+  if ((*(queue_def->cb))->handle == NULL) {
+    vPortFree(*(queue_def->cb));
+    return NULL;
+  }
+  
+  /* Create a mail pool */
+  (*(queue_def->cb))->pool = osPoolCreate(&pool_def);
+  if ((*(queue_def->cb))->pool == NULL) {
+    //TODO: Delete queue. How to do it in FreeRTOS?
+    vPortFree(*(queue_def->cb));
+    return NULL;
+  }
+  
+  return *(queue_def->cb);
+#else
+  return NULL;
+#endif
+}
+
+/**
+* @brief Allocate a memory block from a mail
+* @param  queue_id      mail queue ID obtained with \ref osMailCreate.
+* @param  millisec      timeout value or 0 in case of no time-out.
+* @retval pointer to memory block that can be filled with mail or NULL in case error.
+* @note   MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec)
+{
+  (void) millisec;
+  void *p;
+  
+  
+  if (queue_id == NULL) {
+    return NULL;
+  }
+  
+  p = osPoolAlloc(queue_id->pool);
+  
+  return p;
+}
+
+/**
+* @brief Allocate a memory block from a mail and set memory block to zero
+* @param  queue_id      mail queue ID obtained with \ref osMailCreate.
+* @param  millisec      timeout value or 0 in case of no time-out.
+* @retval pointer to memory block that can be filled with mail or NULL in case error.
+* @note   MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec)
+{
+  uint32_t i;
+  void *p = osMailAlloc(queue_id, millisec);
+  
+  if (p) {
+    for (i = 0; i < queue_id->queue_def->item_sz; i++) {
+      ((uint8_t *)p)[i] = 0;
+    }
+  }
+  
+  return p;
+}
+
+/**
+* @brief Put a mail to a queue
+* @param  queue_id      mail queue ID obtained with \ref osMailCreate.
+* @param  mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMailPut (osMailQId queue_id, void *mail)
+{
+  portBASE_TYPE taskWoken;
+  
+  
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  taskWoken = pdFALSE;
+  
+  if (inHandlerMode()) {
+    if (xQueueSendFromISR(queue_id->handle, &mail, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueSend(queue_id->handle, &mail, 0) != pdTRUE) { 
+      return osErrorOS;
+    }
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Get a mail from a queue
+* @param  queue_id   mail queue ID obtained with \ref osMailCreate.
+* @param millisec    timeout value or 0 in case of no time-out
+* @retval event that contains mail information or error code.
+* @note   MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec)
+{
+  portBASE_TYPE taskWoken;
+  TickType_t ticks;
+  osEvent event;
+  
+  event.def.mail_id = queue_id;
+  
+  if (queue_id == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+  
+  taskWoken = pdFALSE;
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xQueueReceiveFromISR(queue_id->handle, &event.value.p, &taskWoken) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMail;
+    }
+    else {
+      event.status = osOK;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueReceive(queue_id->handle, &event.value.p, ticks) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMail;
+    }
+    else {
+      event.status = (ticks == 0) ? osOK : osEventTimeout;
+    }
+  }
+  
+  return event;
+}
+
+/**
+* @brief Free a memory block from a mail
+* @param  queue_id mail queue ID obtained with \ref osMailCreate.
+* @param  mail     pointer to the memory block that was obtained with \ref osMailGet.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMailFree (osMailQId queue_id, void *mail)
+{
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  return osPoolFree(queue_id->pool, mail);
+}
+#endif  /* Use Mail Queues */
+
+/*************************** Additional specific APIs to Free RTOS ************/
+/**
+* @brief  Handles the tick increment
+* @param  none.
+* @retval none.
+*/
+void osSystickHandler(void)
+{
+
+#if (INCLUDE_xTaskGetSchedulerState  == 1 )
+  if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
+  {
+#endif  /* INCLUDE_xTaskGetSchedulerState */  
+    xPortSysTickHandler();
+#if (INCLUDE_xTaskGetSchedulerState  == 1 )
+  }
+#endif  /* INCLUDE_xTaskGetSchedulerState */  
+}
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/**
+* @brief  Obtain the state of any thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  the stae of the thread, states are encoded by the osThreadState enumerated type.
+*/
+osThreadState osThreadGetState(osThreadId thread_id)
+{
+  eTaskState ThreadState;
+  osThreadState result;
+  
+  ThreadState = eTaskGetState(thread_id);
+  
+  switch (ThreadState)
+  {
+  case eRunning :
+    result = osThreadRunning;
+    break;
+  case eReady :
+    result = osThreadReady;
+    break;
+  case eBlocked :
+    result = osThreadBlocked;
+    break;
+  case eSuspended :
+    result = osThreadSuspended;
+    break;
+  case eDeleted :
+    result = osThreadDeleted;
+    break;
+  default:
+    result = osThreadError;
+  } 
+  
+  return result;
+}
+#endif /* INCLUDE_eTaskGetState */
+
+#if (INCLUDE_eTaskGetState == 1)
+/**
+* @brief Check if a thread is already suspended or not.
+* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval status code that indicates the execution status of the function.
+*/
+osStatus osThreadIsSuspended(osThreadId thread_id)
+{
+  if (eTaskGetState(thread_id) == eSuspended)
+    return osOK;
+  else
+    return osErrorOS;
+}
+#endif /* INCLUDE_eTaskGetState */
+/**
+* @brief  Suspend execution of a thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspend (osThreadId thread_id)
+{
+#if (INCLUDE_vTaskSuspend == 1)
+    vTaskSuspend(thread_id);
+  
+  return osOK;
+#else
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Resume execution of a suspended thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResume (osThreadId thread_id)
+{
+#if (INCLUDE_vTaskSuspend == 1)  
+  if(inHandlerMode())
+  {
+    if (xTaskResumeFromISR(thread_id) == pdTRUE)
+    {
+      portYIELD_FROM_ISR(pdTRUE);
+    }
+  }
+  else
+  {
+    vTaskResume(thread_id);
+  }
+  return osOK;
+#else
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Suspend execution of a all active threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspendAll (void)
+{
+  vTaskSuspendAll();
+  
+  return osOK;
+}
+
+/**
+* @brief  Resume execution of a all suspended threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResumeAll (void)
+{
+  if (xTaskResumeAll() == pdTRUE)
+    return osOK;
+  else
+    return osErrorOS;
+  
+}
+
+/**
+* @brief  Delay a task until a specified time
+* @param   PreviousWakeTime   Pointer to a variable that holds the time at which the 
+*          task was last unblocked. PreviousWakeTime must be initialised with the current time
+*          prior to its first use (PreviousWakeTime = osKernelSysTick() )
+* @param   millisec    time delay value
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec)
+{
+#if INCLUDE_vTaskDelayUntil
+  TickType_t ticks = (millisec / portTICK_PERIOD_MS);
+  vTaskDelayUntil((TickType_t *) PreviousWakeTime, ticks ? ticks : 1);
+  
+  return osOK;
+#else
+  (void) millisec;
+  (void) PreviousWakeTime;
+  
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief   Abort the delay for a specific thread
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId   
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osAbortDelay(osThreadId thread_id)
+{
+#if INCLUDE_xTaskAbortDelay
+  
+  xTaskAbortDelay(thread_id);
+  
+  return osOK;
+#else
+  (void) thread_id;
+  
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief   Lists all the current threads, along with their current state 
+*          and stack usage high water mark.
+* @param   buffer   A buffer into which the above mentioned details
+*          will be written
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadList (uint8_t *buffer)
+{
+#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )
+  vTaskList((char *)buffer);
+#endif
+  return osOK;
+}
+
+/**
+* @brief  Receive an item from a queue without removing the item from the queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval event information that includes status code.
+*/
+osEvent osMessagePeek (osMessageQId queue_id, uint32_t millisec)
+{
+  TickType_t ticks;
+  osEvent event;
+  
+  event.def.message_id = queue_id;
+  
+  if (queue_id == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (xQueuePeek(queue_id, &event.value.v, ticks) == pdTRUE) 
+  {
+    /* We have mail */
+    event.status = osEventMessage;
+  }
+  else 
+  {
+    event.status = (ticks == 0) ? osOK : osEventTimeout;
+  }
+  
+  return event;
+}
+
+/**
+* @brief  Get the number of messaged stored in a queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval number of messages stored in a queue.
+*/
+uint32_t osMessageWaiting(osMessageQId queue_id)
+{
+  if (inHandlerMode()) {
+    return uxQueueMessagesWaitingFromISR(queue_id);
+  }
+  else
+  {
+    return uxQueueMessagesWaiting(queue_id);
+  }
+}
+
+/**
+* @brief  Get the available space in a message queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval available space in a message queue.
+*/
+uint32_t osMessageAvailableSpace(osMessageQId queue_id)  
+{
+  return uxQueueSpacesAvailable(queue_id);
+}
+
+/**
+* @brief Delete a Message Queue
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osMessageDelete (osMessageQId queue_id)
+{
+  if (inHandlerMode()) {
+    return osErrorISR;
+  }
+
+  vQueueDelete(queue_id);
+
+  return osOK; 
+}
+
+/**
+* @brief  Create and Initialize a Recursive Mutex
+* @param  mutex_def     mutex definition referenced with \ref osMutex.
+* @retval  mutex ID for reference by other functions or NULL in case of error..
+*/
+osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def)
+{
+#if (configUSE_RECURSIVE_MUTEXES == 1)
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  if (mutex_def->controlblock != NULL){
+    return xSemaphoreCreateRecursiveMutexStatic( mutex_def->controlblock );
+  }
+  else {
+    return xSemaphoreCreateRecursiveMutex();
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xSemaphoreCreateRecursiveMutexStatic( mutex_def->controlblock );
+#else 
+  return xSemaphoreCreateRecursiveMutex();
+#endif
+#else
+  return NULL;
+#endif	
+}
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id      mutex ID obtained by \ref osRecursiveMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexRelease (osMutexId mutex_id)
+{
+#if (configUSE_RECURSIVE_MUTEXES == 1)
+  osStatus result = osOK;
+ 
+  if (xSemaphoreGiveRecursive(mutex_id) != pdTRUE) 
+  {
+    result = osErrorOS;
+  }
+  return result;
+#else
+	return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id    mutex ID obtained by \ref osRecursiveMutexCreate.
+* @param millisec      timeout value or 0 in case of no time-out.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexWait (osMutexId mutex_id, uint32_t millisec)
+{
+#if (configUSE_RECURSIVE_MUTEXES == 1)
+  TickType_t ticks;
+  
+  if (mutex_id == NULL)
+  {
+    return osErrorParameter;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) 
+  {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) 
+  {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) 
+    {
+      ticks = 1;
+    }
+  }
+  
+  if (xSemaphoreTakeRecursive(mutex_id, ticks) != pdTRUE) 
+  {
+    return osErrorOS;
+  }
+  return osOK;
+#else
+	return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Returns the current count value of a counting semaphore
+* @param  semaphore_id  semaphore_id ID obtained by \ref osSemaphoreCreate.
+* @retval  count value
+*/
+uint32_t osSemaphoreGetCount(osSemaphoreId semaphore_id)
+{
+  return uxSemaphoreGetCount(semaphore_id);
+}

+ 1026 - 0
cube_example/usb_hid_example/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h

@@ -0,0 +1,1026 @@
+/* ----------------------------------------------------------------------
+ * $Date:        5. February 2013
+ * $Revision:    V1.02
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.h header file
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedef's
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ *    
+ *  
+ *----------------------------------------------------------------------------
+ *
+ * Portions Copyright © 2016 STMicroelectronics International N.V. All rights reserved.
+ * Portions Copyright (c) 2013 ARM LIMITED
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+#include "queue.h"
+#include "semphr.h"
+#include "event_groups.h"
+
+/**
+\page cmsis_os_h Header File Template: cmsis_os.h
+
+The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS).
+Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents
+its implementation.
+
+The file cmsis_os.h contains:
+ - CMSIS-RTOS API function definitions
+ - struct definitions for parameters and return types
+ - status and priority values used by CMSIS-RTOS API functions
+ - macros for defining threads and other kernel objects
+
+
+<b>Name conventions and header file modifications</b>
+
+All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions.
+Definitions that are prefixed \b os_ are not used in the application code but local to this header file.
+All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread.
+
+Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation.
+These definitions can be specific to the underlying RTOS kernel.
+
+Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer
+compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation.
+
+
+<b>Function calls from interrupt service routines</b>
+
+The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR):
+  - \ref osSignalSet
+  - \ref osSemaphoreRelease
+  - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree
+  - \ref osMessagePut, \ref osMessageGet
+  - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree
+
+Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called
+from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector.
+
+Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time.
+If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive.
+
+
+<b>Define and reference object definitions</b>
+
+With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file
+that is used throughout a project as shown below:
+
+<i>Header File</i>
+\code
+#include <cmsis_os.h>                                         // CMSIS RTOS header file
+
+// Thread definition
+extern void thread_sample (void const *argument);             // function prototype
+osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
+
+// Pool definition
+osPoolDef(MyPool, 10, long);
+\endcode
+
+
+This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is
+present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be
+used throughout the whole project.
+
+<i>Example</i>
+\code
+#include "osObjects.h"     // Definition of the CMSIS-RTOS objects
+\endcode
+
+\code
+#define osObjectExternal   // Objects will be defined as external symbols
+#include "osObjects.h"     // Reference to the CMSIS-RTOS objects
+\endcode
+
+*/
+
+#ifndef _CMSIS_OS_H
+#define _CMSIS_OS_H
+
+/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
+#define osCMSIS           0x10002      ///< API version (main [31:16] .sub [15:0])
+
+/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
+#define osCMSIS_KERNEL    0x10000	   ///< RTOS identification and version (main [31:16] .sub [15:0])
+
+/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
+#define osKernelSystemId "KERNEL V1.00"   ///< RTOS identification string
+
+/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
+#define osFeature_MainThread   1       ///< main thread      1=main can be thread, 0=not available
+#define osFeature_Pool         1       ///< Memory Pools:    1=available, 0=not available
+#define osFeature_MailQ        1       ///< Mail Queues:     1=available, 0=not available
+#define osFeature_MessageQ     1       ///< Message Queues:  1=available, 0=not available
+#define osFeature_Signals      8       ///< maximum number of Signal Flags available per thread
+#define osFeature_Semaphore    1      ///< osFeature_Semaphore function: 1=available, 0=not available
+#define osFeature_Wait         0       ///< osWait function: 1=available, 0=not available
+#define osFeature_SysTick      1       ///< osKernelSysTick functions: 1=available, 0=not available
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+
+// ==== Enumeration, structures, defines ====
+
+/// Priority used for thread control.
+/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osPriorityIdle          = -3,          ///< priority: idle (lowest)
+  osPriorityLow           = -2,          ///< priority: low
+  osPriorityBelowNormal   = -1,          ///< priority: below normal
+  osPriorityNormal        =  0,          ///< priority: normal (default)
+  osPriorityAboveNormal   = +1,          ///< priority: above normal
+  osPriorityHigh          = +2,          ///< priority: high
+  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
+  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
+} osPriority;
+
+/// Timeout value.
+/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
+#define osWaitForever     0xFFFFFFFF     ///< wait forever timeout value
+
+/// Status code values returned by CMSIS-RTOS functions.
+/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osOK                    =     0,       ///< function completed; no error or event occurred.
+  osEventSignal           =  0x08,       ///< function completed; signal event occurred.
+  osEventMessage          =  0x10,       ///< function completed; message event occurred.
+  osEventMail             =  0x20,       ///< function completed; mail event occurred.
+  osEventTimeout          =  0x40,       ///< function completed; timeout occurred.
+  osErrorParameter        =  0x80,       ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
+  osErrorResource         =  0x81,       ///< resource not available: a specified resource was not available.
+  osErrorTimeoutResource  =  0xC1,       ///< resource not available within given time: a specified resource was not available within the timeout period.
+  osErrorISR              =  0x82,       ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
+  osErrorISRRecursive     =  0x83,       ///< function called multiple times from ISR with same object.
+  osErrorPriority         =  0x84,       ///< system cannot determine priority or thread has illegal priority.
+  osErrorNoMemory         =  0x85,       ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
+  osErrorValue            =  0x86,       ///< value of a parameter is out of range.
+  osErrorOS               =  0xFF,       ///< unspecified RTOS error: run-time error but no other error message fits.
+  os_status_reserved      =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osStatus;
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/* Thread state returned by osThreadGetState */
+typedef enum {
+	osThreadRunning   = 0x0,	      /* A thread is querying the state of itself, so must be running. */
+	osThreadReady     = 0x1 ,			        /* The thread being queried is in a read or pending ready list. */
+	osThreadBlocked   = 0x2,		        /* The thread being queried is in the Blocked state. */
+	osThreadSuspended = 0x3,	      /* The thread being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */
+	osThreadDeleted   = 0x4,		          /* The thread being queried has been deleted, but its TCB has not yet been freed. */   
+  osThreadError     = 0x7FFFFFFF
+} osThreadState;
+#endif /* INCLUDE_eTaskGetState */
+
+/// Timer type value for the timer definition.
+/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osTimerOnce             =     0,       ///< one-shot timer
+  osTimerPeriodic         =     1        ///< repeating timer
+} os_timer_type;
+
+/// Entry point of a thread.
+/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
+typedef void (*os_pthread) (void const *argument);
+
+/// Entry point of a timer call back function.
+/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
+typedef void (*os_ptimer) (void const *argument);
+
+// >>> the following data type definitions may shall adapted towards a specific RTOS
+
+/// Thread ID identifies the thread (pointer to a thread control block).
+/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
+typedef TaskHandle_t osThreadId;
+
+/// Timer ID identifies the timer (pointer to a timer control block).
+/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
+typedef TimerHandle_t osTimerId;
+
+/// Mutex ID identifies the mutex (pointer to a mutex control block).
+/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
+typedef SemaphoreHandle_t osMutexId;
+
+/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
+/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
+typedef SemaphoreHandle_t osSemaphoreId;
+
+/// Pool ID identifies the memory pool (pointer to a memory pool control block).
+/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_cb *osPoolId;
+
+/// Message ID identifies the message queue (pointer to a message queue control block).
+/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
+typedef QueueHandle_t osMessageQId;
+
+/// Mail ID identifies the mail queue (pointer to a mail queue control block).
+/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_cb *osMailQId;
+
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+typedef StaticTask_t               osStaticThreadDef_t;
+typedef StaticTimer_t              osStaticTimerDef_t;
+typedef StaticSemaphore_t          osStaticMutexDef_t;         
+typedef StaticSemaphore_t          osStaticSemaphoreDef_t;
+typedef StaticQueue_t              osStaticMessageQDef_t;
+
+#endif
+
+
+
+
+/// Thread Definition structure contains startup information of a thread.
+/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_thread_def  {
+  char                   *name;        ///< Thread name 
+  os_pthread             pthread;      ///< start address of thread function
+  osPriority             tpriority;    ///< initial thread priority
+  uint32_t               instances;    ///< maximum number of instances of that thread function
+  uint32_t               stacksize;    ///< stack size requirements in bytes; 0 is default stack size
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  uint32_t               *buffer;      ///< stack buffer for static allocation; NULL for dynamic allocation
+  osStaticThreadDef_t    *controlblock;     ///< control block to hold thread's data for static allocation; NULL for dynamic allocation
+#endif
+} osThreadDef_t;
+
+/// Timer Definition structure contains timer parameters.
+/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_timer_def  {
+  os_ptimer                 ptimer;    ///< start address of a timer function
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  osStaticTimerDef_t        *controlblock;      ///< control block to hold timer's data for static allocation; NULL for dynamic allocation
+#endif
+} osTimerDef_t;
+
+/// Mutex Definition structure contains setup information for a mutex.
+/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mutex_def  {
+  uint32_t                   dummy;    ///< dummy value.
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  osStaticMutexDef_t         *controlblock;      ///< control block for static allocation; NULL for dynamic allocation
+#endif
+} osMutexDef_t;
+
+/// Semaphore Definition structure contains setup information for a semaphore.
+/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_semaphore_def  {
+  uint32_t                   dummy;    ///< dummy value.
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  osStaticSemaphoreDef_t     *controlblock;      ///< control block for static allocation; NULL for dynamic allocation
+#endif
+} osSemaphoreDef_t;
+
+/// Definition structure for memory block allocation.
+/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_def  {
+  uint32_t                 pool_sz;    ///< number of items (elements) in the pool
+  uint32_t                 item_sz;    ///< size of an item
+  void                       *pool;    ///< pointer to memory for pool
+} osPoolDef_t;
+
+/// Definition structure for message queue.
+/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_messageQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  uint32_t                item_sz;    ///< size of an item
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  uint8_t                 *buffer;      ///< buffer for static allocation; NULL for dynamic allocation
+  osStaticMessageQDef_t   *controlblock;     ///< control block to hold queue's data for static allocation; NULL for dynamic allocation
+#endif
+  //void                       *pool;    ///< memory array for messages
+} osMessageQDef_t;
+
+/// Definition structure for mail queue.
+/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  uint32_t                 item_sz;    ///< size of an item
+  struct os_mailQ_cb **cb;
+} osMailQDef_t;
+
+/// Event structure contains detailed information about an event.
+/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
+///       However the struct may be extended at the end.
+typedef struct  {
+  osStatus                 status;     ///< status code: event or error information
+  union  {
+    uint32_t                    v;     ///< message as 32-bit value
+    void                       *p;     ///< message or mail as void pointer
+    int32_t               signals;     ///< signal flags
+  } value;                             ///< event value
+  union  {
+    osMailQId             mail_id;     ///< mail id obtained by \ref osMailCreate
+    osMessageQId       message_id;     ///< message id obtained by \ref osMessageCreate
+  } def;                               ///< event definition
+} osEvent;
+
+
+//  ==== Kernel Control Functions ====
+
+/// Initialize the RTOS Kernel for creating objects.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
+osStatus osKernelInitialize (void);
+
+/// Start the RTOS Kernel.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
+osStatus osKernelStart (void);
+
+/// Check if the RTOS kernel is already started.
+/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
+/// \return 0 RTOS is not started, 1 RTOS is started.
+int32_t osKernelRunning(void);
+
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+
+/// Get the RTOS kernel system timer counter 
+/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+/// \return RTOS kernel system timer as 32-bit value 
+uint32_t osKernelSysTick (void);
+
+/// The RTOS kernel system timer frequency in Hz
+/// \note Reflects the system timer setting and is typically defined in a configuration file.
+#define osKernelSysTickFrequency      (configTICK_RATE_HZ)
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to the \ref osKernelSysTickFrequency
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
+
+#endif    // System Timer available
+
+//  ==== Thread Management ====
+
+/// Create a Thread Definition with function, priority, and stack requirements.
+/// \param         name         name of the thread function.
+/// \param         priority     initial priority of the thread function.
+/// \param         instances    number of possible thread instances.
+/// \param         stacksz      stack size (in bytes) requirements for the thread function.
+/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osThreadDef(name, thread, priority, instances, stacksz)  \
+extern const osThreadDef_t os_thread_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osThreadDef(name, thread, priority, instances, stacksz)  \
+const osThreadDef_t os_thread_def_##name = \
+{ #name, (thread), (priority), (instances), (stacksz), NULL, NULL }
+
+#define osThreadStaticDef(name, thread, priority, instances, stacksz, buffer, control)  \
+const osThreadDef_t os_thread_def_##name = \
+{ #name, (thread), (priority), (instances), (stacksz), (buffer), (control) }
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+
+#define osThreadDef(name, thread, priority, instances, stacksz)  \
+const osThreadDef_t os_thread_def_##name = \
+{ #name, (thread), (priority), (instances), (stacksz)}
+#endif
+#endif
+
+/// Access a Thread definition.
+/// \param         name          name of the thread definition object.
+/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osThread(name)  \
+&os_thread_def_##name
+
+/// Create a thread and add it to Active Threads and set it to state READY.
+/// \param[in]     thread_def    thread definition referenced with \ref osThread.
+/// \param[in]     argument      pointer that is passed to the thread function as start argument.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
+
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadGetId (void);
+
+/// Terminate execution of a thread and remove it from Active Threads.
+/// \param[in]     thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
+osStatus osThreadTerminate (osThreadId thread_id);
+
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
+osStatus osThreadYield (void);
+
+/// Change priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     priority      new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
+
+/// Get current priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return current priority value of the thread function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
+osPriority osThreadGetPriority (osThreadId thread_id);
+
+
+//  ==== Generic Wait Functions ====
+
+/// Wait for Timeout (Time Delay).
+/// \param[in]     millisec      time delay value
+/// \return status code that indicates the execution status of the function.
+osStatus osDelay (uint32_t millisec);
+
+#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0))     // Generic Wait available
+
+/// Wait for Signal, Message, Mail, or Timeout.
+/// \param[in] millisec          timeout value or 0 in case of no time-out
+/// \return event that contains signal, message, or mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
+osEvent osWait (uint32_t millisec);
+
+#endif  // Generic Wait available
+
+
+//  ==== Timer Management Functions ====
+/// Define a Timer object.
+/// \param         name          name of the timer object.
+/// \param         function      name of the timer call back function.
+/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osTimerDef(name, function)  \
+extern const osTimerDef_t os_timer_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) 
+#define osTimerDef(name, function)  \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), NULL }
+
+#define osTimerStaticDef(name, function, control)  \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), (control) }
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+#define osTimerDef(name, function)  \
+const osTimerDef_t os_timer_def_##name = \
+{ (function) }
+#endif
+#endif
+
+/// Access a Timer definition.
+/// \param         name          name of the timer object.
+/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osTimer(name) \
+&os_timer_def_##name
+
+/// Create a timer.
+/// \param[in]     timer_def     timer object referenced with \ref osTimer.
+/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in]     argument      argument to the timer call back function.
+/// \return timer ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
+
+/// Start or restart a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \param[in]     millisec      time delay value of the timer.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
+
+/// Stop the timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStop (osTimerId timer_id);
+
+/// Delete a timer that was created by \ref osTimerCreate.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
+osStatus osTimerDelete (osTimerId timer_id);
+
+
+//  ==== Signal Management ====
+
+/// Set the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that should be set.
+/// \return osOK if successful, osErrorOS if failed.
+/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
+int32_t osSignalSet (osThreadId thread_id, int32_t signals);
+
+/// Clear the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that shall be cleared.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
+int32_t osSignalClear (osThreadId thread_id, int32_t signals);
+
+/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+/// \param[in]     signals       wait until all specified signal flags set or 0 for any single signal flag.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return event flag information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
+osEvent osSignalWait (int32_t signals, uint32_t millisec);
+
+
+//  ==== Mutex Management ====
+
+/// Define a Mutex.
+/// \param         name          name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMutexDef(name)  \
+extern const osMutexDef_t os_mutex_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osMutexDef(name)  \
+const osMutexDef_t os_mutex_def_##name = { 0, NULL }
+
+#define osMutexStaticDef(name, control)  \
+const osMutexDef_t os_mutex_def_##name = { 0, (control) }
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+#define osMutexDef(name)  \
+const osMutexDef_t os_mutex_def_##name = { 0 }
+
+#endif
+
+#endif
+
+/// Access a Mutex definition.
+/// \param         name          name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMutex(name)  \
+&os_mutex_def_##name
+
+/// Create and Initialize a Mutex object.
+/// \param[in]     mutex_def     mutex definition referenced with \ref osMutex.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
+
+/// Wait until a Mutex becomes available.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/// Release a Mutex that was obtained by \ref osMutexWait.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
+osStatus osMutexRelease (osMutexId mutex_id);
+
+/// Delete a Mutex that was created by \ref osMutexCreate.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
+osStatus osMutexDelete (osMutexId mutex_id);
+
+
+//  ==== Semaphore Management Functions ====
+
+#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))     // Semaphore available
+
+/// Define a Semaphore object.
+/// \param         name          name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osSemaphoreDef(name)  \
+extern const osSemaphoreDef_t os_semaphore_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osSemaphoreDef(name)  \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0, NULL }
+
+#define osSemaphoreStaticDef(name, control)  \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0, (control) }
+
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+#define osSemaphoreDef(name)  \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
+#endif
+#endif
+
+/// Access a Semaphore definition.
+/// \param         name          name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osSemaphore(name)  \
+&os_semaphore_def_##name
+
+/// Create and Initialize a Semaphore object used for managing resources.
+/// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore.
+/// \param[in]     count         number of available resources.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
+
+/// Wait until a Semaphore token becomes available.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return number of available tokens, or -1 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+
+/// Release a Semaphore token.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
+
+/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
+
+#endif     // Semaphore available
+
+
+//  ==== Memory Pool Management Functions ====
+
+#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0))  // Memory Pool Management available
+
+/// \brief Define a Memory Pool.
+/// \param         name          name of the memory pool.
+/// \param         no            maximum number of blocks (objects) in the memory pool.
+/// \param         type          data type of a single block (object).
+/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osPoolDef(name, no, type)   \
+extern const osPoolDef_t os_pool_def_##name
+#else                            // define the object
+#define osPoolDef(name, no, type)   \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), NULL }
+#endif
+
+/// \brief Access a Memory Pool definition.
+/// \param         name          name of the memory pool
+/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osPool(name) \
+&os_pool_def_##name
+
+/// Create and Initialize a memory pool.
+/// \param[in]     pool_def      memory pool definition referenced with \ref osPool.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
+osPoolId osPoolCreate (const osPoolDef_t *pool_def);
+
+/// Allocate a memory block from a memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolAlloc (osPoolId pool_id);
+
+/// Allocate a memory block from a memory pool and set memory block to zero.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolCAlloc (osPoolId pool_id);
+
+/// Return an allocated memory block back to a specific memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \param[in]     block         address of the allocated memory block that is returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
+osStatus osPoolFree (osPoolId pool_id, void *block);
+
+#endif   // Memory Pool Management available
+
+
+//  ==== Message Queue Management Functions ====
+
+#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0))     // Message Queues available
+
+/// \brief Create a Message Queue Definition.
+/// \param         name          name of the queue.
+/// \param         queue_sz      maximum number of messages in the queue.
+/// \param         type          data type of a single message element (for debugger).
+/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMessageQDef(name, queue_sz, type)   \
+extern const osMessageQDef_t os_messageQ_def_##name
+#else                            // define the object
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osMessageQDef(name, queue_sz, type)   \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type), NULL, NULL  }
+
+#define osMessageQStaticDef(name, queue_sz, type, buffer, control)   \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type) , (buffer), (control)}
+#else //configSUPPORT_STATIC_ALLOCATION == 1
+#define osMessageQDef(name, queue_sz, type)   \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type) }
+
+#endif
+#endif
+
+/// \brief Access a Message Queue Definition.
+/// \param         name          name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMessageQ(name) \
+&os_messageQ_def_##name
+
+/// Create and Initialize a Message Queue.
+/// \param[in]     queue_def     queue definition referenced with \ref osMessageQ.
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+
+/// Put a Message to a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     info          message information.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+
+/// Get a Message or Wait for a Message from a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return event information that includes status code.
+/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
+
+#endif     // Message Queues available
+
+
+//  ==== Mail Queue Management Functions ====
+
+#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))     // Mail Queues available
+
+/// \brief Create a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \param         queue_sz      maximum number of messages in queue
+/// \param         type          data type of a single message element
+/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMailQDef(name, queue_sz, type) \
+extern struct os_mailQ_cb *os_mailQ_cb_##name \
+extern osMailQDef_t os_mailQ_def_##name
+#else                            // define the object
+#define osMailQDef(name, queue_sz, type) \
+struct os_mailQ_cb *os_mailQ_cb_##name; \
+const osMailQDef_t os_mailQ_def_##name =  \
+{ (queue_sz), sizeof (type), (&os_mailQ_cb_##name) }
+#endif
+
+/// \brief Access a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMailQ(name)  \
+&os_mailQ_def_##name
+
+/// Create and Initialize mail queue.
+/// \param[in]     queue_def     reference to the mail queue definition obtain with \ref osMailQ
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return mail queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
+
+/// Allocate a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Allocate a memory block from a mail and set memory block to zero.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Put a mail to a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
+osStatus osMailPut (osMailQId queue_id, void *mail);
+
+/// Get a mail from a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return event that contains mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
+
+/// Free a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          pointer to the memory block that was obtained with \ref osMailGet.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
+osStatus osMailFree (osMailQId queue_id, void *mail);
+
+#endif  // Mail Queues available
+
+/*************************** Additional specific APIs to Free RTOS ************/
+/**
+* @brief  Handles the tick increment
+* @param  none.
+* @retval none.
+*/
+void osSystickHandler(void);
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/**
+* @brief  Obtain the state of any thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  the stae of the thread, states are encoded by the osThreadState enumerated type.
+*/
+osThreadState osThreadGetState(osThreadId thread_id);
+#endif /* INCLUDE_eTaskGetState */
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/**
+* @brief Check if a thread is already suspended or not.
+* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval status code that indicates the execution status of the function.
+*/
+
+osStatus osThreadIsSuspended(osThreadId thread_id);
+
+#endif /* INCLUDE_eTaskGetState */
+
+/**
+* @brief  Suspend execution of a thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspend (osThreadId thread_id);
+
+/**
+* @brief  Resume execution of a suspended thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResume (osThreadId thread_id);
+
+/**
+* @brief  Suspend execution of a all active threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspendAll (void);
+
+/**
+* @brief  Resume execution of a all suspended threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResumeAll (void);
+
+/**
+* @brief  Delay a task until a specified time
+* @param   PreviousWakeTime   Pointer to a variable that holds the time at which the 
+*          task was last unblocked. PreviousWakeTime must be initialised with the current time
+*          prior to its first use (PreviousWakeTime = osKernelSysTick() )
+* @param   millisec    time delay value
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec);
+
+/**
+* @brief   Abort the delay for a specific thread
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId   
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osAbortDelay(osThreadId thread_id);
+
+/**
+* @brief   Lists all the current threads, along with their current state 
+*          and stack usage high water mark.
+* @param   buffer   A buffer into which the above mentioned details
+*          will be written
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadList (uint8_t *buffer);
+
+/**
+* @brief  Receive an item from a queue without removing the item from the queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval event information that includes status code.
+*/
+osEvent osMessagePeek (osMessageQId queue_id, uint32_t millisec);
+
+/**
+* @brief  Get the number of messaged stored in a queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval number of messages stored in a queue.
+*/
+uint32_t osMessageWaiting(osMessageQId queue_id);
+
+/**
+* @brief  Get the available space in a message queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval available space in a message queue.
+*/
+uint32_t osMessageAvailableSpace(osMessageQId queue_id);
+
+/**
+* @brief Delete a Message Queue
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osMessageDelete (osMessageQId queue_id);
+
+/**
+* @brief  Create and Initialize a Recursive Mutex
+* @param  mutex_def     mutex definition referenced with \ref osMutex.
+* @retval  mutex ID for reference by other functions or NULL in case of error..
+*/
+osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def);
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id      mutex ID obtained by \ref osRecursiveMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexRelease (osMutexId mutex_id);
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id    mutex ID obtained by \ref osRecursiveMutexCreate.
+* @param millisec      timeout value or 0 in case of no time-out.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/**
+* @brief  Returns the current count value of a counting semaphore
+* @param   semaphore_id  semaphore_id ID obtained by \ref osSemaphoreCreate.
+* @retval  count value
+*/
+uint32_t osSemaphoreGetCount(osSemaphoreId semaphore_id);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  // _CMSIS_OS_H

+ 236 - 238
cube_example/usb_hid_example/USB_Device/App/usbd_custom_hid_if.c

@@ -1,238 +1,236 @@
-/* USER CODE BEGIN Header */
-/**
-  ******************************************************************************
-  * @file           : usbd_custom_hid_if.c
-  * @version        : v3.0_Cube
-  * @brief          : USB Device Custom HID interface file.
-  ******************************************************************************
-  * @attention
-  *
-  * Copyright (c) 2025 STMicroelectronics.
-  * All rights reserved.
-  *
-  * This software is licensed under terms that can be found in the LICENSE file
-  * in the root directory of this software component.
-  * If no LICENSE file comes with this software, it is provided AS-IS.
-  *
-  ******************************************************************************
-  */
-/* USER CODE END Header */
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_custom_hid_if.h"
-#include "custom_hid_test.h"
-    
-/* USER CODE BEGIN INCLUDE */
-
-/* USER CODE END INCLUDE */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-
-/* USER CODE BEGIN PV */
-/* Private variables ---------------------------------------------------------*/
-
-/* USER CODE END PV */
-
-/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
-  * @brief Usb device.
-  * @{
-  */
-
-/** @addtogroup USBD_CUSTOM_HID
-  * @{
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions USBD_CUSTOM_HID_Private_TypesDefinitions
-  * @brief Private types.
-  * @{
-  */
-
-/* USER CODE BEGIN PRIVATE_TYPES */
-
-/* USER CODE END PRIVATE_TYPES */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_Defines USBD_CUSTOM_HID_Private_Defines
-  * @brief Private defines.
-  * @{
-  */
-
-/* USER CODE BEGIN PRIVATE_DEFINES */
-
-/* USER CODE END PRIVATE_DEFINES */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_Macros USBD_CUSTOM_HID_Private_Macros
-  * @brief Private macros.
-  * @{
-  */
-
-/* USER CODE BEGIN PRIVATE_MACRO */
-
-/* USER CODE END PRIVATE_MACRO */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_Variables USBD_CUSTOM_HID_Private_Variables
-  * @brief Private variables.
-  * @{
-  */
-
-/** Usb HID report descriptor. */
-__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
-{
-  /* USER CODE BEGIN 0 */
-		0x06, 0x00, 0xff, // Usage Page(Undefined )
-		0x09, 0x01, // USAGE (Undefined)
-		0xa1, 0x01, // COLLECTION (Application)
-		0x15, 0x00, // LOGICAL_MINIMUM (0)
-		0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
-		0x75, 0x08, // REPORT_SIZE (8)
-		0x95, 0x40, // REPORT_COUNT (64)
-		0x09, 0x01, // USAGE (Undefined)
-		0x81, 0x02, // INPUT (Data,Var,Abs)
-		0x95, 0x40, // REPORT_COUNT (64)
-		0x09, 0x01, // USAGE (Undefined)
-		0x91, 0x02, // OUTPUT (Data,Var,Abs)
-		0x95, 0x01, // REPORT_COUNT (1)
-		0x09, 0x01, // USAGE (Undefined)
-		0xb1, 0x02, // FEATURE (Data,Var,Abs)
-  /* USER CODE END 0 */
-  0xC0    /*     END_COLLECTION	             */
-};
-
-/* USER CODE BEGIN PRIVATE_VARIABLES */
-
-/* USER CODE END PRIVATE_VARIABLES */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Exported_Variables USBD_CUSTOM_HID_Exported_Variables
-  * @brief Public variables.
-  * @{
-  */
-extern USBD_HandleTypeDef hUsbDeviceFS;
-
-/* USER CODE BEGIN EXPORTED_VARIABLES */
-
-/* USER CODE END EXPORTED_VARIABLES */
-/**
-  * @}
-  */
-
-/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes USBD_CUSTOM_HID_Private_FunctionPrototypes
-  * @brief Private functions declaration.
-  * @{
-  */
-
-static int8_t CUSTOM_HID_Init_FS(void);
-static int8_t CUSTOM_HID_DeInit_FS(void);
-static int8_t CUSTOM_HID_OutEvent_FS(uint8_t *state);
-
-/**
-  * @}
-  */
-
-USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops_FS =
-{
-  CUSTOM_HID_ReportDesc_FS,
-  CUSTOM_HID_Init_FS,
-  CUSTOM_HID_DeInit_FS,
-  CUSTOM_HID_OutEvent_FS
-};
-
-/** @defgroup USBD_CUSTOM_HID_Private_Functions USBD_CUSTOM_HID_Private_Functions
-  * @brief Private functions.
-  * @{
-  */
-
-/* Private functions ---------------------------------------------------------*/
-
-/**
-  * @brief  Initializes the CUSTOM HID media low layer
-  * @retval USBD_OK if all operations are OK else USBD_FAIL
-  */
-static int8_t CUSTOM_HID_Init_FS(void)
-{
-  /* USER CODE BEGIN 4 */
-  return (USBD_OK);
-  /* USER CODE END 4 */
-}
-
-/**
-  * @brief  DeInitializes the CUSTOM HID media low layer
-  * @retval USBD_OK if all operations are OK else USBD_FAIL
-  */
-static int8_t CUSTOM_HID_DeInit_FS(void)
-{
-  /* USER CODE BEGIN 5 */
-  return (USBD_OK);
-  /* USER CODE END 5 */
-}
-
-/**
-  * @brief  Manage the CUSTOM HID class events
-  * @param  event_idx: Event index
-  * @param  state: Event state
-  * @retval USBD_OK if all operations are OK else USBD_FAIL
-  */
-static int8_t CUSTOM_HID_OutEvent_FS(uint8_t *state)
-{
-#if 0  
-  /* USER CODE BEGIN 6 */
-  //UNUSED(event_idx);
-  UNUSED(state);
-
-  /* Start next USB packet transfer once data processing is completed */
-  USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS);
-#endif
-  
-  usb_test_rx_data_copy(state);
-  usb_test_set_rx_flag();
-    
-  return (USBD_OK);
-  /* USER CODE END 6 */
-}
-
-/* USER CODE BEGIN 7 */
-/**
-  * @brief  Send the report to the Host
-  * @param  report: The report to be sent
-  * @param  len: The report length
-  * @retval USBD_OK if all operations are OK else USBD_FAIL
-  */
-/*
-static int8_t USBD_CUSTOM_HID_SendReport_FS(uint8_t *report, uint16_t len)
-{
-  return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len);
-}
-*/
-/* USER CODE END 7 */
-
-/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
-
-/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : usbd_custom_hid_if.c
+  * @version        : v3.0_Cube
+  * @brief          : USB Device Custom HID interface file.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2025 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_custom_hid_if.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE END PV */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @brief Usb device.
+  * @{
+  */
+
+/** @addtogroup USBD_CUSTOM_HID
+  * @{
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions USBD_CUSTOM_HID_Private_TypesDefinitions
+  * @brief Private types.
+  * @{
+  */
+
+/* USER CODE BEGIN PRIVATE_TYPES */
+
+/* USER CODE END PRIVATE_TYPES */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Defines USBD_CUSTOM_HID_Private_Defines
+  * @brief Private defines.
+  * @{
+  */
+
+/* USER CODE BEGIN PRIVATE_DEFINES */
+
+/* USER CODE END PRIVATE_DEFINES */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Macros USBD_CUSTOM_HID_Private_Macros
+  * @brief Private macros.
+  * @{
+  */
+
+/* USER CODE BEGIN PRIVATE_MACRO */
+
+/* USER CODE END PRIVATE_MACRO */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Variables USBD_CUSTOM_HID_Private_Variables
+  * @brief Private variables.
+  * @{
+  */
+
+/** Usb HID report descriptor. */
+__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
+{
+  /* USER CODE BEGIN 0 */
+		0x06, 0x00, 0xff, // Usage Page(Undefined )
+		0x09, 0x01, // USAGE (Undefined)
+		0xa1, 0x01, // COLLECTION (Application)
+		0x15, 0x00, // LOGICAL_MINIMUM (0)
+		0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
+		0x75, 0x08, // REPORT_SIZE (8)
+		0x95, 0x40, // REPORT_COUNT (64)
+		0x09, 0x01, // USAGE (Undefined)
+		0x81, 0x02, // INPUT (Data,Var,Abs)
+		0x95, 0x40, // REPORT_COUNT (64)
+		0x09, 0x01, // USAGE (Undefined)
+		0x91, 0x02, // OUTPUT (Data,Var,Abs)
+		0x95, 0x01, // REPORT_COUNT (1)
+		0x09, 0x01, // USAGE (Undefined)
+		0xb1, 0x02, // FEATURE (Data,Var,Abs)
+  /* USER CODE END 0 */
+  0xC0    /*     END_COLLECTION	             */
+};
+
+/* USER CODE BEGIN PRIVATE_VARIABLES */
+
+/* USER CODE END PRIVATE_VARIABLES */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Variables USBD_CUSTOM_HID_Exported_Variables
+  * @brief Public variables.
+  * @{
+  */
+extern USBD_HandleTypeDef hUsbDeviceFS;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes USBD_CUSTOM_HID_Private_FunctionPrototypes
+  * @brief Private functions declaration.
+  * @{
+  */
+
+static int8_t CUSTOM_HID_Init_FS(void);
+static int8_t CUSTOM_HID_DeInit_FS(void);
+static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state);
+
+/**
+  * @}
+  */
+
+USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops_FS =
+{
+  CUSTOM_HID_ReportDesc_FS,
+  CUSTOM_HID_Init_FS,
+  CUSTOM_HID_DeInit_FS,
+  CUSTOM_HID_OutEvent_FS
+};
+
+/** @defgroup USBD_CUSTOM_HID_Private_Functions USBD_CUSTOM_HID_Private_Functions
+  * @brief Private functions.
+  * @{
+  */
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+  * @brief  Initializes the CUSTOM HID media low layer
+  * @retval USBD_OK if all operations are OK else USBD_FAIL
+  */
+static int8_t CUSTOM_HID_Init_FS(void)
+{
+  /* USER CODE BEGIN 4 */
+  return (USBD_OK);
+  /* USER CODE END 4 */
+}
+
+/**
+  * @brief  DeInitializes the CUSTOM HID media low layer
+  * @retval USBD_OK if all operations are OK else USBD_FAIL
+  */
+static int8_t CUSTOM_HID_DeInit_FS(void)
+{
+  /* USER CODE BEGIN 5 */
+  return (USBD_OK);
+  /* USER CODE END 5 */
+}
+
+/**
+  * @brief  Manage the CUSTOM HID class events
+  * @param  event_idx: Event index
+  * @param  state: Event state
+  * @retval USBD_OK if all operations are OK else USBD_FAIL
+  */
+static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
+{
+  /* USER CODE BEGIN 6 */
+  //UNUSED(event_idx);
+  UNUSED(state);
+
+  /* Start next USB packet transfer once data processing is completed */
+  USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS);
+#endif
+  
+  usb_test_rx_data_copy(state);
+  usb_test_set_rx_flag();
+    
+  return (USBD_OK);
+  /* USER CODE END 6 */
+}
+
+/* USER CODE BEGIN 7 */
+/**
+  * @brief  Send the report to the Host
+  * @param  report: The report to be sent
+  * @param  len: The report length
+  * @retval USBD_OK if all operations are OK else USBD_FAIL
+  */
+/*
+static int8_t USBD_CUSTOM_HID_SendReport_FS(uint8_t *report, uint16_t len)
+{
+  return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len);
+}
+*/
+/* USER CODE END 7 */
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+

+ 5 - 5
cube_example/usb_hid_example/usb_hid_example.ioc

@@ -3,7 +3,7 @@ CAD.formats=
 CAD.pinconfig=
 CAD.provider=
 FREERTOS.IPParameters=Tasks01
-FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
+FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
 File.Version=6
 GPIO.groupedBy=
 I2C2.IPParameters=Timing
@@ -42,7 +42,7 @@ Mcu.Pin20=PA8
 Mcu.Pin21=PA11
 Mcu.Pin22=PA12
 Mcu.Pin23=PB3
-Mcu.Pin24=VP_FREERTOS_VS_CMSIS_V2
+Mcu.Pin24=VP_FREERTOS_VS_CMSIS_V1
 Mcu.Pin25=VP_RTC_VS_RTC_Activate
 Mcu.Pin26=VP_SYS_VS_Systick
 Mcu.Pin27=VP_SYS_VS_DBSignals
@@ -169,7 +169,7 @@ ProjectManager.ToolChainLocation=
 ProjectManager.UAScriptAfterPath=
 ProjectManager.UAScriptBeforePath=
 ProjectManager.UnderRoot=false
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_RTC_Init-RTC-false-HAL-true,4-MX_USB_Device_Init-USB_DEVICE-false-HAL-false
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_RTC_Init-RTC-false-HAL-true,4-MX_USB_Device_Init-USB_DEVICE-false-HAL-false,5-MX_I2C2_Init-I2C2-false-HAL-true,6-MX_TIM2_Init-TIM2-false-HAL-true,7-MX_USART2_UART_Init-USART2-false-HAL-true,8-MX_USART3_UART_Init-USART3-false-HAL-true
 RCC.ADC12Freq_Value=170000000
 RCC.AHBFreq_Value=170000000
 RCC.APB1Freq_Value=170000000
@@ -232,8 +232,8 @@ USB_DEVICE.USBD_CUSTOMHID_OUTREPORT_BUF_SIZE=64
 USB_DEVICE.USBD_CUSTOM_HID_REPORT_DESC_SIZE=33
 USB_DEVICE.VirtualMode=CustomHid
 USB_DEVICE.VirtualModeFS=Custom_Hid_FS
-VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
-VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
+VP_FREERTOS_VS_CMSIS_V1.Mode=CMSIS_V1
+VP_FREERTOS_VS_CMSIS_V1.Signal=FREERTOS_VS_CMSIS_V1
 VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
 VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
 VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals

+ 1727 - 0
desk/libs/thirdparty/freertos/CMSIS_RTOS/cmsis_os.c

@@ -0,0 +1,1727 @@
+/* ----------------------------------------------------------------------
+ * $Date:        5. February 2013
+ * $Revision:    V1.02
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.c
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedef's
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ *    
+ *  
+ *----------------------------------------------------------------------------
+ *
+ * Portions Copyright © 2016 STMicroelectronics International N.V. All rights reserved.
+ * Portions Copyright (c) 2013 ARM LIMITED
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include <string.h>
+#include "cmsis_os.h"
+
+/*
+ * ARM Compiler 4/5
+ */
+#if   defined ( __CC_ARM )
+
+  #define __ASM            __asm                                      
+  #define __INLINE         __inline                                     
+  #define __STATIC_INLINE  static __inline
+
+  #include "cmsis_armcc.h"
+
+/*
+ * GNU Compiler
+ */
+#elif defined ( __GNUC__ )
+
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+  #include "cmsis_gcc.h"
+
+
+/*
+ * IAR Compiler
+ */
+#elif defined ( __ICCARM__ )
+
+  #ifndef   __ASM
+    #define __ASM                     __asm
+  #endif
+  #ifndef   __INLINE
+    #define __INLINE                  inline
+  #endif
+  #ifndef   __STATIC_INLINE
+    #define __STATIC_INLINE           static inline
+  #endif
+
+  #include <cmsis_iar.h>
+#endif
+
+extern void xPortSysTickHandler(void);
+
+/* Convert from CMSIS type osPriority to FreeRTOS priority number */
+static unsigned portBASE_TYPE makeFreeRtosPriority (osPriority priority)
+{
+  unsigned portBASE_TYPE fpriority = tskIDLE_PRIORITY;
+  
+  if (priority != osPriorityError) {
+    fpriority += (priority - osPriorityIdle);
+  }
+  
+  return fpriority;
+}
+
+#if (INCLUDE_uxTaskPriorityGet == 1)
+/* Convert from FreeRTOS priority number to CMSIS type osPriority */
+static osPriority makeCmsisPriority (unsigned portBASE_TYPE fpriority)
+{
+  osPriority priority = osPriorityError;
+  
+  if ((fpriority - tskIDLE_PRIORITY) <= (osPriorityRealtime - osPriorityIdle)) {
+    priority = (osPriority)((int)osPriorityIdle + (int)(fpriority - tskIDLE_PRIORITY));
+  }
+  
+  return priority;
+}
+#endif
+
+
+/* Determine whether we are in thread mode or handler mode. */
+static int inHandlerMode (void)
+{
+  return __get_IPSR() != 0;
+}
+
+/*********************** Kernel Control Functions *****************************/
+/**
+* @brief  Initialize the RTOS Kernel for creating objects.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osKernelInitialize (void);
+
+/**
+* @brief  Start the RTOS Kernel with executing the specified thread.
+* @param  thread_def    thread definition referenced with \ref osThread.
+* @param  argument      pointer that is passed to the thread function as start argument.
+* @retval status code that indicates the execution status of the function
+* @note   MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osKernelStart (void)
+{
+  vTaskStartScheduler();
+  
+  return osOK;
+}
+
+/**
+* @brief  Check if the RTOS kernel is already started
+* @param  None
+* @retval (0) RTOS is not started
+*         (1) RTOS is started
+*         (-1) if this feature is disabled in FreeRTOSConfig.h 
+* @note  MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osKernelRunning(void)
+{
+#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
+  if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED)
+    return 0;
+  else
+    return 1;
+#else
+	return (-1);
+#endif	
+}
+
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+/**
+* @brief  Get the value of the Kernel SysTick timer
+* @param  None
+* @retval None
+* @note   MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+*/
+uint32_t osKernelSysTick(void)
+{
+  if (inHandlerMode()) {
+    return xTaskGetTickCountFromISR();
+  }
+  else {
+    return xTaskGetTickCount();
+  }
+}
+#endif    // System Timer available
+/*********************** Thread Management *****************************/
+/**
+* @brief  Create a thread and add it to Active Threads and set it to state READY.
+* @param  thread_def    thread definition referenced with \ref osThread.
+* @param  argument      pointer that is passed to the thread function as start argument.
+* @retval thread ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
+*/
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)
+{
+  TaskHandle_t handle;
+  
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) &&  ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+  if((thread_def->buffer != NULL) && (thread_def->controlblock != NULL)) {
+    handle = xTaskCreateStatic((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+              thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+              thread_def->buffer, thread_def->controlblock);
+  }
+  else {
+    if (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+              thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+              &handle) != pdPASS)  {
+      return NULL;
+    } 
+  }
+#elif( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+    handle = xTaskCreateStatic((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+              thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+              thread_def->buffer, thread_def->controlblock);
+#else
+  if (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,
+                   thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),
+                   &handle) != pdPASS)  {
+    return NULL;
+  }     
+#endif
+  
+  return handle;
+}
+
+/**
+* @brief  Return the thread ID of the current running thread.
+* @retval thread ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
+*/
+osThreadId osThreadGetId (void)
+{
+#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
+  return xTaskGetCurrentTaskHandle();
+#else
+	return NULL;
+#endif
+}
+
+/**
+* @brief  Terminate execution of a thread and remove it from Active Threads.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osThreadTerminate (osThreadId thread_id)
+{
+#if (INCLUDE_vTaskDelete == 1)
+  vTaskDelete(thread_id);
+  return osOK;
+#else
+  return osErrorOS;
+#endif
+}
+
+/**
+* @brief  Pass control to next thread that is in state \b READY.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osThreadYield (void)
+{
+  taskYIELD();
+  
+  return osOK;
+}
+
+/**
+* @brief   Change priority of an active thread.
+* @param   thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @param   priority      new priority value for the thread function.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority)
+{
+#if (INCLUDE_vTaskPrioritySet == 1)
+  vTaskPrioritySet(thread_id, makeFreeRtosPriority(priority));
+  return osOK;
+#else
+  return osErrorOS;
+#endif
+}
+
+/**
+* @brief   Get current priority of an active thread.
+* @param   thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  current priority value of the thread function.
+* @note   MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
+*/
+osPriority osThreadGetPriority (osThreadId thread_id)
+{
+#if (INCLUDE_uxTaskPriorityGet == 1)
+  if (inHandlerMode())
+  {
+    return makeCmsisPriority(uxTaskPriorityGetFromISR(thread_id));  
+  }
+  else
+  {  
+    return makeCmsisPriority(uxTaskPriorityGet(thread_id));
+  }
+#else
+  return osPriorityError;
+#endif
+}
+
+/*********************** Generic Wait Functions *******************************/
+/**
+* @brief   Wait for Timeout (Time Delay)
+* @param   millisec      time delay value
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osDelay (uint32_t millisec)
+{
+#if INCLUDE_vTaskDelay
+  TickType_t ticks = millisec / portTICK_PERIOD_MS;
+  
+  vTaskDelay(ticks ? ticks : 1);          /* Minimum delay = 1 tick */
+  
+  return osOK;
+#else
+  (void) millisec;
+  
+  return osErrorResource;
+#endif
+}
+
+#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0)) /* Generic Wait available */
+/**
+* @brief  Wait for Signal, Message, Mail, or Timeout
+* @param   millisec  timeout value or 0 in case of no time-out
+* @retval  event that contains signal, message, or mail information or error code.
+* @note   MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osWait (uint32_t millisec);
+
+#endif  /* Generic Wait available */
+
+/***********************  Timer Management Functions ***************************/
+/**
+* @brief  Create a timer.
+* @param  timer_def     timer object referenced with \ref osTimer.
+* @param  type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+* @param  argument      argument to the timer call back function.
+* @retval  timer ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
+*/
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument)
+{
+#if (configUSE_TIMERS == 1)
+
+#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 
+  if(timer_def->controlblock != NULL) {
+    return xTimerCreateStatic((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer,
+                      (StaticTimer_t *)timer_def->controlblock);
+  }
+  else {
+    return xTimerCreate((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer);
+ }
+#elif( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xTimerCreateStatic((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer,
+                      (StaticTimer_t *)timer_def->controlblock);  
+#else
+  return xTimerCreate((const char *)"",
+                      1, // period should be filled when starting the Timer using osTimerStart
+                      (type == osTimerPeriodic) ? pdTRUE : pdFALSE,
+                      (void *) argument,
+                      (TimerCallbackFunction_t)timer_def->ptimer);
+#endif
+
+#else 
+	return NULL;
+#endif
+}
+
+/**
+* @brief  Start or restart a timer.
+* @param  timer_id      timer ID obtained by \ref osTimerCreate.
+* @param  millisec      time delay value of the timer.
+* @retval  status code that indicates the execution status of the function
+* @note   MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec)
+{
+  osStatus result = osOK;
+#if (configUSE_TIMERS == 1)  
+  portBASE_TYPE taskWoken = pdFALSE;
+  TickType_t ticks = millisec / portTICK_PERIOD_MS;
+
+  if (ticks == 0)
+    ticks = 1;
+    
+  if (inHandlerMode()) 
+  {
+    if (xTimerChangePeriodFromISR(timer_id, ticks, &taskWoken) != pdPASS)
+    {
+      result = osErrorOS;
+    }
+    else
+    {
+      portEND_SWITCHING_ISR(taskWoken);     
+    }
+  }
+  else 
+  {
+    if (xTimerChangePeriod(timer_id, ticks, 0) != pdPASS)
+      result = osErrorOS;
+  }
+
+#else 
+  result = osErrorOS;
+#endif
+  return result;
+}
+
+/**
+* @brief  Stop a timer.
+* @param  timer_id      timer ID obtained by \ref osTimerCreate
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osTimerStop (osTimerId timer_id)
+{
+  osStatus result = osOK;
+#if (configUSE_TIMERS == 1)  
+  portBASE_TYPE taskWoken = pdFALSE;
+
+  if (inHandlerMode()) {
+    if (xTimerStopFromISR(timer_id, &taskWoken) != pdPASS) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xTimerStop(timer_id, 0) != pdPASS) {
+      result = osErrorOS;
+    }
+  }
+#else 
+  result = osErrorOS;
+#endif 
+  return result;
+}
+
+/**
+* @brief  Delete a timer.
+* @param  timer_id      timer ID obtained by \ref osTimerCreate
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osTimerDelete (osTimerId timer_id)
+{
+osStatus result = osOK;
+
+#if (configUSE_TIMERS == 1)
+
+   if (inHandlerMode()) {
+     return osErrorISR;
+  }
+  else { 
+    if ((xTimerDelete(timer_id, osWaitForever )) != pdPASS) {
+      result = osErrorOS;
+    }
+  } 
+    
+#else 
+  result = osErrorOS;
+#endif 
+ 
+  return result;
+}
+
+/***************************  Signal Management ********************************/
+/**
+* @brief  Set the specified Signal Flags of an active thread.
+* @param  thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @param  signals       specifies the signal flags of the thread that should be set.
+* @retval previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+* @note   MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osSignalSet (osThreadId thread_id, int32_t signal)
+{
+#if( configUSE_TASK_NOTIFICATIONS == 1 )	
+  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+  uint32_t ulPreviousNotificationValue = 0;
+  
+  if (inHandlerMode())
+  {
+    if(xTaskGenericNotifyFromISR( thread_id , (uint32_t)signal, eSetBits, &ulPreviousNotificationValue, &xHigherPriorityTaskWoken ) != pdPASS )
+      return 0x80000000;
+    
+    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+  }  
+  else if(xTaskGenericNotify( thread_id , (uint32_t)signal, eSetBits, &ulPreviousNotificationValue) != pdPASS )
+    return 0x80000000;
+  
+  return ulPreviousNotificationValue;
+#else
+  (void) thread_id;
+  (void) signal;
+
+  return 0x80000000; /* Task Notification not supported */ 	
+#endif
+}
+
+/**
+* @brief  Clear the specified Signal Flags of an active thread.
+* @param  thread_id  thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @param  signals    specifies the signal flags of the thread that shall be cleared.
+* @retval  previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+* @note   MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osSignalClear (osThreadId thread_id, int32_t signal);
+
+/**
+* @brief  Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+* @param  signals   wait until all specified signal flags set or 0 for any single signal flag.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval  event flag information or error code.
+* @note   MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osSignalWait (int32_t signals, uint32_t millisec)
+{
+  osEvent ret;
+
+#if( configUSE_TASK_NOTIFICATIONS == 1 )
+	
+  TickType_t ticks;
+
+  ret.value.signals = 0;  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }  
+  
+  if (inHandlerMode())
+  {
+    ret.status = osErrorISR;  /*Not allowed in ISR*/
+  }
+  else
+  {
+    if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)
+    {
+      if(ticks == 0)  ret.status = osOK;
+      else  ret.status = osEventTimeout;
+    }
+    else if(ret.value.signals < 0)
+    {
+      ret.status =  osErrorValue;     
+    }
+    else  ret.status =  osEventSignal;
+  }
+#else
+  (void) signals;
+  (void) millisec;
+	
+  ret.status =  osErrorOS;	/* Task Notification not supported */
+#endif
+  
+  return ret;
+}
+
+/****************************  Mutex Management ********************************/
+/**
+* @brief  Create and Initialize a Mutex object
+* @param  mutex_def     mutex definition referenced with \ref osMutex.
+* @retval  mutex ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
+*/
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def)
+{
+#if ( configUSE_MUTEXES == 1)
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  if (mutex_def->controlblock != NULL) {
+    return xSemaphoreCreateMutexStatic( mutex_def->controlblock );
+     }
+  else {
+    return xSemaphoreCreateMutex(); 
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xSemaphoreCreateMutexStatic( mutex_def->controlblock );
+#else  
+    return xSemaphoreCreateMutex(); 
+#endif
+#else
+  return NULL;
+#endif
+}
+
+/**
+* @brief Wait until a Mutex becomes available
+* @param mutex_id      mutex ID obtained by \ref osMutexCreate.
+* @param millisec      timeout value or 0 in case of no time-out.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec)
+{
+  TickType_t ticks;
+  portBASE_TYPE taskWoken = pdFALSE;  
+  
+  
+  if (mutex_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreTakeFromISR(mutex_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+	portEND_SWITCHING_ISR(taskWoken);
+  } 
+  else if (xSemaphoreTake(mutex_id, ticks) != pdTRUE) {
+    return osErrorOS;
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Release a Mutex that was obtained by \ref osMutexWait
+* @param mutex_id      mutex ID obtained by \ref osMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMutexRelease (osMutexId mutex_id)
+{
+  osStatus result = osOK;
+  portBASE_TYPE taskWoken = pdFALSE;
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreGiveFromISR(mutex_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else if (xSemaphoreGive(mutex_id) != pdTRUE) 
+  {
+    result = osErrorOS;
+  }
+  return result;
+}
+
+/**
+* @brief Delete a Mutex
+* @param mutex_id  mutex ID obtained by \ref osMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMutexDelete (osMutexId mutex_id)
+{
+  if (inHandlerMode()) {
+    return osErrorISR;
+  }
+
+  vQueueDelete(mutex_id);
+
+  return osOK;
+}
+
+/********************  Semaphore Management Functions **************************/
+
+#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))
+
+/**
+* @brief Create and Initialize a Semaphore object used for managing resources
+* @param semaphore_def semaphore definition referenced with \ref osSemaphore.
+* @param count         number of available resources.
+* @retval  semaphore ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
+*/
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count)
+{ 
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  osSemaphoreId sema;
+  
+  if (semaphore_def->controlblock != NULL){
+    if (count == 1) {
+      return xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
+    }
+    else {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )
+      return xSemaphoreCreateCountingStatic( count, count, semaphore_def->controlblock );
+#else
+      return NULL;
+#endif
+    }
+  }
+  else {
+    if (count == 1) {
+      vSemaphoreCreateBinary(sema);
+      return sema;
+    }
+    else {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )	
+      return xSemaphoreCreateCounting(count, count);
+#else
+      return NULL;
+#endif    
+    }
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 ) // configSUPPORT_DYNAMIC_ALLOCATION == 0
+  if(count == 1) {
+    return xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
+  }
+  else
+  {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )
+      return xSemaphoreCreateCountingStatic( count, count, semaphore_def->controlblock );
+#else
+      return NULL;
+#endif    
+  }
+#else  // configSUPPORT_STATIC_ALLOCATION == 0  && configSUPPORT_DYNAMIC_ALLOCATION == 1
+  osSemaphoreId sema;
+ 
+  if (count == 1) {
+    vSemaphoreCreateBinary(sema);
+    return sema;
+  }
+  else {
+#if (configUSE_COUNTING_SEMAPHORES == 1 )	
+    return xSemaphoreCreateCounting(count, count);
+#else
+    return NULL;
+#endif
+  }
+#endif
+}
+
+/**
+* @brief Wait until a Semaphore token becomes available
+* @param  semaphore_id  semaphore object referenced with \ref osSemaphore.
+* @param  millisec      timeout value or 0 in case of no time-out.
+* @retval  number of available tokens, or -1 in case of incorrect parameters.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
+*/
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
+{
+  TickType_t ticks;
+  portBASE_TYPE taskWoken = pdFALSE;  
+  
+  
+  if (semaphore_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreTakeFromISR(semaphore_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+	portEND_SWITCHING_ISR(taskWoken);
+  }  
+  else if (xSemaphoreTake(semaphore_id, ticks) != pdTRUE) {
+    return osErrorOS;
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Release a Semaphore token
+* @param  semaphore_id  semaphore object referenced with \ref osSemaphore.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
+{
+  osStatus result = osOK;
+  portBASE_TYPE taskWoken = pdFALSE;
+  
+  
+  if (inHandlerMode()) {
+    if (xSemaphoreGiveFromISR(semaphore_id, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xSemaphoreGive(semaphore_id) != pdTRUE) {
+      result = osErrorOS;
+    }
+  }
+  
+  return result;
+}
+
+/**
+* @brief Delete a Semaphore
+* @param  semaphore_id  semaphore object referenced with \ref osSemaphore.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id)
+{
+  if (inHandlerMode()) {
+    return osErrorISR;
+  }
+
+  vSemaphoreDelete(semaphore_id);
+
+  return osOK; 
+}
+
+#endif    /* Use Semaphores */
+
+/*******************   Memory Pool Management Functions  ***********************/
+
+#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0)) 
+
+//TODO
+//This is a primitive and inefficient wrapper around the existing FreeRTOS memory management.
+//A better implementation will have to modify heap_x.c!
+
+
+typedef struct os_pool_cb {
+  void *pool;
+  uint8_t *markers;
+  uint32_t pool_sz;
+  uint32_t item_sz;
+  uint32_t currentIndex;
+} os_pool_cb_t;
+
+
+/**
+* @brief Create and Initialize a memory pool
+* @param  pool_def      memory pool definition referenced with \ref osPool.
+* @retval  memory pool ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
+*/
+osPoolId osPoolCreate (const osPoolDef_t *pool_def)
+{
+#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+  osPoolId thePool;
+  int itemSize = 4 * ((pool_def->item_sz + 3) / 4);
+  uint32_t i;
+  
+  /* First have to allocate memory for the pool control block. */
+ thePool = pvPortMalloc(sizeof(os_pool_cb_t));
+
+  
+  if (thePool) {
+    thePool->pool_sz = pool_def->pool_sz;
+    thePool->item_sz = itemSize;
+    thePool->currentIndex = 0;
+    
+    /* Memory for markers */
+    thePool->markers = pvPortMalloc(pool_def->pool_sz);
+   
+    if (thePool->markers) {
+      /* Now allocate the pool itself. */
+     thePool->pool = pvPortMalloc(pool_def->pool_sz * itemSize);
+      
+      if (thePool->pool) {
+        for (i = 0; i < pool_def->pool_sz; i++) {
+          thePool->markers[i] = 0;
+        }
+      }
+      else {
+        vPortFree(thePool->markers);
+        vPortFree(thePool);
+        thePool = NULL;
+      }
+    }
+    else {
+      vPortFree(thePool);
+      thePool = NULL;
+    }
+  }
+
+  return thePool;
+ 
+#else
+  return NULL;
+#endif
+}
+
+/**
+* @brief Allocate a memory block from a memory pool
+* @param pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+* @retval  address of the allocated memory block or NULL in case of no memory available.
+* @note   MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osPoolAlloc (osPoolId pool_id)
+{
+  int dummy = 0;
+  void *p = NULL;
+  uint32_t i;
+  uint32_t index;
+  
+  if (inHandlerMode()) {
+    dummy = portSET_INTERRUPT_MASK_FROM_ISR();
+  }
+  else {
+    vPortEnterCritical();
+  }
+  
+  for (i = 0; i < pool_id->pool_sz; i++) {
+    index = (pool_id->currentIndex + i) % pool_id->pool_sz;
+    
+    if (pool_id->markers[index] == 0) {
+      pool_id->markers[index] = 1;
+      p = (void *)((uint32_t)(pool_id->pool) + (index * pool_id->item_sz));
+      pool_id->currentIndex = index;
+      break;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    portCLEAR_INTERRUPT_MASK_FROM_ISR(dummy);
+  }
+  else {
+    vPortExitCritical();
+  }
+  
+  return p;
+}
+
+/**
+* @brief Allocate a memory block from a memory pool and set memory block to zero
+* @param  pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+* @retval  address of the allocated memory block or NULL in case of no memory available.
+* @note   MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osPoolCAlloc (osPoolId pool_id)
+{
+  void *p = osPoolAlloc(pool_id);
+  
+  if (p != NULL)
+  {
+    memset(p, 0, sizeof(pool_id->pool_sz));
+  }
+  
+  return p;
+}
+
+/**
+* @brief Return an allocated memory block back to a specific memory pool
+* @param  pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+* @param  block         address of the allocated memory block that is returned to the memory pool.
+* @retval  status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osPoolFree (osPoolId pool_id, void *block)
+{
+  uint32_t index;
+  
+  if (pool_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  if (block == NULL) {
+    return osErrorParameter;
+  }
+  
+  if (block < pool_id->pool) {
+    return osErrorParameter;
+  }
+  
+  index = (uint32_t)block - (uint32_t)(pool_id->pool);
+  if (index % pool_id->item_sz) {
+    return osErrorParameter;
+  }
+  index = index / pool_id->item_sz;
+  if (index >= pool_id->pool_sz) {
+    return osErrorParameter;
+  }
+  
+  pool_id->markers[index] = 0;
+  
+  return osOK;
+}
+
+
+#endif   /* Use Memory Pool Management */
+
+/*******************   Message Queue Management Functions  *********************/
+
+#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0)) /* Use Message Queues */
+
+/**
+* @brief Create and Initialize a Message Queue
+* @param queue_def     queue definition referenced with \ref osMessageQ.
+* @param  thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+* @retval  message queue ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
+*/
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id)
+{
+  (void) thread_id;
+  
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  if ((queue_def->buffer != NULL) && (queue_def->controlblock != NULL)) {
+    return xQueueCreateStatic(queue_def->queue_sz, queue_def->item_sz, queue_def->buffer, queue_def->controlblock);
+  }
+  else {
+    return xQueueCreate(queue_def->queue_sz, queue_def->item_sz);
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xQueueCreateStatic(queue_def->queue_sz, queue_def->item_sz, queue_def->buffer, queue_def->controlblock);
+#else  
+  return xQueueCreate(queue_def->queue_sz, queue_def->item_sz);
+#endif
+}
+
+/**
+* @brief Put a Message to a Queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  info      message information.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec)
+{
+  portBASE_TYPE taskWoken = pdFALSE;
+  TickType_t ticks;
+  
+  ticks = millisec / portTICK_PERIOD_MS;
+  if (ticks == 0) {
+    ticks = 1;
+  }
+  
+  if (inHandlerMode()) {
+    if (xQueueSendFromISR(queue_id, &info, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueSend(queue_id, &info, ticks) != pdTRUE) {
+      return osErrorOS;
+    }
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Get a Message or Wait for a Message from a Queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval event information that includes status code.
+* @note   MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec)
+{
+  portBASE_TYPE taskWoken;
+  TickType_t ticks;
+  osEvent event;
+  
+  event.def.message_id = queue_id;
+  event.value.v = 0;
+  
+  if (queue_id == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+  
+  taskWoken = pdFALSE;
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xQueueReceiveFromISR(queue_id, &event.value.v, &taskWoken) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMessage;
+    }
+    else {
+      event.status = osOK;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueReceive(queue_id, &event.value.v, ticks) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMessage;
+    }
+    else {
+      event.status = (ticks == 0) ? osOK : osEventTimeout;
+    }
+  }
+  
+  return event;
+}
+
+#endif     /* Use Message Queues */
+
+/********************   Mail Queue Management Functions  ***********************/
+#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))  /* Use Mail Queues */
+
+
+typedef struct os_mailQ_cb {
+  const osMailQDef_t *queue_def;
+  QueueHandle_t handle;
+  osPoolId pool;
+} os_mailQ_cb_t;
+
+/**
+* @brief Create and Initialize mail queue
+* @param  queue_def     reference to the mail queue definition obtain with \ref osMailQ
+* @param   thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+* @retval mail queue ID for reference by other functions or NULL in case of error.
+* @note   MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
+*/
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id)
+{
+#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
+  (void) thread_id;
+  
+  osPoolDef_t pool_def = {queue_def->queue_sz, queue_def->item_sz, NULL};
+  
+  /* Create a mail queue control block */
+
+  *(queue_def->cb) = pvPortMalloc(sizeof(struct os_mailQ_cb));
+
+  if (*(queue_def->cb) == NULL) {
+    return NULL;
+  }
+  (*(queue_def->cb))->queue_def = queue_def;
+  
+  /* Create a queue in FreeRTOS */
+  (*(queue_def->cb))->handle = xQueueCreate(queue_def->queue_sz, sizeof(void *));
+
+
+  if ((*(queue_def->cb))->handle == NULL) {
+    vPortFree(*(queue_def->cb));
+    return NULL;
+  }
+  
+  /* Create a mail pool */
+  (*(queue_def->cb))->pool = osPoolCreate(&pool_def);
+  if ((*(queue_def->cb))->pool == NULL) {
+    //TODO: Delete queue. How to do it in FreeRTOS?
+    vPortFree(*(queue_def->cb));
+    return NULL;
+  }
+  
+  return *(queue_def->cb);
+#else
+  return NULL;
+#endif
+}
+
+/**
+* @brief Allocate a memory block from a mail
+* @param  queue_id      mail queue ID obtained with \ref osMailCreate.
+* @param  millisec      timeout value or 0 in case of no time-out.
+* @retval pointer to memory block that can be filled with mail or NULL in case error.
+* @note   MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec)
+{
+  (void) millisec;
+  void *p;
+  
+  
+  if (queue_id == NULL) {
+    return NULL;
+  }
+  
+  p = osPoolAlloc(queue_id->pool);
+  
+  return p;
+}
+
+/**
+* @brief Allocate a memory block from a mail and set memory block to zero
+* @param  queue_id      mail queue ID obtained with \ref osMailCreate.
+* @param  millisec      timeout value or 0 in case of no time-out.
+* @retval pointer to memory block that can be filled with mail or NULL in case error.
+* @note   MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
+*/
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec)
+{
+  uint32_t i;
+  void *p = osMailAlloc(queue_id, millisec);
+  
+  if (p) {
+    for (i = 0; i < queue_id->queue_def->item_sz; i++) {
+      ((uint8_t *)p)[i] = 0;
+    }
+  }
+  
+  return p;
+}
+
+/**
+* @brief Put a mail to a queue
+* @param  queue_id      mail queue ID obtained with \ref osMailCreate.
+* @param  mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMailPut (osMailQId queue_id, void *mail)
+{
+  portBASE_TYPE taskWoken;
+  
+  
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  taskWoken = pdFALSE;
+  
+  if (inHandlerMode()) {
+    if (xQueueSendFromISR(queue_id->handle, &mail, &taskWoken) != pdTRUE) {
+      return osErrorOS;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueSend(queue_id->handle, &mail, 0) != pdTRUE) { 
+      return osErrorOS;
+    }
+  }
+  
+  return osOK;
+}
+
+/**
+* @brief Get a mail from a queue
+* @param  queue_id   mail queue ID obtained with \ref osMailCreate.
+* @param millisec    timeout value or 0 in case of no time-out
+* @retval event that contains mail information or error code.
+* @note   MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
+*/
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec)
+{
+  portBASE_TYPE taskWoken;
+  TickType_t ticks;
+  osEvent event;
+  
+  event.def.mail_id = queue_id;
+  
+  if (queue_id == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+  
+  taskWoken = pdFALSE;
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (inHandlerMode()) {
+    if (xQueueReceiveFromISR(queue_id->handle, &event.value.p, &taskWoken) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMail;
+    }
+    else {
+      event.status = osOK;
+    }
+    portEND_SWITCHING_ISR(taskWoken);
+  }
+  else {
+    if (xQueueReceive(queue_id->handle, &event.value.p, ticks) == pdTRUE) {
+      /* We have mail */
+      event.status = osEventMail;
+    }
+    else {
+      event.status = (ticks == 0) ? osOK : osEventTimeout;
+    }
+  }
+  
+  return event;
+}
+
+/**
+* @brief Free a memory block from a mail
+* @param  queue_id mail queue ID obtained with \ref osMailCreate.
+* @param  mail     pointer to the memory block that was obtained with \ref osMailGet.
+* @retval status code that indicates the execution status of the function.
+* @note   MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
+*/
+osStatus osMailFree (osMailQId queue_id, void *mail)
+{
+  if (queue_id == NULL) {
+    return osErrorParameter;
+  }
+  
+  return osPoolFree(queue_id->pool, mail);
+}
+#endif  /* Use Mail Queues */
+
+/*************************** Additional specific APIs to Free RTOS ************/
+/**
+* @brief  Handles the tick increment
+* @param  none.
+* @retval none.
+*/
+void osSystickHandler(void)
+{
+
+#if (INCLUDE_xTaskGetSchedulerState  == 1 )
+  if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
+  {
+#endif  /* INCLUDE_xTaskGetSchedulerState */  
+    xPortSysTickHandler();
+#if (INCLUDE_xTaskGetSchedulerState  == 1 )
+  }
+#endif  /* INCLUDE_xTaskGetSchedulerState */  
+}
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/**
+* @brief  Obtain the state of any thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  the stae of the thread, states are encoded by the osThreadState enumerated type.
+*/
+osThreadState osThreadGetState(osThreadId thread_id)
+{
+  eTaskState ThreadState;
+  osThreadState result;
+  
+  ThreadState = eTaskGetState(thread_id);
+  
+  switch (ThreadState)
+  {
+  case eRunning :
+    result = osThreadRunning;
+    break;
+  case eReady :
+    result = osThreadReady;
+    break;
+  case eBlocked :
+    result = osThreadBlocked;
+    break;
+  case eSuspended :
+    result = osThreadSuspended;
+    break;
+  case eDeleted :
+    result = osThreadDeleted;
+    break;
+  default:
+    result = osThreadError;
+  } 
+  
+  return result;
+}
+#endif /* INCLUDE_eTaskGetState */
+
+#if (INCLUDE_eTaskGetState == 1)
+/**
+* @brief Check if a thread is already suspended or not.
+* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval status code that indicates the execution status of the function.
+*/
+osStatus osThreadIsSuspended(osThreadId thread_id)
+{
+  if (eTaskGetState(thread_id) == eSuspended)
+    return osOK;
+  else
+    return osErrorOS;
+}
+#endif /* INCLUDE_eTaskGetState */
+/**
+* @brief  Suspend execution of a thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspend (osThreadId thread_id)
+{
+#if (INCLUDE_vTaskSuspend == 1)
+    vTaskSuspend(thread_id);
+  
+  return osOK;
+#else
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Resume execution of a suspended thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResume (osThreadId thread_id)
+{
+#if (INCLUDE_vTaskSuspend == 1)  
+  if(inHandlerMode())
+  {
+    if (xTaskResumeFromISR(thread_id) == pdTRUE)
+    {
+      portYIELD_FROM_ISR(pdTRUE);
+    }
+  }
+  else
+  {
+    vTaskResume(thread_id);
+  }
+  return osOK;
+#else
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Suspend execution of a all active threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspendAll (void)
+{
+  vTaskSuspendAll();
+  
+  return osOK;
+}
+
+/**
+* @brief  Resume execution of a all suspended threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResumeAll (void)
+{
+  if (xTaskResumeAll() == pdTRUE)
+    return osOK;
+  else
+    return osErrorOS;
+  
+}
+
+/**
+* @brief  Delay a task until a specified time
+* @param   PreviousWakeTime   Pointer to a variable that holds the time at which the 
+*          task was last unblocked. PreviousWakeTime must be initialised with the current time
+*          prior to its first use (PreviousWakeTime = osKernelSysTick() )
+* @param   millisec    time delay value
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec)
+{
+#if INCLUDE_vTaskDelayUntil
+  TickType_t ticks = (millisec / portTICK_PERIOD_MS);
+  vTaskDelayUntil((TickType_t *) PreviousWakeTime, ticks ? ticks : 1);
+  
+  return osOK;
+#else
+  (void) millisec;
+  (void) PreviousWakeTime;
+  
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief   Abort the delay for a specific thread
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId   
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osAbortDelay(osThreadId thread_id)
+{
+#if INCLUDE_xTaskAbortDelay
+  
+  xTaskAbortDelay(thread_id);
+  
+  return osOK;
+#else
+  (void) thread_id;
+  
+  return osErrorResource;
+#endif
+}
+
+/**
+* @brief   Lists all the current threads, along with their current state 
+*          and stack usage high water mark.
+* @param   buffer   A buffer into which the above mentioned details
+*          will be written
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadList (uint8_t *buffer)
+{
+#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )
+  vTaskList((char *)buffer);
+#endif
+  return osOK;
+}
+
+/**
+* @brief  Receive an item from a queue without removing the item from the queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval event information that includes status code.
+*/
+osEvent osMessagePeek (osMessageQId queue_id, uint32_t millisec)
+{
+  TickType_t ticks;
+  osEvent event;
+  
+  event.def.message_id = queue_id;
+  
+  if (queue_id == NULL) {
+    event.status = osErrorParameter;
+    return event;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) {
+      ticks = 1;
+    }
+  }
+  
+  if (xQueuePeek(queue_id, &event.value.v, ticks) == pdTRUE) 
+  {
+    /* We have mail */
+    event.status = osEventMessage;
+  }
+  else 
+  {
+    event.status = (ticks == 0) ? osOK : osEventTimeout;
+  }
+  
+  return event;
+}
+
+/**
+* @brief  Get the number of messaged stored in a queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval number of messages stored in a queue.
+*/
+uint32_t osMessageWaiting(osMessageQId queue_id)
+{
+  if (inHandlerMode()) {
+    return uxQueueMessagesWaitingFromISR(queue_id);
+  }
+  else
+  {
+    return uxQueueMessagesWaiting(queue_id);
+  }
+}
+
+/**
+* @brief  Get the available space in a message queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval available space in a message queue.
+*/
+uint32_t osMessageAvailableSpace(osMessageQId queue_id)  
+{
+  return uxQueueSpacesAvailable(queue_id);
+}
+
+/**
+* @brief Delete a Message Queue
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osMessageDelete (osMessageQId queue_id)
+{
+  if (inHandlerMode()) {
+    return osErrorISR;
+  }
+
+  vQueueDelete(queue_id);
+
+  return osOK; 
+}
+
+/**
+* @brief  Create and Initialize a Recursive Mutex
+* @param  mutex_def     mutex definition referenced with \ref osMutex.
+* @retval  mutex ID for reference by other functions or NULL in case of error..
+*/
+osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def)
+{
+#if (configUSE_RECURSIVE_MUTEXES == 1)
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+
+  if (mutex_def->controlblock != NULL){
+    return xSemaphoreCreateRecursiveMutexStatic( mutex_def->controlblock );
+  }
+  else {
+    return xSemaphoreCreateRecursiveMutex();
+  }
+#elif ( configSUPPORT_STATIC_ALLOCATION == 1 )
+  return xSemaphoreCreateRecursiveMutexStatic( mutex_def->controlblock );
+#else 
+  return xSemaphoreCreateRecursiveMutex();
+#endif
+#else
+  return NULL;
+#endif	
+}
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id      mutex ID obtained by \ref osRecursiveMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexRelease (osMutexId mutex_id)
+{
+#if (configUSE_RECURSIVE_MUTEXES == 1)
+  osStatus result = osOK;
+ 
+  if (xSemaphoreGiveRecursive(mutex_id) != pdTRUE) 
+  {
+    result = osErrorOS;
+  }
+  return result;
+#else
+	return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id    mutex ID obtained by \ref osRecursiveMutexCreate.
+* @param millisec      timeout value or 0 in case of no time-out.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexWait (osMutexId mutex_id, uint32_t millisec)
+{
+#if (configUSE_RECURSIVE_MUTEXES == 1)
+  TickType_t ticks;
+  
+  if (mutex_id == NULL)
+  {
+    return osErrorParameter;
+  }
+  
+  ticks = 0;
+  if (millisec == osWaitForever) 
+  {
+    ticks = portMAX_DELAY;
+  }
+  else if (millisec != 0) 
+  {
+    ticks = millisec / portTICK_PERIOD_MS;
+    if (ticks == 0) 
+    {
+      ticks = 1;
+    }
+  }
+  
+  if (xSemaphoreTakeRecursive(mutex_id, ticks) != pdTRUE) 
+  {
+    return osErrorOS;
+  }
+  return osOK;
+#else
+	return osErrorResource;
+#endif
+}
+
+/**
+* @brief  Returns the current count value of a counting semaphore
+* @param  semaphore_id  semaphore_id ID obtained by \ref osSemaphoreCreate.
+* @retval  count value
+*/
+uint32_t osSemaphoreGetCount(osSemaphoreId semaphore_id)
+{
+  return uxSemaphoreGetCount(semaphore_id);
+}

+ 1026 - 0
desk/libs/thirdparty/freertos/CMSIS_RTOS/cmsis_os.h

@@ -0,0 +1,1026 @@
+/* ----------------------------------------------------------------------
+ * $Date:        5. February 2013
+ * $Revision:    V1.02
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.h header file
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedef's
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ *    
+ *  
+ *----------------------------------------------------------------------------
+ *
+ * Portions Copyright © 2016 STMicroelectronics International N.V. All rights reserved.
+ * Portions Copyright (c) 2013 ARM LIMITED
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+#include "queue.h"
+#include "semphr.h"
+#include "event_groups.h"
+
+/**
+\page cmsis_os_h Header File Template: cmsis_os.h
+
+The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS).
+Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents
+its implementation.
+
+The file cmsis_os.h contains:
+ - CMSIS-RTOS API function definitions
+ - struct definitions for parameters and return types
+ - status and priority values used by CMSIS-RTOS API functions
+ - macros for defining threads and other kernel objects
+
+
+<b>Name conventions and header file modifications</b>
+
+All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions.
+Definitions that are prefixed \b os_ are not used in the application code but local to this header file.
+All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread.
+
+Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation.
+These definitions can be specific to the underlying RTOS kernel.
+
+Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer
+compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation.
+
+
+<b>Function calls from interrupt service routines</b>
+
+The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR):
+  - \ref osSignalSet
+  - \ref osSemaphoreRelease
+  - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree
+  - \ref osMessagePut, \ref osMessageGet
+  - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree
+
+Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called
+from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector.
+
+Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time.
+If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive.
+
+
+<b>Define and reference object definitions</b>
+
+With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file
+that is used throughout a project as shown below:
+
+<i>Header File</i>
+\code
+#include <cmsis_os.h>                                         // CMSIS RTOS header file
+
+// Thread definition
+extern void thread_sample (void const *argument);             // function prototype
+osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
+
+// Pool definition
+osPoolDef(MyPool, 10, long);
+\endcode
+
+
+This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is
+present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be
+used throughout the whole project.
+
+<i>Example</i>
+\code
+#include "osObjects.h"     // Definition of the CMSIS-RTOS objects
+\endcode
+
+\code
+#define osObjectExternal   // Objects will be defined as external symbols
+#include "osObjects.h"     // Reference to the CMSIS-RTOS objects
+\endcode
+
+*/
+
+#ifndef _CMSIS_OS_H
+#define _CMSIS_OS_H
+
+/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
+#define osCMSIS           0x10002      ///< API version (main [31:16] .sub [15:0])
+
+/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
+#define osCMSIS_KERNEL    0x10000	   ///< RTOS identification and version (main [31:16] .sub [15:0])
+
+/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
+#define osKernelSystemId "KERNEL V1.00"   ///< RTOS identification string
+
+/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
+#define osFeature_MainThread   1       ///< main thread      1=main can be thread, 0=not available
+#define osFeature_Pool         1       ///< Memory Pools:    1=available, 0=not available
+#define osFeature_MailQ        1       ///< Mail Queues:     1=available, 0=not available
+#define osFeature_MessageQ     1       ///< Message Queues:  1=available, 0=not available
+#define osFeature_Signals      8       ///< maximum number of Signal Flags available per thread
+#define osFeature_Semaphore    1      ///< osFeature_Semaphore function: 1=available, 0=not available
+#define osFeature_Wait         0       ///< osWait function: 1=available, 0=not available
+#define osFeature_SysTick      1       ///< osKernelSysTick functions: 1=available, 0=not available
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+
+// ==== Enumeration, structures, defines ====
+
+/// Priority used for thread control.
+/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osPriorityIdle          = -3,          ///< priority: idle (lowest)
+  osPriorityLow           = -2,          ///< priority: low
+  osPriorityBelowNormal   = -1,          ///< priority: below normal
+  osPriorityNormal        =  0,          ///< priority: normal (default)
+  osPriorityAboveNormal   = +1,          ///< priority: above normal
+  osPriorityHigh          = +2,          ///< priority: high
+  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
+  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
+} osPriority;
+
+/// Timeout value.
+/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
+#define osWaitForever     0xFFFFFFFF     ///< wait forever timeout value
+
+/// Status code values returned by CMSIS-RTOS functions.
+/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osOK                    =     0,       ///< function completed; no error or event occurred.
+  osEventSignal           =  0x08,       ///< function completed; signal event occurred.
+  osEventMessage          =  0x10,       ///< function completed; message event occurred.
+  osEventMail             =  0x20,       ///< function completed; mail event occurred.
+  osEventTimeout          =  0x40,       ///< function completed; timeout occurred.
+  osErrorParameter        =  0x80,       ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
+  osErrorResource         =  0x81,       ///< resource not available: a specified resource was not available.
+  osErrorTimeoutResource  =  0xC1,       ///< resource not available within given time: a specified resource was not available within the timeout period.
+  osErrorISR              =  0x82,       ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
+  osErrorISRRecursive     =  0x83,       ///< function called multiple times from ISR with same object.
+  osErrorPriority         =  0x84,       ///< system cannot determine priority or thread has illegal priority.
+  osErrorNoMemory         =  0x85,       ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
+  osErrorValue            =  0x86,       ///< value of a parameter is out of range.
+  osErrorOS               =  0xFF,       ///< unspecified RTOS error: run-time error but no other error message fits.
+  os_status_reserved      =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osStatus;
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/* Thread state returned by osThreadGetState */
+typedef enum {
+	osThreadRunning   = 0x0,	      /* A thread is querying the state of itself, so must be running. */
+	osThreadReady     = 0x1 ,			        /* The thread being queried is in a read or pending ready list. */
+	osThreadBlocked   = 0x2,		        /* The thread being queried is in the Blocked state. */
+	osThreadSuspended = 0x3,	      /* The thread being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */
+	osThreadDeleted   = 0x4,		          /* The thread being queried has been deleted, but its TCB has not yet been freed. */   
+  osThreadError     = 0x7FFFFFFF
+} osThreadState;
+#endif /* INCLUDE_eTaskGetState */
+
+/// Timer type value for the timer definition.
+/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osTimerOnce             =     0,       ///< one-shot timer
+  osTimerPeriodic         =     1        ///< repeating timer
+} os_timer_type;
+
+/// Entry point of a thread.
+/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
+typedef void (*os_pthread) (void const *argument);
+
+/// Entry point of a timer call back function.
+/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
+typedef void (*os_ptimer) (void const *argument);
+
+// >>> the following data type definitions may shall adapted towards a specific RTOS
+
+/// Thread ID identifies the thread (pointer to a thread control block).
+/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
+typedef TaskHandle_t osThreadId;
+
+/// Timer ID identifies the timer (pointer to a timer control block).
+/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
+typedef TimerHandle_t osTimerId;
+
+/// Mutex ID identifies the mutex (pointer to a mutex control block).
+/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
+typedef SemaphoreHandle_t osMutexId;
+
+/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
+/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
+typedef SemaphoreHandle_t osSemaphoreId;
+
+/// Pool ID identifies the memory pool (pointer to a memory pool control block).
+/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_cb *osPoolId;
+
+/// Message ID identifies the message queue (pointer to a message queue control block).
+/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
+typedef QueueHandle_t osMessageQId;
+
+/// Mail ID identifies the mail queue (pointer to a mail queue control block).
+/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_cb *osMailQId;
+
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+typedef StaticTask_t               osStaticThreadDef_t;
+typedef StaticTimer_t              osStaticTimerDef_t;
+typedef StaticSemaphore_t          osStaticMutexDef_t;         
+typedef StaticSemaphore_t          osStaticSemaphoreDef_t;
+typedef StaticQueue_t              osStaticMessageQDef_t;
+
+#endif
+
+
+
+
+/// Thread Definition structure contains startup information of a thread.
+/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_thread_def  {
+  char                   *name;        ///< Thread name 
+  os_pthread             pthread;      ///< start address of thread function
+  osPriority             tpriority;    ///< initial thread priority
+  uint32_t               instances;    ///< maximum number of instances of that thread function
+  uint32_t               stacksize;    ///< stack size requirements in bytes; 0 is default stack size
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  uint32_t               *buffer;      ///< stack buffer for static allocation; NULL for dynamic allocation
+  osStaticThreadDef_t    *controlblock;     ///< control block to hold thread's data for static allocation; NULL for dynamic allocation
+#endif
+} osThreadDef_t;
+
+/// Timer Definition structure contains timer parameters.
+/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_timer_def  {
+  os_ptimer                 ptimer;    ///< start address of a timer function
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  osStaticTimerDef_t        *controlblock;      ///< control block to hold timer's data for static allocation; NULL for dynamic allocation
+#endif
+} osTimerDef_t;
+
+/// Mutex Definition structure contains setup information for a mutex.
+/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mutex_def  {
+  uint32_t                   dummy;    ///< dummy value.
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  osStaticMutexDef_t         *controlblock;      ///< control block for static allocation; NULL for dynamic allocation
+#endif
+} osMutexDef_t;
+
+/// Semaphore Definition structure contains setup information for a semaphore.
+/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_semaphore_def  {
+  uint32_t                   dummy;    ///< dummy value.
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  osStaticSemaphoreDef_t     *controlblock;      ///< control block for static allocation; NULL for dynamic allocation
+#endif
+} osSemaphoreDef_t;
+
+/// Definition structure for memory block allocation.
+/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_def  {
+  uint32_t                 pool_sz;    ///< number of items (elements) in the pool
+  uint32_t                 item_sz;    ///< size of an item
+  void                       *pool;    ///< pointer to memory for pool
+} osPoolDef_t;
+
+/// Definition structure for message queue.
+/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_messageQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  uint32_t                item_sz;    ///< size of an item
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+  uint8_t                 *buffer;      ///< buffer for static allocation; NULL for dynamic allocation
+  osStaticMessageQDef_t   *controlblock;     ///< control block to hold queue's data for static allocation; NULL for dynamic allocation
+#endif
+  //void                       *pool;    ///< memory array for messages
+} osMessageQDef_t;
+
+/// Definition structure for mail queue.
+/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  uint32_t                 item_sz;    ///< size of an item
+  struct os_mailQ_cb **cb;
+} osMailQDef_t;
+
+/// Event structure contains detailed information about an event.
+/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
+///       However the struct may be extended at the end.
+typedef struct  {
+  osStatus                 status;     ///< status code: event or error information
+  union  {
+    uint32_t                    v;     ///< message as 32-bit value
+    void                       *p;     ///< message or mail as void pointer
+    int32_t               signals;     ///< signal flags
+  } value;                             ///< event value
+  union  {
+    osMailQId             mail_id;     ///< mail id obtained by \ref osMailCreate
+    osMessageQId       message_id;     ///< message id obtained by \ref osMessageCreate
+  } def;                               ///< event definition
+} osEvent;
+
+
+//  ==== Kernel Control Functions ====
+
+/// Initialize the RTOS Kernel for creating objects.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
+osStatus osKernelInitialize (void);
+
+/// Start the RTOS Kernel.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
+osStatus osKernelStart (void);
+
+/// Check if the RTOS kernel is already started.
+/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
+/// \return 0 RTOS is not started, 1 RTOS is started.
+int32_t osKernelRunning(void);
+
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+
+/// Get the RTOS kernel system timer counter 
+/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+/// \return RTOS kernel system timer as 32-bit value 
+uint32_t osKernelSysTick (void);
+
+/// The RTOS kernel system timer frequency in Hz
+/// \note Reflects the system timer setting and is typically defined in a configuration file.
+#define osKernelSysTickFrequency      (configTICK_RATE_HZ)
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to the \ref osKernelSysTickFrequency
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
+
+#endif    // System Timer available
+
+//  ==== Thread Management ====
+
+/// Create a Thread Definition with function, priority, and stack requirements.
+/// \param         name         name of the thread function.
+/// \param         priority     initial priority of the thread function.
+/// \param         instances    number of possible thread instances.
+/// \param         stacksz      stack size (in bytes) requirements for the thread function.
+/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osThreadDef(name, thread, priority, instances, stacksz)  \
+extern const osThreadDef_t os_thread_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osThreadDef(name, thread, priority, instances, stacksz)  \
+const osThreadDef_t os_thread_def_##name = \
+{ #name, (thread), (priority), (instances), (stacksz), NULL, NULL }
+
+#define osThreadStaticDef(name, thread, priority, instances, stacksz, buffer, control)  \
+const osThreadDef_t os_thread_def_##name = \
+{ #name, (thread), (priority), (instances), (stacksz), (buffer), (control) }
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+
+#define osThreadDef(name, thread, priority, instances, stacksz)  \
+const osThreadDef_t os_thread_def_##name = \
+{ #name, (thread), (priority), (instances), (stacksz)}
+#endif
+#endif
+
+/// Access a Thread definition.
+/// \param         name          name of the thread definition object.
+/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osThread(name)  \
+&os_thread_def_##name
+
+/// Create a thread and add it to Active Threads and set it to state READY.
+/// \param[in]     thread_def    thread definition referenced with \ref osThread.
+/// \param[in]     argument      pointer that is passed to the thread function as start argument.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
+
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadGetId (void);
+
+/// Terminate execution of a thread and remove it from Active Threads.
+/// \param[in]     thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
+osStatus osThreadTerminate (osThreadId thread_id);
+
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
+osStatus osThreadYield (void);
+
+/// Change priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     priority      new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
+
+/// Get current priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return current priority value of the thread function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
+osPriority osThreadGetPriority (osThreadId thread_id);
+
+
+//  ==== Generic Wait Functions ====
+
+/// Wait for Timeout (Time Delay).
+/// \param[in]     millisec      time delay value
+/// \return status code that indicates the execution status of the function.
+osStatus osDelay (uint32_t millisec);
+
+#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0))     // Generic Wait available
+
+/// Wait for Signal, Message, Mail, or Timeout.
+/// \param[in] millisec          timeout value or 0 in case of no time-out
+/// \return event that contains signal, message, or mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
+osEvent osWait (uint32_t millisec);
+
+#endif  // Generic Wait available
+
+
+//  ==== Timer Management Functions ====
+/// Define a Timer object.
+/// \param         name          name of the timer object.
+/// \param         function      name of the timer call back function.
+/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osTimerDef(name, function)  \
+extern const osTimerDef_t os_timer_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 ) 
+#define osTimerDef(name, function)  \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), NULL }
+
+#define osTimerStaticDef(name, function, control)  \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), (control) }
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+#define osTimerDef(name, function)  \
+const osTimerDef_t os_timer_def_##name = \
+{ (function) }
+#endif
+#endif
+
+/// Access a Timer definition.
+/// \param         name          name of the timer object.
+/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osTimer(name) \
+&os_timer_def_##name
+
+/// Create a timer.
+/// \param[in]     timer_def     timer object referenced with \ref osTimer.
+/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in]     argument      argument to the timer call back function.
+/// \return timer ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
+
+/// Start or restart a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \param[in]     millisec      time delay value of the timer.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
+
+/// Stop the timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStop (osTimerId timer_id);
+
+/// Delete a timer that was created by \ref osTimerCreate.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
+osStatus osTimerDelete (osTimerId timer_id);
+
+
+//  ==== Signal Management ====
+
+/// Set the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that should be set.
+/// \return osOK if successful, osErrorOS if failed.
+/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
+int32_t osSignalSet (osThreadId thread_id, int32_t signals);
+
+/// Clear the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that shall be cleared.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
+int32_t osSignalClear (osThreadId thread_id, int32_t signals);
+
+/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+/// \param[in]     signals       wait until all specified signal flags set or 0 for any single signal flag.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return event flag information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
+osEvent osSignalWait (int32_t signals, uint32_t millisec);
+
+
+//  ==== Mutex Management ====
+
+/// Define a Mutex.
+/// \param         name          name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMutexDef(name)  \
+extern const osMutexDef_t os_mutex_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osMutexDef(name)  \
+const osMutexDef_t os_mutex_def_##name = { 0, NULL }
+
+#define osMutexStaticDef(name, control)  \
+const osMutexDef_t os_mutex_def_##name = { 0, (control) }
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+#define osMutexDef(name)  \
+const osMutexDef_t os_mutex_def_##name = { 0 }
+
+#endif
+
+#endif
+
+/// Access a Mutex definition.
+/// \param         name          name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMutex(name)  \
+&os_mutex_def_##name
+
+/// Create and Initialize a Mutex object.
+/// \param[in]     mutex_def     mutex definition referenced with \ref osMutex.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
+
+/// Wait until a Mutex becomes available.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/// Release a Mutex that was obtained by \ref osMutexWait.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
+osStatus osMutexRelease (osMutexId mutex_id);
+
+/// Delete a Mutex that was created by \ref osMutexCreate.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
+osStatus osMutexDelete (osMutexId mutex_id);
+
+
+//  ==== Semaphore Management Functions ====
+
+#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))     // Semaphore available
+
+/// Define a Semaphore object.
+/// \param         name          name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osSemaphoreDef(name)  \
+extern const osSemaphoreDef_t os_semaphore_def_##name
+#else                            // define the object
+
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osSemaphoreDef(name)  \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0, NULL }
+
+#define osSemaphoreStaticDef(name, control)  \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0, (control) }
+
+#else //configSUPPORT_STATIC_ALLOCATION == 0
+#define osSemaphoreDef(name)  \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
+#endif
+#endif
+
+/// Access a Semaphore definition.
+/// \param         name          name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osSemaphore(name)  \
+&os_semaphore_def_##name
+
+/// Create and Initialize a Semaphore object used for managing resources.
+/// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore.
+/// \param[in]     count         number of available resources.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
+
+/// Wait until a Semaphore token becomes available.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return number of available tokens, or -1 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+
+/// Release a Semaphore token.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
+
+/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
+
+#endif     // Semaphore available
+
+
+//  ==== Memory Pool Management Functions ====
+
+#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0))  // Memory Pool Management available
+
+/// \brief Define a Memory Pool.
+/// \param         name          name of the memory pool.
+/// \param         no            maximum number of blocks (objects) in the memory pool.
+/// \param         type          data type of a single block (object).
+/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osPoolDef(name, no, type)   \
+extern const osPoolDef_t os_pool_def_##name
+#else                            // define the object
+#define osPoolDef(name, no, type)   \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), NULL }
+#endif
+
+/// \brief Access a Memory Pool definition.
+/// \param         name          name of the memory pool
+/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osPool(name) \
+&os_pool_def_##name
+
+/// Create and Initialize a memory pool.
+/// \param[in]     pool_def      memory pool definition referenced with \ref osPool.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
+osPoolId osPoolCreate (const osPoolDef_t *pool_def);
+
+/// Allocate a memory block from a memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolAlloc (osPoolId pool_id);
+
+/// Allocate a memory block from a memory pool and set memory block to zero.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolCAlloc (osPoolId pool_id);
+
+/// Return an allocated memory block back to a specific memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \param[in]     block         address of the allocated memory block that is returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
+osStatus osPoolFree (osPoolId pool_id, void *block);
+
+#endif   // Memory Pool Management available
+
+
+//  ==== Message Queue Management Functions ====
+
+#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0))     // Message Queues available
+
+/// \brief Create a Message Queue Definition.
+/// \param         name          name of the queue.
+/// \param         queue_sz      maximum number of messages in the queue.
+/// \param         type          data type of a single message element (for debugger).
+/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMessageQDef(name, queue_sz, type)   \
+extern const osMessageQDef_t os_messageQ_def_##name
+#else                            // define the object
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define osMessageQDef(name, queue_sz, type)   \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type), NULL, NULL  }
+
+#define osMessageQStaticDef(name, queue_sz, type, buffer, control)   \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type) , (buffer), (control)}
+#else //configSUPPORT_STATIC_ALLOCATION == 1
+#define osMessageQDef(name, queue_sz, type)   \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type) }
+
+#endif
+#endif
+
+/// \brief Access a Message Queue Definition.
+/// \param         name          name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMessageQ(name) \
+&os_messageQ_def_##name
+
+/// Create and Initialize a Message Queue.
+/// \param[in]     queue_def     queue definition referenced with \ref osMessageQ.
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+
+/// Put a Message to a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     info          message information.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+
+/// Get a Message or Wait for a Message from a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return event information that includes status code.
+/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
+
+#endif     // Message Queues available
+
+
+//  ==== Mail Queue Management Functions ====
+
+#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))     // Mail Queues available
+
+/// \brief Create a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \param         queue_sz      maximum number of messages in queue
+/// \param         type          data type of a single message element
+/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMailQDef(name, queue_sz, type) \
+extern struct os_mailQ_cb *os_mailQ_cb_##name \
+extern osMailQDef_t os_mailQ_def_##name
+#else                            // define the object
+#define osMailQDef(name, queue_sz, type) \
+struct os_mailQ_cb *os_mailQ_cb_##name; \
+const osMailQDef_t os_mailQ_def_##name =  \
+{ (queue_sz), sizeof (type), (&os_mailQ_cb_##name) }
+#endif
+
+/// \brief Access a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMailQ(name)  \
+&os_mailQ_def_##name
+
+/// Create and Initialize mail queue.
+/// \param[in]     queue_def     reference to the mail queue definition obtain with \ref osMailQ
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return mail queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
+
+/// Allocate a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Allocate a memory block from a mail and set memory block to zero.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Put a mail to a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
+osStatus osMailPut (osMailQId queue_id, void *mail);
+
+/// Get a mail from a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return event that contains mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
+
+/// Free a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          pointer to the memory block that was obtained with \ref osMailGet.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
+osStatus osMailFree (osMailQId queue_id, void *mail);
+
+#endif  // Mail Queues available
+
+/*************************** Additional specific APIs to Free RTOS ************/
+/**
+* @brief  Handles the tick increment
+* @param  none.
+* @retval none.
+*/
+void osSystickHandler(void);
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/**
+* @brief  Obtain the state of any thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  the stae of the thread, states are encoded by the osThreadState enumerated type.
+*/
+osThreadState osThreadGetState(osThreadId thread_id);
+#endif /* INCLUDE_eTaskGetState */
+
+#if ( INCLUDE_eTaskGetState == 1 )
+/**
+* @brief Check if a thread is already suspended or not.
+* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval status code that indicates the execution status of the function.
+*/
+
+osStatus osThreadIsSuspended(osThreadId thread_id);
+
+#endif /* INCLUDE_eTaskGetState */
+
+/**
+* @brief  Suspend execution of a thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspend (osThreadId thread_id);
+
+/**
+* @brief  Resume execution of a suspended thread.
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResume (osThreadId thread_id);
+
+/**
+* @brief  Suspend execution of a all active threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadSuspendAll (void);
+
+/**
+* @brief  Resume execution of a all suspended threads.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadResumeAll (void);
+
+/**
+* @brief  Delay a task until a specified time
+* @param   PreviousWakeTime   Pointer to a variable that holds the time at which the 
+*          task was last unblocked. PreviousWakeTime must be initialised with the current time
+*          prior to its first use (PreviousWakeTime = osKernelSysTick() )
+* @param   millisec    time delay value
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec);
+
+/**
+* @brief   Abort the delay for a specific thread
+* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId   
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osAbortDelay(osThreadId thread_id);
+
+/**
+* @brief   Lists all the current threads, along with their current state 
+*          and stack usage high water mark.
+* @param   buffer   A buffer into which the above mentioned details
+*          will be written
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osThreadList (uint8_t *buffer);
+
+/**
+* @brief  Receive an item from a queue without removing the item from the queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @param  millisec  timeout value or 0 in case of no time-out.
+* @retval event information that includes status code.
+*/
+osEvent osMessagePeek (osMessageQId queue_id, uint32_t millisec);
+
+/**
+* @brief  Get the number of messaged stored in a queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval number of messages stored in a queue.
+*/
+uint32_t osMessageWaiting(osMessageQId queue_id);
+
+/**
+* @brief  Get the available space in a message queue.
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval available space in a message queue.
+*/
+uint32_t osMessageAvailableSpace(osMessageQId queue_id);
+
+/**
+* @brief Delete a Message Queue
+* @param  queue_id  message queue ID obtained with \ref osMessageCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osMessageDelete (osMessageQId queue_id);
+
+/**
+* @brief  Create and Initialize a Recursive Mutex
+* @param  mutex_def     mutex definition referenced with \ref osMutex.
+* @retval  mutex ID for reference by other functions or NULL in case of error..
+*/
+osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def);
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id      mutex ID obtained by \ref osRecursiveMutexCreate.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexRelease (osMutexId mutex_id);
+
+/**
+* @brief  Release a Recursive Mutex
+* @param   mutex_id    mutex ID obtained by \ref osRecursiveMutexCreate.
+* @param millisec      timeout value or 0 in case of no time-out.
+* @retval  status code that indicates the execution status of the function.
+*/
+osStatus osRecursiveMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/**
+* @brief  Returns the current count value of a counting semaphore
+* @param   semaphore_id  semaphore_id ID obtained by \ref osSemaphoreCreate.
+* @retval  count value
+*/
+uint32_t osSemaphoreGetCount(osSemaphoreId semaphore_id);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  // _CMSIS_OS_H

+ 2 - 0
desk/libs/thirdparty/oled_ssd1327/i2c.c

@@ -5,6 +5,7 @@ I2C_HandleTypeDef hi2c2;
 
 void MX_I2C1_Init(void)
 {
+/*  
     hi2c2.Instance = I2C2;
     hi2c2.Init.ClockSpeed = 100000;
     hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
@@ -15,6 +16,7 @@ void MX_I2C1_Init(void)
     hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
     hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
     HAL_I2C_Init(&hi2c2);
+*/
 }
 
 

+ 745 - 0
desk/modules/terminal/terminal.cpp

@@ -0,0 +1,745 @@
+#include "terminal.h"
+#include <string.h>
+#include <stdarg.h>
+
+static char tmpCommand[40];
+
+//-----------------------------------------------------------------------------
+// Microrl callbacks
+//-----------------------------------------------------------------------------
+extern "C" {
+
+    //Configure terminal
+    void configure_terminal() {
+        pTerminal->configure();
+    }
+
+    //Print micrrl callback
+    void print_terminal(const char *str) {
+        pTerminal->print(str);
+    }
+
+    //Execute microrl callback
+    int execute_terminal(int argc, const char * const * argv) {
+        return pTerminal->execute(argc, argv);}
+
+    //Sigint microrl callback
+    void sigint_terminal (void) {
+        pTerminal->sigint();}
+    
+    //Complete microrl callback
+    char** completion_terminal (int argc, const char * const * argv) {
+        return pTerminal->completion(argc, argv);}
+
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Terminal class
+//-----------------------------------------------------------------------------
+
+Terminal::Terminal():
+    m_countPrintFunction(0),
+    prl(&rl)
+{
+    memset(&f_print, 0, sizeof(f_print));
+    memset(tmpCommand, 0, sizeof(tmpCommand));
+}
+
+
+
+
+//Configure microrl callbacks
+void Terminal::configure()
+{
+  
+    m_countPrintFunction = 0;
+    prl = &rl;
+
+    memset(&f_print, 0, sizeof(f_print));
+    memset(tmpCommand, 0, sizeof(tmpCommand));
+	
+    microrl_init (prl, ::print_terminal);
+    microrl_set_execute_callback (prl, ::execute_terminal);
+    microrl_set_sigint_callback (prl, ::sigint_terminal);
+    microrl_set_complete_callback (prl, ::completion_terminal);
+}
+
+
+void Terminal::connectCallback() {
+    printeol();
+    printll("Hello stranger. It is goot day for work :)");    
+}
+
+
+//Insert char to microrl
+void Terminal::insert(int ch) {
+    microrl_insert_char(prl, ch);
+}
+
+
+//Out message to all terminals
+void Terminal::print(const char *str) {
+    for (int i = 0; i < m_countPrintFunction; i++) {
+        if (f_print[i] != 0) {
+            f_print[i](str);
+        }
+    }
+}
+
+
+void Terminal::printl(const char * str) {
+    print(str);
+    print(EOL);
+}
+
+void Terminal::printll(const char * str) {
+    print(str);
+    print(EOL);
+    print(EOL);
+}
+
+
+void Terminal::eol() {
+    print(EOL);
+}
+
+void Terminal::printeol() {
+    print(EOL);
+}
+
+
+//Execute microrl callbacks
+int Terminal::execute(int argc, const char * const *argv) {
+    return 0;
+}
+
+char* helloNull[] = {0};
+
+//Comletion microrl callbacks
+char ** Terminal::completion(int argc, const char * const * argv) {
+    int i = 0;
+    i++;
+    return helloNull;
+}
+
+//Sigint microrl callbacks
+void Terminal::sigint()
+{
+}
+
+
+//Add external print function
+void Terminal::addPrint(InterfacePrint print_func) {
+    if (m_countPrintFunction < COUNT_TERMINAL_INTERFACE) {
+        f_print[m_countPrintFunction] = print_func;
+        m_countPrintFunction++;
+    }
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Вывод команд в терминал
+//-----------------------------------------------------------------------------
+
+//Очистка экрана
+void Terminal::clearScreen() {
+    //Clear
+    print("\033[2J");        
+    //Move to up left corner
+    print("\033[H");    
+}
+
+
+//Сдвинуть в указанную позицию
+void Terminal::moveToPos(uint32_t h, uint32_t v)
+{
+    uint32_t sizeCommand = 0;
+    getCommand_MoveToPos(tmpCommand, sizeCommand, h, v);
+    print(tmpCommand);
+}
+
+
+//Сдвинуть в верхний левый угол
+void Terminal::moveToUpLeftCorner() {
+    //Move to up left corner
+    print("\033[H");    
+}
+
+
+//Reset terminal to initial state 
+void Terminal::reset() {
+    //Сбросить настройки терминала
+    print("\033c");
+}
+
+//Сбросить аттрибуты текста
+void Terminal::resetAttribute() {
+    print("\033[0m");
+}
+
+//Сохранить позицию курсора и атрибуты
+void Terminal::saveCursorPos() {
+    //Save cursor position and attributes 
+    print("\0337");    
+}
+
+//Востановить позицию курсора и аттрибуты
+void Terminal::restoreCursorPos() {
+    //Restore cursor position and attributes 
+    print("\0338");    
+}
+
+//Скрыть курсов
+void Terminal::hideCursor() {
+    print("\033[8m");
+}
+
+//Очистить строку
+void Terminal::clearCurrentLine() {
+    print("\033[2K");
+}
+
+
+
+
+
+void write(const char* src, int src_size, char* dst, uint32_t& size) {
+    memcpy(&dst[size], src, src_size);
+    size += src_size;
+}
+
+
+//Формирование команды для установки курсора в заданную позицию
+uint32_t Terminal::getCommand_MoveToPos(
+    char* res_command, uint32_t& res_size, uint32_t h, uint32_t v
+)
+{    
+    //Esc[Line;ColumnH
+    res_size = 0;
+    
+    write("\x1B[", 2, res_command, res_size);
+    
+        
+    char* vStr = utoa(v);
+    uint32_t sizeV = strlen(vStr);
+    write(vStr, sizeV, res_command, res_size);
+    
+    write(";", 1, res_command, res_size);
+    
+    char* hStr = utoa(h);
+    uint32_t sizeH = strlen(hStr);
+    write(hStr, sizeH, res_command, res_size);
+
+    write("H", 1, res_command, res_size);
+    write("\0", 1, res_command, res_size); 
+
+    return res_size;
+}
+
+
+
+
+//Формирование команды для сдвига курсора вверх на n позиций
+uint32_t Terminal::getCommand_MoveUpNLines(
+    char* res_command, uint32_t& res_size, uint32_t n)
+{
+    return 0;
+}
+
+
+
+//Формирование команды для сдвига курсора вниз на n позиций
+uint32_t Terminal::getCommand_MoveDownNLines(
+    char* res_command, uint32_t& res_size, uint32_t n)
+{
+    return 0;
+}
+
+
+
+//Формирование команды для сдвига курсора вправо на n позиций
+uint32_t Terminal::getCommand_MoveRightNLines(
+    char* res_command, uint32_t& res_size, uint32_t n)
+{
+    return 0;
+}
+
+
+//Формирование команды для сдвига курсора влево на n позиций
+uint32_t Terminal::getCommand_MoveLeftNLines(
+    char* res_command, uint32_t& res_size, uint32_t n)
+{
+    return 0;
+}
+
+
+//Формирование команды для установки цвета текста
+uint32_t Terminal::getCommand_SetTextColor(char* res_command, uint32_t& res_size, TextColor color)
+{
+    //Esc[3ColorH
+    res_size = 0;    
+    write("\x1B[3", 3, res_command, res_size);
+        
+    char* vStr = utoa(color);
+    write(vStr, 1, res_command, res_size);
+    write("m", 1, res_command, res_size);   
+    write("\0", 1, res_command, res_size); 
+        
+    return res_size;
+}
+
+
+//Формирование команды для установки аттрибута подчёркивания
+uint32_t Terminal::getCommand_UnderlineText(char* res_command, uint32_t& res_size)
+{
+    res_size = 0;    
+    write("\x1B[4m", 4, res_command, res_size);
+    write("\0", 1, res_command, res_size); 
+    return res_size;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Класс реализации таблицы
+//-----------------------------------------------------------------------------
+Table::Table() {
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Вывод элементов таблицы
+//-----------------------------------------------------------------------------
+
+//Вывод сктроки в заданную ячейку
+void Table::outToCell(uint8_t col, uint8_t row, const char* str) 
+{
+    //CellAttribute &cell = cells[col][row];
+    //print(cell.pos_command);
+    //print(cell.color_command);
+    pTerminal->resetAttribute();
+    
+    //Выводим атрибуты
+    CellAttribute &cell = cells[col][row];    
+    print(cell.attributes);
+    
+    //Выводим строку
+    print(str);
+    
+    //Выводим пробелы на до конца ячейки
+    int32_t countSpace = m_width[col] - strlen(str) - 1; 
+    for (uint8_t i = 0; i < countSpace; i++)
+        print(" ");
+    
+    
+}
+
+
+//Вывод значения в заданную ячейку
+void Table::outToCell(uint8_t col, uint8_t row, uint32_t val)  {
+    outToCell(col, row, utoa(val));
+}
+
+
+//Выводим в нужную строку разделяющую линию
+void Table::outCrossLine(uint8_t row) {    
+    uint32_t line = m_y + row;
+    pTerminal->moveToPos(m_x, line);
+    printCrossLine(line);        
+}
+
+
+
+//Вывод внешней границы в строке
+void Table::outExternalBorder() {
+    
+    uint32_t line = m_y;        
+        
+    printTopLine(line);        
+    for (uint8_t r = 0; r < m_row; r++)
+        printTextLine(line);    
+    printBottomLine(line);                                              
+        
+}
+
+
+//Печать статической части таблицы
+void Table::outStatic() 
+{
+    pTerminal->saveCursorPos();
+    outExternalBorder();
+    pTerminal->restoreCursorPos();    
+}
+
+
+//Печатает в таблице счётчик ячеек
+void Table::outCellNumber()
+{
+    uint32_t count = 0;
+    for (uint8_t c = 0; c < m_col; c ++) {
+        for (uint8_t r = 0; r < m_row; r++) {
+            print(cells[c][r].attributes);            
+            print(utoa(count));
+            count ++;
+        }
+    }
+}
+
+
+void Table::startUpdate() {
+    pTerminal->saveCursorPos();
+}
+
+
+void Table::endUpdate() {
+    pTerminal->restoreCursorPos();
+}
+
+//-----------------------------------------------------------------------------
+// Конфигурация талицы
+//-----------------------------------------------------------------------------
+
+//Задать геометрию таблицы 
+void Table::setGeometry(uint8_t x, uint8_t y, uint8_t col, uint8_t row, uint32_t width, ...)
+{   
+    setPos(x, y);
+    setSize(col, row);
+    
+    if ((m_col == 0) || (m_row == 0))
+        return;
+    
+    //Читаем ширину колонок
+    va_list ap;
+    va_start(ap, width); 
+    
+    uint8_t c = 0;
+    m_width[c] = width;    
+    do {
+        c++;
+        m_width[c] = va_arg(ap, int32_t);
+    } while (c < m_col);        
+    
+    va_end(ap);  
+    
+    resetAttributes();    
+}
+
+
+//Задать геометрию таблицы 
+void Table::setGeometry(uint8_t x, uint8_t y, uint8_t col, uint8_t row, const uint32_t* width) 
+{
+    setPos(x, y);
+    setSize(col, row);
+    
+    if ((m_col == 0) || (m_row == 0))
+        return;
+    
+    for (int c = 0; c < m_col; c++)
+        m_width[c] = width[c];
+           
+    resetAttributes();    
+}
+
+
+//Установить позицию таблицы
+void Table::setPos(uint8_t x, uint8_t y) {
+     m_x = x; m_y = y;
+}
+
+//Установить размеры таблицы
+void Table::setSize(uint8_t col, uint8_t row) {
+    m_col = col;
+    m_row = row;
+    
+    if (m_col > MAX_COL)
+        m_col = MAX_COL;
+    
+    if (m_row > MAX_ROW)
+        m_row = MAX_ROW;
+}
+
+
+//Сброс аттрибутов для ячеек
+void Table::resetAttributes()
+{
+    //Добавляем аттрибут для перемещения
+    //курсора в начало каждой ячейки
+    for (uint8_t c = 0; c < m_col; c ++) {
+        for (uint8_t r = 0; r < m_row; r++) {
+            clearCellAttributes(c, r);
+            
+            addCellPosAttribute(c, r);              
+        }
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+// Работа с аттрибутами
+//-----------------------------------------------------------------------------
+
+//Атрибуты - строка с управляющими командами для
+//терминала VT100, которые выводятся в терминал
+//перед выводом в ячейку (перемещение курсора
+//на ячейку, установка цвета)
+
+static char tmpAttr[20];
+static uint32_t tmpAttrSize = 0; 
+
+//Расчитать для начала ячейки позицию курсора 
+void Table::addCellPosAttribute(uint8_t col, uint8_t row) {
+         
+    //Расчитываем позицию курсора для ячейки
+    uint32_t y = m_y + 1;
+    uint32_t x = m_x + 1;
+    
+    for (uint32_t c = 0; c < col; c++)
+        x += m_width[c];
+    
+    x += col;
+    y += row;
+    
+    //Формируем команду перемещения курсора в рассчитанную позицию
+    pTerminal->getCommand_MoveToPos(tmpAttr, tmpAttrSize, x, y);    
+    addCellAttribute(col, row, tmpAttr);        
+}
+
+
+
+//Добавить аттрибут цвета текста
+void Table::addCellColorAttribute(uint8_t col, uint8_t row, TextColor color) {
+    pTerminal->getCommand_SetTextColor(tmpAttr, tmpAttrSize, color); 
+    addCellAttribute(col, row, tmpAttr);     
+}
+
+
+//Добавить аттрибут цвета текста
+void Table::addCellUnderlineAttribute(uint8_t col, uint8_t row) {
+    pTerminal->getCommand_UnderlineText(tmpAttr, tmpAttrSize); 
+    addCellAttribute(col, row, tmpAttr);     
+}
+
+
+//Очистить аттрибуты ячейки 
+void Table::clearCellAttributes(uint8_t col, uint8_t row) {          
+    CellAttribute& cell = cells[col][row];
+    
+    cell.text = 0;
+        
+    char* attributes = cell.attributes;
+    uint32_t attrSize = sizeof(cell.attributes);
+    
+    memset(attributes, 0, attrSize);
+}
+
+
+//Дописать аттрибут к ячейке
+void Table::addCellAttribute(uint8_t col, uint8_t row, const char* attr) {
+    CellAttribute& cell = cells[col][row];    
+    
+    uint8_t attrSize = strlen(cell.attributes);    
+    char* dst = &cell.attributes[attrSize];
+    
+    attrSize = strlen(attr);
+    memcpy(dst, attr, attrSize);
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Работа с выводом элементов рамки
+//-----------------------------------------------------------------------------
+
+
+//Символы псевдографики
+//----------------------------------------
+//─│┌┐└┘├┤┬┴┼═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬
+//----------------------------------------
+
+
+//Печать верхней границы рамки
+void Table::printTopLine(uint32_t& line) {
+    printFrameLine(line, "┌", "┐", "┬", "─");
+}
+
+//Печать линии в таблице
+void Table::printCrossLine(uint32_t& line) {
+    printFrameLine(line, "├", "┤", "┼", "─");
+}
+
+//Печать рамки для отдельной строки
+void Table::printTextLine(uint32_t& line) {
+    printFrameLine(line, "│", "│", "│", " ");
+}
+
+//Печать нижней границы рамки таблицы
+void Table::printBottomLine(uint32_t& line) {
+    printFrameLine(line, "└", "┘", "┴", "─");
+}
+
+
+////Печать верхней границы рамки
+//void Table::printTopLine(uint32_t& line) {
+//    printFrameLine(line, "╔", "╗", "╤", "═");
+//}
+
+////Печать линии в таблице
+//void Table::printCrossLine(uint32_t& line) {
+//    printFrameLine(line, "╟", "╢", "┼", "─");
+//}
+
+////Печать рамки для отдельной строки
+//void Table::printTextLine(uint32_t& line) {
+//    printFrameLine(line, "║", "║", "│", " ");
+//}
+
+////Печать нижней границы рамки таблицы
+//void Table::printBottomLine(uint32_t& line) {
+//    printFrameLine(line, "╚", "╝", "╧", "═");
+//}
+
+
+
+
+//Выводит строку рамки таблицы
+void Table::printFrameLine(uint32_t& line, 
+    const char* lc, const char* rc, const char* cr, const char* ln)
+{
+    pTerminal->moveToPos(m_x, line);
+    
+    //Left corner
+    print(lc);
+    
+    for (uint8_t c = 0; c < m_col; c++) 
+    {
+        //Print line charachter
+        uint8_t width = 0;
+        while (width < m_width[c]) {
+            print(ln);
+            width++;
+        }
+        if (c < (m_col - 1)) 
+            //Print cross character
+            print(cr);
+        else
+            //Print right corner
+            print(rc);  
+    }
+    line++;
+}
+
+
+
+
+void Table::print(const char* str) {
+    pTerminal->print(str);
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Преобразование числа в строку ANSI C через быстрое деление
+//-----------------------------------------------------------------------------
+
+struct divmod10_t
+{
+    uint32_t quot;
+    uint8_t rem;
+};
+
+
+
+inline static divmod10_t divmodu10(uint32_t n)
+{
+    divmod10_t res;
+
+    res.quot = n >> 1;
+    res.quot += res.quot >> 1;
+    res.quot += res.quot >> 4;
+    res.quot += res.quot >> 8;
+    res.quot += res.quot >> 16;
+    uint32_t qq = res.quot;
+
+    res.quot >>= 3;
+    res.rem = uint8_t(n - ((res.quot << 1) + (qq & ~7ul)));
+    if(res.rem > 9)
+    {
+        res.rem -= 10;
+        res.quot++;
+    }
+    return res;
+}
+
+
+static char utoaBuffer[13];
+
+//utoa fast div
+char * utoa(uint32_t value)
+{
+    char* buffer = &utoaBuffer[1];
+    buffer += 11;
+    *--buffer = 0;
+    do
+    {
+        divmod10_t res = divmodu10(value);
+        *--buffer = res.rem + '0';
+        value = res.quot;
+    }
+    while (value != 0);
+    return buffer;
+}
+
+
+
+
+//utoa fast div
+char * itoa(int32_t value)
+{
+    //Чёто неохото было гуглить. Мой
+    //тупой вариант взятия модуля
+    uint32_t unsignedValue = value;
+    if (value < 0)
+        unsignedValue = (uint32_t)(value - (2*value));
+    
+    char* unsignedStr = utoa(unsignedValue);
+    
+    //Добавляем знак минус в начало
+    if (value < 0) {
+        unsignedStr--;
+        *unsignedStr = '-';       
+    }
+           
+    return unsignedStr;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 161 - 0
desk/modules/terminal/terminal.h

@@ -0,0 +1,161 @@
+#ifndef __TERMINAL_H
+#define __TERMINAL_H
+
+
+#include "stm32g4xx_hal.h"
+#include "microrl.h"
+
+#define EOL "\n\r"
+#define COUNT_TERMINAL_INTERFACE  2
+
+//Function for print on concrete interface
+typedef void (*InterfacePrint)(const char * str);
+
+typedef struct {
+    InterfacePrint print;
+    char* description[10];
+} TerminalInterface;
+
+
+
+
+//-----------------------------------------------------------------------------
+// Базовый класс терминала
+//-----------------------------------------------------------------------------
+
+typedef enum { 
+    tc_Black = 0x0, tc_Red, tc_Green, tc_Yello, tc_Blue, tc_Magenta, tc_Cyan, tc_White
+} TextColor;
+
+
+class Terminal
+{
+public:
+    Terminal();
+
+    virtual void connectCallback();
+
+    void addPrint(InterfacePrint print_func);
+    void clearScreen();   
+    void moveToPos(uint32_t h, uint32_t v);
+    void moveToUpLeftCorner();
+    void reset();
+    void resetAttribute();
+    void saveCursorPos();
+    void restoreCursorPos();
+    void hideCursor();
+    void clearCurrentLine();
+    
+
+    //Формирование команд терминала
+    uint32_t getCommand_MoveToPos(char* res_command, uint32_t& res_size, uint32_t h, uint32_t v);
+    uint32_t getCommand_MoveUpNLines(char* res_command, uint32_t& res_size, uint32_t n);
+    uint32_t getCommand_MoveDownNLines(char* res_command, uint32_t& res_size, uint32_t n);
+    uint32_t getCommand_MoveRightNLines(char* res_command, uint32_t& res_size, uint32_t n);
+    uint32_t getCommand_MoveLeftNLines(char* res_command, uint32_t& res_size, uint32_t n);
+    uint32_t getCommand_SetTextColor(char* res_command, uint32_t& res_size, TextColor color);
+    uint32_t getCommand_UnderlineText(char* res_command, uint32_t& res_size);
+
+public:
+    virtual void configure();
+    void insert(int ch);
+    void print(const char * str);
+    void printl(const char * str);
+    void printll(const char * str);
+    void eol();
+    void printeol();
+    
+    virtual int execute(int argc, const char * const * argv);
+    virtual char ** completion(int argc, const char * const * argv);
+    virtual void sigint (void);
+    
+    
+private:
+    InterfacePrint f_print[COUNT_TERMINAL_INTERFACE];
+    int m_countPrintFunction;
+
+    microrl_t rl;
+    microrl_t * prl;
+};
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Класс таблицы
+//-----------------------------------------------------------------------------    
+#define MAX_COL 8
+#define MAX_ROW 10    
+    
+class Table {
+public:
+    Table();
+    
+    void outToCell(uint8_t col, uint8_t row, const char* str);
+    void outToCell(uint8_t col, uint8_t row, uint32_t val);
+    void outCellNumber();
+    virtual void outStatic();
+    void outExternalBorder();    
+    void outCrossLine(uint8_t row);
+
+    void startUpdate();
+    void endUpdate();
+
+    //virtual void refreshData();
+    
+    void setGeometry(uint8_t x, uint8_t y, uint8_t col, uint8_t row, uint32_t width, ...);
+    void setGeometry(uint8_t x, uint8_t y, uint8_t col, uint8_t row, const uint32_t* width);
+
+private:
+    void setPos(uint8_t x, uint8_t y);
+    void setSize(uint8_t col, uint8_t row);
+    void resetAttributes();
+
+public:
+    void addCellPosAttribute(uint8_t col, uint8_t row);
+    void addCellColorAttribute(uint8_t col, uint8_t row, TextColor color);
+    void addCellUnderlineAttribute(uint8_t col, uint8_t row);
+    inline void clearCellAttributes(uint8_t col, uint8_t row);
+
+protected:
+    inline void addCellAttribute(uint8_t col, uint8_t row, const char* attr);
+
+private:
+    inline void printTopLine(uint32_t& line);
+    inline void printCrossLine(uint32_t& line);
+    inline void printTextLine(uint32_t& line);
+    inline void printBottomLine(uint32_t& line);
+
+    void printFrameLine(uint32_t& line, 
+        const char* lc, const char* rc,
+        const char* cr, const char* ln);
+            
+    inline void print(const char* str);    
+
+private:
+    uint8_t m_x, m_y;
+    uint8_t m_col, m_row;    
+    uint8_t m_width[MAX_COL];    
+
+    typedef struct {
+        char    attributes[40]; 
+        char*   text;
+    } CellAttribute;
+    
+    CellAttribute cells[MAX_COL][MAX_ROW];    
+}; 
+
+
+
+
+
+
+
+extern Terminal* pTerminal;
+char * utoa(uint32_t value);
+char * itoa(int32_t value);
+
+
+
+#endif // __TERMINAL_H

+ 173 - 0
desk/modules/terminal/terminal_usartbridge.cpp

@@ -0,0 +1,173 @@
+#include "terminal_usartbridge.h"
+#include "terminal_user.h"
+#include <string.h>
+#include <stdio.h>
+
+
+UsartBridgeTerminal terminalUsartBridge;
+
+extern Terminal* pTerminal;
+
+
+#ifdef __GNUC__    
+  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)    
+#else    
+  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)    
+#endif  
+
+PUTCHAR_PROTOTYPE   
+{   
+    terminalUsartBridge.uart.Instance->TDR = (uint16_t)(ch & 0x01FF);
+    while (!(terminalUsartBridge.uart.Instance->ISR & UART_FLAG_TC)) {}
+  
+    return ch; 
+}  
+
+//-----------------------------------------------------------------------------
+// Connect usartBridge objectt with ANSI C Interfaces
+//-----------------------------------------------------------------------------
+
+//Configure usart bridge
+void configure_usartbridge() {
+    terminalUsartBridge.configure();
+}
+
+//Print callback for terminal object
+void print_usartbridge(const char * str) {
+    terminalUsartBridge.print(str);
+}
+
+
+//-----------------------------------------------------------------------------
+// Usart Bridge for terminal
+//-----------------------------------------------------------------------------
+UsartBridgeTerminal::UsartBridgeTerminal():
+    m_readIndex(0),
+    m_state(true),
+    m_isTxNoEmpty(false)
+{
+}
+
+UsartBridgeTerminal::~UsartBridgeTerminal()
+{
+}
+
+
+//Configure hardware and link with terminal
+void UsartBridgeTerminal::configure()
+{
+    m_sizeCache = 0;
+    m_readIndex = 0;
+    m_isTxNoEmpty = false;
+	
+    InitUsart();
+
+    //Add usart print to global terminal object
+    pTerminal->addPrint(::print_usartbridge);
+}
+
+
+//print function
+void UsartBridgeTerminal::print(const char *str)
+{
+    uint16_t index = 0;
+    uint16_t len = strlen(str);
+    if (len <= 0)
+      return;
+    
+    while (index < len) {
+        sendByte(str[index++]);
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+// Hardware usart function
+//-----------------------------------------------------------------------------
+
+extern "C" {
+
+void USART_BRIDGE_IRQHandler(void) 
+{
+    HAL_UART_IRQHandler(&terminalUsartBridge.uart);
+}
+}
+
+
+//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+void HAL_UART_RxCpltCallbackTerminal(void)
+{
+    if (terminalUsartBridge.m_state) {
+        terminalUsartBridge.recvByte();
+    }
+      
+    HAL_UART_Receive_IT(&terminalUsartBridge.uart, (uint8_t*)&terminalUsartBridge.m_uartByte, 1);
+}
+
+
+//void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+void HAL_UART_TxCpltCallbackTerminal(void)
+{
+    terminalUsartBridge.clearTxNoEmpty();
+}
+
+
+//Recv byte from usart
+void UsartBridgeTerminal::recvByte()
+{
+    sbsTerminal.put_byte((char)(uart.Instance->RDR & (uint16_t)0x01FF));
+}
+
+
+//Send byte to usart
+void UsartBridgeTerminal::sendByte(uint8_t byte)
+{
+    m_isTxNoEmpty = true;
+    terminalUsartBridge.uart.Instance->TDR = (uint16_t)(byte & 0x01FF);
+    while (!(terminalUsartBridge.uart.Instance->ISR & UART_FLAG_TC)) {}
+}
+
+
+//Clear TX No Empty flag
+void UsartBridgeTerminal::clearTxNoEmpty() 
+{
+    m_isTxNoEmpty = false;
+}
+
+
+//Init USART
+void UsartBridgeTerminal::InitUsart()
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+    
+    USART_BRIDGE_TX_PORT_CLK_ENABLE
+    USART_BRIDGE_RX_PORT_CLK_ENABLE  
+  
+    GPIO_InitStruct.Pin       = USART_BRIDGE_TX_PIN;
+    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull      = GPIO_PULLUP;
+    GPIO_InitStruct.Speed     = GPIO_SPEED_HIGH;
+    GPIO_InitStruct.Alternate = USART_BRIDGE_AF;
+    HAL_GPIO_Init(USART_BRIDGE_TX_PORT, &GPIO_InitStruct);
+      
+    GPIO_InitStruct.Pin       = USART_BRIDGE_RX_PIN;
+    HAL_GPIO_Init(USART_BRIDGE_RX_PORT, &GPIO_InitStruct);  
+      
+
+    USART_BRIDGE_CLK_ENABLE
+
+    uart.Instance           = USART_BRIDGE_USART;
+    uart.Init.BaudRate      = USART_BRIDGE_SPEED;
+    uart.Init.WordLength    = UART_WORDLENGTH_8B;
+    uart.Init.StopBits      = UART_STOPBITS_1;
+    uart.Init.Parity        = UART_PARITY_NONE;
+    uart.Init.Mode          = UART_MODE_TX_RX;
+    uart.Init.HwFlowCtl     = UART_HWCONTROL_NONE;
+    uart.Init.OverSampling  = UART_OVERSAMPLING_8;
+    uart.Init.OneBitSampling= UART_ONE_BIT_SAMPLE_DISABLE;
+    HAL_UART_Init(&uart);
+
+    HAL_NVIC_SetPriority(USART_BRIDGE_IRQn, 6, 0);
+    HAL_NVIC_EnableIRQ(USART_BRIDGE_IRQn);
+    HAL_UART_Receive_IT(&uart, (uint8_t*)&m_uartByte, 1);
+}

+ 86 - 0
desk/modules/terminal/terminal_usartbridge.h

@@ -0,0 +1,86 @@
+#ifndef __USARTBRIDGETERMINAL_H
+#define __USARTBRIDGETERMINAL_H
+
+#include "stm32g4xx_hal.h"
+#include "terminal.h"
+
+
+//Usart configuration
+#define USART_BRIDGE_USART            USART3
+#define USART_BRIDGE_SPEED            115200 
+#define USART_BRIDGE_IRQn             USART3_IRQn
+#define USART_BRIDGE_IRQHandler       USART3_IRQHandler
+#define USART_BRIDGE_AF               GPIO_AF7_USART3
+#define USART_BRIDGE_TX_PIN           GPIO_PIN_10
+#define USART_BRIDGE_RX_PIN           GPIO_PIN_11
+#define USART_BRIDGE_TX_PORT          GPIOB
+#define USART_BRIDGE_RX_PORT          GPIOB
+#define USART_BRIDGE_CLK_ENABLE       __USART3_CLK_ENABLE();
+#define USART_BRIDGE_TX_PORT_CLK_ENABLE  __HAL_RCC_GPIOB_CLK_ENABLE();
+#define USART_BRIDGE_RX_PORT_CLK_ENABLE  __HAL_RCC_GPIOB_CLK_ENABLE();
+
+
+//-----------------------------------------------------------------------------
+
+// Connect usartBridge objectt with ANSI C Interfaces
+
+//-----------------------------------------------------------------------------
+
+
+//Task for freertos function
+void task_usartbridge(void *pvParameters);
+
+//Ansi C interface for usartBridge object
+
+void configure_usartbridge();
+void processing_usartbridge();
+void print_usartbridge(const char * str);
+void vTaskUsartBridge(void *params);
+void HAL_UART_RxCpltCallbackTerminal(void);
+void HAL_UART_TxCpltCallbackTerminal(void);
+
+//-----------------------------------------------------------------------------
+
+// Usart bridge class for terminal
+
+//-----------------------------------------------------------------------------
+
+class UsartBridgeTerminal
+{
+public:
+
+    UsartBridgeTerminal();
+    ~UsartBridgeTerminal();
+
+    void configure();
+    void print(const char *str);
+
+public:
+
+    void recvByte();
+    void sendByte(uint8_t byte);
+    void clearTxNoEmpty();
+
+private:
+
+    void InitUsart();
+
+public:
+    
+    UART_HandleTypeDef uart;
+    char               m_uartByte;
+    bool               m_state;
+    
+private:
+
+    uint32_t m_sizeCache;
+    uint32_t m_readIndex;
+    bool m_isTxNoEmpty;
+};
+
+
+extern UsartBridgeTerminal terminalUsartBridge;
+
+
+#endif // USARTBRIDGETERMINAL_H
+

+ 153 - 0
desk/modules/terminal/terminal_usbbridge.cpp

@@ -0,0 +1,153 @@
+#include "terminal_usbbridge.h"
+#include "terminal_sbs.h"
+#include "usbd_cdc.h" 
+#include "usbd_desc.h"
+#include "cmsis_os.h"
+#include "usbd_cdc_interface.h"
+#include "fpga_blaster.h"
+#include "_config.h"
+#include <string.h>
+#include <stdio.h>
+
+
+
+osThreadId usbBridgeHandle;
+
+osThreadId usbRxHandle;
+osThreadId usbTxHandle;
+
+//Usart bridge object for global terminal
+UsbBridgeTerminal terminalUsbBridge;
+
+//Pointer to global terminal object
+extern Terminal* pTerminal;
+
+
+//Print callback for terminal object
+void print_usbbridge(const char * str) {
+    terminalUsbBridge.print(str);
+}
+
+
+
+UsbBridgeTerminal::UsbBridgeTerminal()
+{
+    m_fpga_blast = false;
+}
+
+UsbBridgeTerminal::~UsbBridgeTerminal()
+{
+}
+
+
+//Configure hardware and link with terminal
+void UsbBridgeTerminal::configure()
+{
+    m_recvQueue = xQueueCreate(10, sizeof(char));
+  
+    m_sendQueue = xQueueCreate(200, sizeof(char));
+    
+    CDC_SetRecvCb(&USB_RecvByte);
+
+    // Добавить функцию печати в терминал
+    pTerminal->addPrint(::print_usbbridge);
+
+    osThreadDef(UsbTx, vUsbTx, osPriorityNormal, 0, 2*128);
+    usbTxHandle = osThreadCreate(osThread(UsbTx), NULL);;
+    
+    osThreadDef(UsbRx, vUsbRx, osPriorityNormal, 0, 2*128);
+    usbRxHandle = osThreadCreate(osThread(UsbRx), NULL);
+}
+
+
+//
+void UsbBridgeTerminal::print(const char *str)
+{
+    uint16_t len = strlen(str);
+
+    if (len <= 0)
+        return;
+
+    CDC_Itf_Transmit((uint8_t*)str, len);
+    vTaskDelay(1);    
+}
+
+
+// Recv byte from vcp
+void UsbBridgeTerminal::recvByte(char byte)
+{
+    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
+    
+    xQueueSendFromISR(m_recvQueue, &byte, &xHigherPriorityTaskWoken);
+    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
+}
+
+
+//
+void UsbBridgeTerminal::sendByte(uint8_t byte)
+{
+    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
+    xQueueSendFromISR(m_sendQueue, &byte, &xHigherPriorityTaskWoken);
+}
+
+
+//
+void UsbBridgeTerminal::set_fpga_blast(bool state)
+{
+    m_fpga_blast = state;
+}
+
+
+//
+void USB_RecvByte(uint8_t* byte, uint32_t size)
+{
+    if (terminalUsbBridge.m_fpga_blast) {
+        fpga_blast.receive(byte, size);
+    }
+    else {
+        for (uint32_t i = 0; i < size; i++) {
+            terminalUsbBridge.recvByte(*byte++);
+        }
+    }
+}
+
+//
+void UsbBridgeTerminal::txProc()
+{
+    uint8_t byte;
+    
+    if (xQueueReceive(m_sendQueue, &byte, portMAX_DELAY) == pdTRUE)
+    {
+        CDC_Itf_Transmit(&byte, 1);
+        vTaskDelay(1);    
+    }
+}
+
+//
+void UsbBridgeTerminal::rxProc()
+{
+    uint8_t byte;
+    
+    if (xQueueReceive(m_recvQueue, &byte, portMAX_DELAY) == pdTRUE)
+    {
+        pTerminal->insert(byte); 
+    }
+}    
+
+//
+void vUsbTx(void const *params)
+{
+    for (;;)
+    {
+        terminalUsbBridge.txProc();
+    }
+}
+
+//
+void vUsbRx(void const *params)
+{
+    for (;;)
+    {
+        terminalUsbBridge.rxProc();
+    }
+}

+ 48 - 0
desk/modules/terminal/terminal_usbbridge.h

@@ -0,0 +1,48 @@
+#ifndef __TERMINAL_USBBRIDGE_H
+#define __TERMINAL_USBBRIDGE_H
+
+#include "stm32f7xx.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "terminal.h"
+#include <stdbool.h>
+
+
+class UsbBridgeTerminal {
+
+public :
+
+    UsbBridgeTerminal();
+    ~UsbBridgeTerminal();
+    void configure();
+
+public :
+
+    QueueHandle_t m_recvQueue;
+    QueueHandle_t m_sendQueue;
+    
+    void rxProc();
+    void txProc();
+    
+    void print(const char *str);
+    void recvByte(char byte);  
+    void sendByte(uint8_t byte);
+    
+    void set_fpga_blast(bool state);
+
+public :    
+  
+    bool m_fpga_blast;
+};
+
+
+extern UsbBridgeTerminal terminalUsbBridge;
+
+
+void vUsbTx(void const *params);
+void vUsbRx(void const *params);
+void USB_RecvByte(uint8_t* byte, uint32_t size);
+
+
+#endif // __TERMINAL_USBBRIDGE_H

+ 167 - 0
desk/modules/terminal/terminal_user.cpp

@@ -0,0 +1,167 @@
+#include "terminal_user.h"
+#include "cmsis_os.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+
+SbsTerminal sbsTerminal;
+Terminal* pTerminal;
+
+osThreadId terminaltTaskHandle;
+void vTerminal(void const *params);
+
+
+//
+SbsTerminal::SbsTerminal() :
+    Terminal()
+{}
+
+
+//
+void SbsTerminal::configure()
+{
+    Terminal::configure();
+    pTerminal = &sbsTerminal;
+    
+    osMessageQDef(TerminalQueue, 20, uint8_t);
+    m_dataQueue = osMessageCreate(osMessageQ(TerminalQueue), NULL);
+      
+    osThreadDef(Terminal, vTerminal, osPriorityNormal, 0, 2*128);
+    terminaltTaskHandle = osThreadCreate(osThread(Terminal), NULL);
+}
+
+
+//
+int SbsTerminal::execute(int argc, const char * const *argv)
+{
+    if (argc <= 0) {
+        return -1;
+    }
+    if (strcmp(argv[0], "help") == 0) {
+        return help(argc, argv);
+    }
+    else if (strcmp(argv[0], "version") == 0) {
+        return version(argc, argv);
+    }
+    else if (strcmp(argv[0], "clear") == 0) {
+        return clear(argc, argv);
+    }    
+    else if (strcmp(argv[0], "reset") == 0) {
+        NVIC_SystemReset();
+    }
+
+    // ---------------------------------------------------------------------- //
+    else {
+        printeol();
+        printll("Uncknown command [oO]");
+        return 0;
+    }
+}
+
+
+void SbsTerminal::sigint() {
+}
+
+
+//Колбэк, который может быть вызван при подключении
+void SbsTerminal::connectCallback() 
+{
+    clearScreen();
+    printll("SBS terminal.");
+  
+    //Тут выводим полезную при подключении информацию
+    printeol();
+    printll("For help type 'help'.");
+    insert('\r');    
+}
+    
+
+//
+int SbsTerminal::help(int argc, const char * const *argv)
+{
+    printeol();
+    printeol();
+    printl ("You can use the following commands:");
+    printl ("  version        Print nSBS software version");
+    printl ("  os             Print FreeRTOS statistics");
+    printl ("  stat           Print FreeRTOS common controller statistics");
+    printl ("  ifconfig       Print net params");
+    printl ("  set_ip         Set IP address");
+    printl ("  set_mask       Set netmask");
+    printl ("  set_gw         Set gateway");
+    printl ("  set_usb_ip     Set IP address for RNDIS");
+    printl ("  set_usb_mask   Set netmask for RNDIS");
+    printl ("  set_usb_gw     Set gateway for RNDIS");
+    printl ("  reset          Controller reset");
+    printl ("  boot           Go to DFU mode");
+    printl ("  clear          Clear terminal screen");
+    printl ("  ls             List of files");
+    printl ("  cat            Cat file");
+    printl ("  del            Delete file");
+    printl ("  format         Format file system");
+    printl ("  phy            dump phy reisters");
+    printl ("  fpga_boot      Prepare FPGA for download mode");
+    printll("  update         update main firmaware");
+    printeol();
+    
+    help_connection();
+    return 0;
+}
+
+
+// Справка по поводу соединения
+int SbsTerminal::help_connection() 
+{
+    return 0;
+}
+
+
+//
+int SbsTerminal::version(int argc, const char * const *argv) 
+{
+    printeol();
+    //print(FW_VERSION);
+    printeol();
+    return 0;
+}
+
+
+//
+int SbsTerminal::clear(int argc, const char * const *argv)
+{
+    if ((argc > 1) && (strcmp(argv[1], "help") == 0))  
+    {
+        printeol();
+        printl("Clear terminal screen");      
+        printeol();
+        printeol();
+        return 0;
+    }
+    clearScreen();
+    return 0;
+}
+
+
+
+//
+void SbsTerminal::put_byte(char byte)
+{
+    osMessagePut(m_dataQueue, byte, 0);
+}
+
+//
+void vTerminal(void const *params)
+{
+    osEvent event;
+    
+    for (;;)
+    {
+        event = osMessageGet(sbsTerminal.m_dataQueue, 1000);
+       
+        if (event.status == osEventMessage) {
+            sbsTerminal.insert(event.value.v);
+        }
+    }  
+}

+ 41 - 0
desk/modules/terminal/terminal_user.h

@@ -0,0 +1,41 @@
+#ifndef __TERMINAL_USER_H
+#define __TERMINAL_USER_H
+
+#include "cmsis_os.h"
+#include "terminal.h"
+
+
+
+class SbsTerminal : public Terminal
+{
+public:
+    SbsTerminal();
+
+    virtual void configure();
+    virtual int execute(int argc, const char * const * argv);
+    virtual void sigint (void);
+    virtual void connectCallback();
+
+
+public:
+    int help(int argc, const char * const * argv);
+    int help_connection();
+    int version(int argc, const char * const * argv);
+    int clear(int argc, const char * const * argv);
+    int reset(int argc, const char * const * argv);
+    
+    
+public:
+    
+    void put_byte(char byte);
+    
+public :
+  
+    osMessageQId m_dataQueue;
+    
+};
+
+extern SbsTerminal sbsTerminal;
+
+
+#endif // __TERMINAL_USER_H

+ 171 - 171
desk/user/FreeRTOSConfig.h

@@ -1,171 +1,171 @@
-/* USER CODE BEGIN Header */
-/*
- * FreeRTOS Kernel V10.3.1
- * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
- * Portion Copyright (C) 2019 StMicroelectronics, Inc.  All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-/* USER CODE END Header */
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * These parameters and more are described within the 'configuration' section of the
- * FreeRTOS API documentation available on the FreeRTOS.org web site.
- *
- * See http://www.freertos.org/a00110.html
- *----------------------------------------------------------*/
-
-/* USER CODE BEGIN Includes */
-/* Section where include file can be added */
-/* USER CODE END Includes */
-
-/* Ensure definitions are only used by the compiler, and not by the assembler. */
-#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
-  #include <stdint.h>
-  extern uint32_t SystemCoreClock;
-  void xPortSysTickHandler(void);
-#endif
-#ifndef CMSIS_device_header
-#define CMSIS_device_header "stm32g4xx.h"
-#endif /* CMSIS_device_header */
-
-#define configENABLE_FPU                         0
-#define configENABLE_MPU                         0
-
-#define configUSE_PREEMPTION                     1
-#define configSUPPORT_STATIC_ALLOCATION          1
-#define configSUPPORT_DYNAMIC_ALLOCATION         1
-#define configUSE_IDLE_HOOK                      0
-#define configUSE_TICK_HOOK                      0
-#define configCPU_CLOCK_HZ                       ( SystemCoreClock )
-#define configTICK_RATE_HZ                       ((TickType_t)1000)
-#define configMAX_PRIORITIES                     ( 56 )
-#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
-#define configTOTAL_HEAP_SIZE                    ((size_t)3072)
-#define configMAX_TASK_NAME_LEN                  ( 16 )
-#define configUSE_TRACE_FACILITY                 1
-#define configUSE_16_BIT_TICKS                   0
-#define configUSE_MUTEXES                        1
-#define configQUEUE_REGISTRY_SIZE                8
-#define configUSE_RECURSIVE_MUTEXES              1
-#define configUSE_COUNTING_SEMAPHORES            1
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0
-/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
-/* Defaults to size_t for backward compatibility, but can be changed
-   if lengths will always be less than the number of bytes in a size_t. */
-#define configMESSAGE_BUFFER_LENGTH_TYPE         size_t
-/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES                    0
-#define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )
-
-/* Software timer definitions. */
-#define configUSE_TIMERS                         1
-#define configTIMER_TASK_PRIORITY                ( 2 )
-#define configTIMER_QUEUE_LENGTH                 10
-#define configTIMER_TASK_STACK_DEPTH             256
-
-/* CMSIS-RTOS V2 flags */
-#define configUSE_OS2_THREAD_SUSPEND_RESUME  1
-#define configUSE_OS2_THREAD_ENUMERATE       1
-#define configUSE_OS2_EVENTFLAGS_FROM_ISR    1
-#define configUSE_OS2_THREAD_FLAGS           1
-#define configUSE_OS2_TIMER                  1
-#define configUSE_OS2_MUTEX                  1
-
-/* Set the following definitions to 1 to include the API function, or zero
-to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet             1
-#define INCLUDE_uxTaskPriorityGet            1
-#define INCLUDE_vTaskDelete                  1
-#define INCLUDE_vTaskCleanUpResources        0
-#define INCLUDE_vTaskSuspend                 1
-#define INCLUDE_vTaskDelayUntil              1
-#define INCLUDE_vTaskDelay                   1
-#define INCLUDE_xTaskGetSchedulerState       1
-#define INCLUDE_xTimerPendFunctionCall       1
-#define INCLUDE_xQueueGetMutexHolder         1
-#define INCLUDE_uxTaskGetStackHighWaterMark  1
-#define INCLUDE_xTaskGetCurrentTaskHandle    1
-#define INCLUDE_eTaskGetState                1
-
-/*
- * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
- * by the application thus the correct define need to be enabled below
- */
-#define USE_FreeRTOS_HEAP_4
-
-/* Cortex-M specific definitions. */
-#ifdef __NVIC_PRIO_BITS
- /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
- #define configPRIO_BITS         __NVIC_PRIO_BITS
-#else
- #define configPRIO_BITS         4
-#endif
-
-/* The lowest interrupt priority that can be used in a call to a "set priority"
-function. */
-#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15
-
-/* The highest interrupt priority that can be used by any interrupt service
-routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
-INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
-PRIORITY THAN THIS! (higher priorities are lower numeric values. */
-#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
-
-/* Interrupt priorities used by the kernel port layer itself.  These are generic
-to all Cortex-M ports, and do not rely on any particular library functions. */
-#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
-See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
-#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-
-/* Normal assert() semantics without relying on the provision of an assert.h
-header file. */
-/* USER CODE BEGIN 1 */
-#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
-/* USER CODE END 1 */
-
-/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
-standard names. */
-#define vPortSVCHandler    SVC_Handler
-#define xPortPendSVHandler PendSV_Handler
-
-/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
-
-#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1
-
-/* USER CODE BEGIN Defines */
-/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
-/* USER CODE END Defines */
-
-#endif /* FREERTOS_CONFIG_H */
+/* USER CODE BEGIN Header */
+/*
+ * FreeRTOS Kernel V10.3.1
+ * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
+ * Portion Copyright (C) 2019 StMicroelectronics, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+/* USER CODE END Header */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * These parameters and more are described within the 'configuration' section of the
+ * FreeRTOS API documentation available on the FreeRTOS.org web site.
+ *
+ * See http://www.freertos.org/a00110.html
+ *----------------------------------------------------------*/
+
+/* USER CODE BEGIN Includes */
+/* Section where include file can be added */
+/* USER CODE END Includes */
+
+/* Ensure definitions are only used by the compiler, and not by the assembler. */
+#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
+  #include <stdint.h>
+  extern uint32_t SystemCoreClock;
+  void xPortSysTickHandler(void);
+#endif
+#ifndef CMSIS_device_header
+#define CMSIS_device_header "stm32g4xx.h"
+#endif /* CMSIS_device_header */
+
+#define configENABLE_FPU                         0
+#define configENABLE_MPU                         0
+
+#define configUSE_PREEMPTION                     1
+#define configSUPPORT_STATIC_ALLOCATION          0
+#define configSUPPORT_DYNAMIC_ALLOCATION         1
+#define configUSE_IDLE_HOOK                      0
+#define configUSE_TICK_HOOK                      0
+#define configCPU_CLOCK_HZ                       ( SystemCoreClock )
+#define configTICK_RATE_HZ                       ((TickType_t)1000)
+#define configMAX_PRIORITIES                     ( 12 )
+#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
+#define configTOTAL_HEAP_SIZE                    ((size_t)(22 * 1024))
+#define configMAX_TASK_NAME_LEN                  ( 16 )
+#define configUSE_TRACE_FACILITY                 1
+#define configUSE_16_BIT_TICKS                   0
+#define configUSE_MUTEXES                        1
+#define configQUEUE_REGISTRY_SIZE                8
+#define configUSE_RECURSIVE_MUTEXES              1
+#define configUSE_COUNTING_SEMAPHORES            1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0
+/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
+/* Defaults to size_t for backward compatibility, but can be changed
+   if lengths will always be less than the number of bytes in a size_t. */
+#define configMESSAGE_BUFFER_LENGTH_TYPE         size_t
+/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES                    0
+#define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS                         1
+#define configTIMER_TASK_PRIORITY                ( 10 )
+#define configTIMER_QUEUE_LENGTH                 10
+#define configTIMER_TASK_STACK_DEPTH             256
+
+/* CMSIS-RTOS V2 flags */
+#define configUSE_OS2_THREAD_SUSPEND_RESUME  1
+#define configUSE_OS2_THREAD_ENUMERATE       1
+#define configUSE_OS2_EVENTFLAGS_FROM_ISR    1
+#define configUSE_OS2_THREAD_FLAGS           1
+#define configUSE_OS2_TIMER                  1
+#define configUSE_OS2_MUTEX                  1
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet             1
+#define INCLUDE_uxTaskPriorityGet            1
+#define INCLUDE_vTaskDelete                  1
+#define INCLUDE_vTaskCleanUpResources        0
+#define INCLUDE_vTaskSuspend                 1
+#define INCLUDE_vTaskDelayUntil              1
+#define INCLUDE_vTaskDelay                   1
+#define INCLUDE_xTaskGetSchedulerState       1
+#define INCLUDE_xTimerPendFunctionCall       1
+#define INCLUDE_xQueueGetMutexHolder         1
+#define INCLUDE_uxTaskGetStackHighWaterMark  1
+#define INCLUDE_xTaskGetCurrentTaskHandle    1
+#define INCLUDE_eTaskGetState                1
+
+/*
+ * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
+ * by the application thus the correct define need to be enabled below
+ */
+#define USE_FreeRTOS_HEAP_4
+
+/* Cortex-M specific definitions. */
+#ifdef __NVIC_PRIO_BITS
+ /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
+ #define configPRIO_BITS         __NVIC_PRIO_BITS
+#else
+ #define configPRIO_BITS         4
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority"
+function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
+
+/* Interrupt priorities used by the kernel port layer itself.  These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* Normal assert() semantics without relying on the provision of an assert.h
+header file. */
+/* USER CODE BEGIN 1 */
+#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
+/* USER CODE END 1 */
+
+/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
+standard names. */
+#define vPortSVCHandler    SVC_Handler
+#define xPortPendSVHandler PendSV_Handler
+
+/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
+
+#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1
+
+/* USER CODE BEGIN Defines */
+/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
+/* USER CODE END Defines */
+
+#endif /* FREERTOS_CONFIG_H */

+ 105 - 0
desk/user/MicroRLConfig.h

@@ -0,0 +1,105 @@
+/*
+Microrl library config files
+Autor: Eugene Samoylov aka Helius (ghelius@gmail.com)
+*/
+#ifndef _MICRORL_CONFIG_H_
+#define _MICRORL_CONFIG_H_
+
+#define MICRORL_LIB_VER "1.5.1"
+
+/*********** CONFIG SECTION **************/
+/*
+Command line length, define cmdline buffer size. Set max number of chars + 1,
+because last byte of buffer need to contain '\0' - NULL terminator, and 
+not use for storing inputed char.
+If user input chars more then it parametrs-1, chars not added to command line.*/
+#define _COMMAND_LINE_LEN (1+100)									// for 32 chars
+
+/*
+Command token number, define max token it command line, if number of token 
+typed in command line exceed this value, then prints message about it and
+command line not to be parced and 'execute' callback will not calls.
+Token is word separate by white space, for example 3 token line:
+"IRin> set mode test" */
+#define _COMMAND_TOKEN_NMB 8
+
+/*
+Define you prompt string here. You can use colors escape code, for highlight you prompt,
+for example this prompt will green color (if you terminal supports color)*/
+//#define _PROMPT_DEFAULT "\033[32mIRin >\033[0m "	// green color
+#define _PROMPT_DEFAULT "\033[32mCMC: $\033[0m "	// green color
+//#define _PROMPT_DEFAULT "IRin > "
+
+/*
+Define prompt text (without ESC sequence, only text) prompt length, it needs because if you use
+ESC sequence, it's not possible detect only text length*/
+#define _PROMPT_LEN       7
+
+/*Define it, if you wanna use completion functional, also set completion callback in you code,
+now if user press TAB calls 'copmlitetion' callback. If you no need it, you can just set 
+NULL to callback ptr and do not use it, but for memory saving tune, 
+if you are not going to use it - disable this define.*/
+//#define _USE_COMPLETE
+
+/*Define it, if you wanna use history. It s work's like bash history, and
+set stored value to cmdline, if UP and DOWN key pressed. Using history add
+memory consuming, depends from _RING_HISTORY_LEN parametr */
+#define _USE_HISTORY
+
+/*
+History ring buffer length, define static buffer size.
+For saving memory, each entered cmdline store to history in ring buffer,
+so we can not say, how many line we can store, it depends from cmdline len,
+but memory using more effective. We not prefer dinamic memory allocation for
+small and embedded devices. Overhead is 2 char on each saved line*/
+#define _RING_HISTORY_LEN 64
+
+/*
+Enable Handling terminal ESC sequence. If disabling, then cursor arrow, HOME, END will not work,
+use Ctrl+A(B,F,P,N,A,E,H,K,U,C) see README, but decrease code memory.*/
+#define _USE_ESC_SEQ
+
+/*
+Use snprintf from you standard complier library, but it gives some overhead.
+If not defined, use my own u16int_to_str variant, it's save about 800 byte of code size
+on AVR (avr-gcc build).
+Try to build with and without, and compare total code size for tune library.
+*/
+//#define _USE_LIBC_STDIO
+
+/*
+Enable 'interrupt signal' callback, if user press Ctrl+C */
+#define _USE_CTLR_C
+
+/*
+Print prompt at 'microrl_init', if enable, prompt will print at startup, 
+otherwise first prompt will print after first press Enter in terminal
+NOTE!: Enable it, if you call 'microrl_init' after your communication subsystem 
+already initialize and ready to print message */
+#undef _ENABLE_INIT_PROMPT
+
+/*
+New line symbol */
+#define _ENDL_CR //Putty 0x0D
+//#define _ENDL_LF //netcat 0x0A 
+
+#if defined(_ENDL_CR)
+#define ENDL "\r"
+#elif defined(_ENDL_CRLF)
+#define ENDL "\r\n"
+#elif defined(_ENDL_LF)
+#define ENDL "\n"
+#elif defined(_ENDL_LFCR)
+#define ENDL "\n\r"
+#else
+#error "You must define new line symbol."
+#endif
+
+/********** END CONFIG SECTION ************/
+
+
+#if _RING_HISTORY_LEN > 256
+#error "This history implementation (ring buffer with 1 byte iterator) allow 256 byte buffer size maximum"
+#endif
+
+#endif

+ 26 - 0
desk/user/hal_callback.cpp

@@ -0,0 +1,26 @@
+#include "stm32g4xx_hal.h"
+#include "hal_callback.h"
+#include "terminal_usartbridge.h"
+
+// -------------------------------------------------------------------------- //
+//                                  UART                                      //
+// -------------------------------------------------------------------------- //
+
+/**
+  * @brief  Rx Transfer completed callback
+  * @param  huart: UART handle
+  * @retval None
+  */
+void UART_RxCpltCallback(UART_HandleTypeDef *huart);    
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+    switch((uint32_t)huart->Instance)
+    {
+        case USART3_BASE :  // HAL USART Terminal
+            HAL_UART_RxCpltCallbackTerminal();
+        break;
+        
+        default : break;
+    }    
+}
+

+ 6 - 0
desk/user/hal_callback.h

@@ -0,0 +1,6 @@
+#ifndef __HAL_CALLBACK_H
+#define __HAL_CALLBACK_H
+
+
+
+#endif

+ 22 - 17
desk/user/main.cpp

@@ -1,22 +1,20 @@
 #include "stm32g4xx_hal.h"
 #include "cmsis_os.h"
 #include "i2c.h"
-
+#include "terminal_user.h"
+#include "terminal_usartbridge.h"
+#include <stdio.h>
 
 void SystemClock_Config(void);
 void Error_Handler(void);
 
 static void MX_GPIO_Init(void);
 
-void StartDefaultTask(void *argument);
+
+void StartupTask(void const *params);
+osThreadId startupTaskHandle;
 
 
-osThreadId_t defaultTaskHandle;
-const osThreadAttr_t defaultTask_attributes = {
-    .name = "defaultTask",
-    .priority = (osPriority_t) osPriorityNormal,
-    .stack_size = 128 * 4
-};
 
 
 int main()
@@ -27,10 +25,11 @@ int main()
     
     MX_GPIO_Init();
     
-    MX_I2C1_Init();
+    //MX_I2C1_Init();
     
-    osKernelInitialize();
-    defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
+   
+    osThreadDef(Startup, StartupTask, osPriorityNormal, 0, 2*128);
+    startupTaskHandle = osThreadCreate(osThread(Startup), NULL);
     
     osKernelStart();
     
@@ -39,15 +38,21 @@ int main()
 
 
 //
-void StartDefaultTask(void *argument)
+void StartupTask(void const *argument)
 {
     //MX_USB_Device_Init();
 
-    for(;;)
-    {
-        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6);
-        osDelay(1000);
-    }
+    // Терминал
+    sbsTerminal.configure();
+            
+    // USART терминал
+    terminalUsartBridge.configure();
+    
+    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6);
+    osDelay(100);
+    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6);
+    
+    vTaskDelete(NULL);
 }
 
 

+ 2 - 2
desk/user/stm32g4xx_hal_conf.h

@@ -63,8 +63,8 @@
 /*#define HAL_SPI_MODULE_ENABLED   */
 /*#define HAL_SRAM_MODULE_ENABLED   */
 /*#define HAL_TIM_MODULE_ENABLED   */
-/*#define HAL_UART_MODULE_ENABLED   */
-/*#define HAL_USART_MODULE_ENABLED   */
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED 
 /*#define HAL_WWDG_MODULE_ENABLED   */
 #define HAL_GPIO_MODULE_ENABLED
 #define HAL_EXTI_MODULE_ENABLED

BIN
project/ewarm/desk/Debug/Exe/desk.out


BIN
project/ewarm/desk/Debug/Exe/desk.sim


+ 716 - 480
project/ewarm/desk/Debug/List/desk.map

@@ -1,6 +1,6 @@
 ###############################################################################
 #
-# IAR ELF Linker V8.40.1.212/W32 for ARM                  25/May/2025  09:52:19
+# IAR ELF Linker V8.40.1.212/W32 for ARM                  09/Jul/2025  18:51:30
 # Copyright 2007-2019 IAR Systems AB.
 #
 #    Output file  =
@@ -8,14 +8,19 @@
 #    Map file     =
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\List\desk.map
 #    Command line =
-#        -f C:\Temp\EW4F1A.tmp
+#        -f C:\Temp\EW1B00.tmp
 #        (D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\app_freertos.o
-#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\cmsis_os2.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\cmsis_os.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\croutine.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\event_groups.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\GFX_SSD1327.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\hal_callback.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\heap_4.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\i2c.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\list.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\main.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\microrl.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\OLED_SSD1327.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\port.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\portasm.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\queue.o
@@ -83,6 +88,9 @@
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\stream_buffer.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\system_stm32g4xx.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\tasks.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\terminal.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\terminal_usartbridge.o
+#        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\terminal_user.o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj\timers.o
 #        --no_out_extension -o
 #        D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Exe\desk.out
@@ -98,11 +106,13 @@
 *** RUNTIME MODEL ATTRIBUTES
 ***
 
-CppFlavor        = *
-__CPP_Exceptions = Disabled
-__CPP_Language   = C++14
-__SystemLibrary  = DLib
-__dlib_version   = 6
+CppFlavor                     = *
+__CPP_Exceptions              = Disabled
+__CPP_Language                = C++14
+__Heap_Handler                = Basic
+__SystemLibrary               = DLib
+__dlib_dynamic_initialization = normal
+__dlib_version                = 6
 
 
 *******************************************************************************
@@ -127,203 +137,266 @@ define block HEAP with size = 512, alignment = 8 { };
           rw, block CSTACK, block HEAP };
 initialize by copy { rw };
 
-  Section            Kind         Address    Size  Object
-  -------            ----         -------    ----  ------
-"A0":                                       0x1d8
-  .intvec            ro code   0x800'0000   0x1d8  startup_stm32g431xx.o [1]
-                             - 0x800'01d8   0x1d8
-
-"P1":                                      0x3178
-  .text              ro code   0x800'01d8   0xa64  tasks.o [1]
-  .text              ro code   0x800'0c3c   0x288  heap_4.o [1]
-  .text              ro code   0x800'0ec4    0x66  ABImemset.o [4]
-  .text              ro code   0x800'0f2a    0x9a  list.o [1]
-  .text              ro code   0x800'0fc4   0x25c  port.o [1]
-  .text              ro code   0x800'1220   0x1c0  cmsis_os2.o [1]
-  .text              ro code   0x800'13e0   0x4d4  timers.o [1]
-  CODE               ro code   0x800'18b4    0xb0  portasm.o [1]
-  .text              ro code   0x800'1964    0x18  cmsis_os2.o [1]
-  .text              ro code   0x800'197c   0x774  queue.o [1]
-  .text              ro code   0x800'20f0    0xa6  ABImemcpy.o [4]
-  .text              ro code   0x800'2196    0x3a  zero_init3.o [4]
-  .text              ro code   0x800'21d0   0x7d8  stm32g4xx_hal_rcc.o [1]
-  .text              ro code   0x800'29a8     0xc  stm32g4xx_hal.o [1]
-  .text              ro code   0x800'29b4    0x60  stm32g4xx_hal.o [1]
-  .text              ro code   0x800'2a14   0x124  stm32g4xx_hal_cortex.o [1]
-  .text              ro code   0x800'2b38   0x22c  stm32g4xx_hal_gpio.o [1]
-  .text              ro code   0x800'2d64   0x170  main.o [1]
-  .text              ro code   0x800'2ed4    0x24  stm32g4xx_hal.o [1]
-  .text              ro code   0x800'2ef8    0x14  memset.o [4]
-  .text              ro code   0x800'2f0c   0x11c  stm32g4xx_hal_pwr_ex.o [1]
-  .text              ro code   0x800'3028    0x10  stm32g4xx_hal_pwr.o [1]
-  .text              ro code   0x800'3038    0x44  stm32g4xx_hal_msp.o [1]
-  .text              ro code   0x800'307c    0x2e  copy_init3.o [4]
-  .rodata            const     0x800'30aa     0x1  unwind_debug.o [5]
-  .text              ro code   0x800'30ac    0x28  data_init.o [4]
-  .rodata            const     0x800'30d4    0x24  main.o [1]
-  .text              ro code   0x800'30f8    0x22  stm32g4xx_it.o [1]
-  .text              ro code   0x800'311c    0x18  stm32g4xx_hal.o [1]
-  .text              ro code   0x800'3134    0x22  fpinit_M.o [3]
-  .iar.init_table    const     0x800'3158    0x24  - Linker created -
-  .text              ro code   0x800'317c    0x1e  cmain.o [4]
-  .text              ro code   0x800'319a     0x4  low_level_init.o [2]
-  .text              ro code   0x800'319e     0x4  exit.o [2]
-  .text              ro code   0x800'31a4     0xa  cexit.o [4]
-  .text              ro code   0x800'31b0    0x14  exit.o [5]
-  .rodata            const     0x800'31c4    0x10  system_stm32g4xx.o [1]
-  .text              ro code   0x800'31d4    0x10  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'31e4    0x10  system_stm32g4xx.o [1]
-  Initializer bytes  const     0x800'31f4    0x10  <for P2-1>
-  .rodata            const     0x800'3204     0xc  main.o [1]
-  .text              ro code   0x800'3210     0xc  cstartup_M.o [4]
-  .rodata            const     0x800'321c     0x8  tasks.o [1]
-  .rodata            const     0x800'3224     0x8  timers.o [1]
-  .rodata            const     0x800'322c     0x8  timers.o [1]
-  .rodata            const     0x800'3234     0x4  heap_4.o [1]
-  .rodata            const     0x800'3238     0x4  port.o [1]
-  .text              ro code   0x800'323c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3240     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3244     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3248     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'324c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3250     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3254     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3258     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'325c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3260     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3264     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3268     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'326c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3270     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3274     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3278     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'327c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3280     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3284     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3288     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'328c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3290     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3294     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3298     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'329c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32a0     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32a4     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32a8     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32ac     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32b0     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32b4     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32b8     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32bc     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32c0     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32c4     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32c8     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32cc     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32d0     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32d4     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32d8     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32dc     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32e0     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32e4     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32e8     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32ec     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32f0     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32f4     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32f8     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'32fc     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3300     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3304     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3308     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'330c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3310     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3314     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3318     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'331c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3320     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3324     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3328     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'332c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3330     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3334     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3338     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'333c     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3340     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3344     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'3348     0x4  startup_stm32g431xx.o [1]
-  .text              ro code   0x800'334c     0x4  startup_stm32g431xx.o [1]
-  .rodata            const     0x800'3350     0x0  zero_init3.o [4]
-  .rodata            const     0x800'3350     0x0  copy_init3.o [4]
-                             - 0x800'3350  0x3178
-
-"P2", part 1 of 3:                           0x10
-  P2-1                        0x2000'0000    0x10  <Init block>
-    .data            inited   0x2000'0000     0x4  port.o [1]
-    .data            inited   0x2000'0004     0x4  stm32g4xx_hal.o [1]
-    .data            inited   0x2000'0008     0x4  stm32g4xx_hal.o [1]
-    .data            inited   0x2000'000c     0x4  system_stm32g4xx.o [1]
-                            - 0x2000'0010    0x10
-
-"P2", part 2 of 3:                         0x1958
-  .bss               zero     0x2000'0010   0xc00  heap_4.o [1]
-  .bss               zero     0x2000'0c10   0x460  tasks.o [1]
-  .bss               zero     0x2000'1070   0x400  cmsis_os2.o [1]
-  .bss               zero     0x2000'1470   0x200  cmsis_os2.o [1]
-  .bss               zero     0x2000'1670    0xa0  timers.o [1]
-  .bss               zero     0x2000'1710    0x5c  cmsis_os2.o [1]
-  .bss               zero     0x2000'176c    0x5c  cmsis_os2.o [1]
-  .bss               zero     0x2000'17c8    0x50  timers.o [1]
-  .bss               zero     0x2000'1818    0x40  queue.o [1]
-  .bss               zero     0x2000'1858    0x14  tasks.o [1]
-  .bss               zero     0x2000'186c    0x14  tasks.o [1]
-  .bss               zero     0x2000'1880    0x14  tasks.o [1]
-  .bss               zero     0x2000'1894    0x14  tasks.o [1]
-  .bss               zero     0x2000'18a8    0x14  tasks.o [1]
-  .bss               zero     0x2000'18bc    0x14  timers.o [1]
-  .bss               zero     0x2000'18d0    0x14  timers.o [1]
-  .bss               zero     0x2000'18e4     0x8  heap_4.o [1]
-  .bss               zero     0x2000'18ec     0x4  cmsis_os2.o [1]
-  .bss               zero     0x2000'18f0     0x4  heap_4.o [1]
-  .bss               zero     0x2000'18f4     0x4  heap_4.o [1]
-  .bss               zero     0x2000'18f8     0x4  heap_4.o [1]
-  .bss               zero     0x2000'18fc     0x4  heap_4.o [1]
-  .bss               zero     0x2000'1900     0x4  heap_4.o [1]
-  .bss               zero     0x2000'1904     0x4  heap_4.o [1]
-  .bss               zero     0x2000'1908     0x4  main.o [1]
-  .bss               zero     0x2000'190c     0x4  port.o [1]
-  .bss               zero     0x2000'1910     0x4  stm32g4xx_hal.o [1]
-  .bss               zero     0x2000'1914     0x4  tasks.o [1]
-  .bss               zero     0x2000'1918     0x4  tasks.o [1]
-  .bss               zero     0x2000'191c     0x4  tasks.o [1]
-  .bss               zero     0x2000'1920     0x4  tasks.o [1]
-  .bss               zero     0x2000'1924     0x4  tasks.o [1]
-  .bss               zero     0x2000'1928     0x4  tasks.o [1]
-  .bss               zero     0x2000'192c     0x4  tasks.o [1]
-  .bss               zero     0x2000'1930     0x4  tasks.o [1]
-  .bss               zero     0x2000'1934     0x4  tasks.o [1]
-  .bss               zero     0x2000'1938     0x4  tasks.o [1]
-  .bss               zero     0x2000'193c     0x4  tasks.o [1]
-  .bss               zero     0x2000'1940     0x4  tasks.o [1]
-  .bss               zero     0x2000'1944     0x4  tasks.o [1]
-  .bss               zero     0x2000'1948     0x4  tasks.o [1]
-  .bss               zero     0x2000'194c     0x4  tasks.o [1]
-  .bss               zero     0x2000'1950     0x4  timers.o [1]
-  .bss               zero     0x2000'1954     0x4  timers.o [1]
-  .bss               zero     0x2000'1958     0x4  timers.o [1]
-  .bss               zero     0x2000'195c     0x4  timers.o [1]
-  .bss               zero     0x2000'1960     0x4  timers.o [1]
-  .bss               zero     0x2000'1964     0x1  port.o [1]
-                            - 0x2000'1965  0x1955
-
-"P2", part 3 of 3:                          0x400
-  CSTACK                      0x2000'1968   0x400  <Block>
-    CSTACK           uninit   0x2000'1968   0x400  <Block tail>
-                            - 0x2000'1d68   0x400
+  Section                Kind         Address    Size  Object
+  -------                ----         -------    ----  ------
+"A0":                                           0x1d8
+  .intvec                ro code   0x800'0000   0x1d8  startup_stm32g431xx.o [1]
+                                 - 0x800'01d8   0x1d8
+
+"P1":                                          0x5ce8
+  .text                  ro code   0x800'01d8  0x1262  stm32g4xx_hal_uart.o [1]
+  .text                  ro code   0x800'143a    0x3a  zero_init3.o [5]
+  .text                  ro code   0x800'1474   0x10c  stm32g4xx_hal_dma.o [1]
+  .text                  ro code   0x800'1580     0x2  stm32g4xx_hal_uart.o [1]
+  .text                  ro code   0x800'1582     0x2  stm32g4xx_hal_uart.o [1]
+  .text                  ro code   0x800'1584     0x2  stm32g4xx_hal_uart_ex.o [1]
+  .text                  ro code   0x800'1586     0x2  stm32g4xx_hal_uart_ex.o [1]
+  .text                  ro code   0x800'1588     0x2  stm32g4xx_hal_uart_ex.o [1]
+  .text                  ro code   0x800'158a    0x2e  copy_init3.o [5]
+  .text                  ro code   0x800'15b8   0x814  stm32g4xx_hal_rcc.o [1]
+  .text                  ro code   0x800'1dcc   0x230  I64DivMod.o [5]
+  .text                  ro code   0x800'1ffc     0xc  stm32g4xx_hal.o [1]
+  .text                  ro code   0x800'2008     0x2  stm32g4xx_hal_uart.o [1]
+  .rodata                const     0x800'200a     0x1  unwind_debug.o [6]
+  .text                  ro code   0x800'200c    0x18  hal_callback.o [1]
+  .text                  ro code   0x800'2024    0x60  stm32g4xx_hal.o [1]
+  .text                  ro code   0x800'2084     0x2  I64DivZer.o [5]
+  .text                  ro code   0x800'2088   0x1c0  terminal_usartbridge.o [1]
+  .text                  ro code   0x800'2248   0x154  stm32g4xx_hal_cortex.o [1]
+  .text                  ro code   0x800'239c   0x204  terminal.o [1]
+  .text                  ro code   0x800'25a0    0x36  strlen.o [5]
+  .text                  ro code   0x800'25d8   0x2f8  terminal_user.o [1]
+  .text                  ro code   0x800'28d0   0x22c  stm32g4xx_hal_gpio.o [1]
+  .text                  ro code   0x800'2afc    0x66  ABImemset.o [5]
+  .text                  ro code   0x800'2b64   0x964  microrl.o [1]
+  .text                  ro code   0x800'34c8   0x1ac  cmsis_os.o [1]
+  .text                  ro code   0x800'3674    0xa6  ABImemcpy.o [5]
+  .text                  ro code   0x800'371c    0x12  strcmp.o [5]
+  .text                  ro code   0x800'3730    0x18  strcpy.o [5]
+  .text                  ro code   0x800'3748    0x96  ABImemmove.o [5]
+  .text                  ro code   0x800'37e0   0xa18  tasks.o [1]
+  .text                  ro code   0x800'41f8   0x7b0  queue.o [1]
+  .text                  ro code   0x800'49a8   0x288  heap_4.o [1]
+  .text                  ro code   0x800'4c30    0x9a  list.o [1]
+  .text                  ro code   0x800'4ccc   0x25c  port.o [1]
+  .text                  ro code   0x800'4f28   0x4a4  timers.o [1]
+  CODE                   ro code   0x800'53cc    0xb0  portasm.o [1]
+  .text                  ro code   0x800'547c   0x194  main.o [1]
+  .text                  ro code   0x800'5610    0x24  stm32g4xx_hal.o [1]
+  .text                  ro code   0x800'5634    0x14  memset.o [5]
+  .text                  ro code   0x800'5648   0x11c  stm32g4xx_hal_pwr_ex.o [1]
+  .text                  ro code   0x800'5764    0x10  stm32g4xx_hal_pwr.o [1]
+  .text                  ro code   0x800'5774    0x44  stm32g4xx_hal_msp.o [1]
+  .rodata                const     0x800'57b8    0x40  terminal_user.o [1]
+  .rodata                const     0x800'57f8    0x30  terminal_user.o [1]
+  .rodata                const     0x800'5828    0x30  terminal_user.o [1]
+  .rodata                const     0x800'5858    0x2c  terminal_user.o [1]
+  .rodata                const     0x800'5884    0x2c  terminal_user.o [1]
+  .rodata                const     0x800'58b0    0x28  terminal_user.o [1]
+  .rodata                const     0x800'58d8    0x28  terminal_user.o [1]
+  .rodata                const     0x800'5900    0x28  terminal_user.o [1]
+  .rodata                const     0x800'5928    0x28  terminal_user.o [1]
+  .text                  ro code   0x800'5950    0x28  data_init.o [5]
+  .rodata                const     0x800'5978    0x24  terminal_user.o [1]
+  .rodata                const     0x800'599c    0x24  terminal_user.o [1]
+  .rodata                const     0x800'59c0    0x24  terminal_user.o [1]
+  .rodata                const     0x800'59e4    0x24  terminal_user.o [1]
+  .rodata                const     0x800'5a08    0x24  terminal_user.o [1]
+  .text                  ro code   0x800'5a2c    0x22  stm32g4xx_it.o [1]
+  .text                  ro code   0x800'5a50    0x18  stm32g4xx_hal.o [1]
+  .text                  ro code   0x800'5a68    0x22  fpinit_M.o [4]
+  .iar.init_table        const     0x800'5a8c    0x28  - Linker created -
+  .rodata                const     0x800'5ab4    0x20  terminal_user.o [1]
+  .rodata                const     0x800'5ad4    0x20  terminal_user.o [1]
+  .rodata                const     0x800'5af4    0x20  terminal_user.o [1]
+  .rodata                const     0x800'5b14    0x20  terminal_user.o [1]
+  .rodata                const     0x800'5b34    0x20  terminal_user.o [1]
+  .rodata                const     0x800'5b54    0x20  terminal_user.o [1]
+  .text                  ro code   0x800'5b74    0x20  cmain_call_ctors.o [5]
+  .text                  ro code   0x800'5b94    0x18  cppinit.o [2]
+  .text                  ro code   0x800'5bac    0x1e  cmain.o [5]
+  .text                  ro code   0x800'5bca     0x4  low_level_init.o [2]
+  .text                  ro code   0x800'5bce     0x4  exit.o [2]
+  .text                  ro code   0x800'5bd4     0xa  cexit.o [5]
+  .text                  ro code   0x800'5be0    0x14  exit.o [6]
+  .rodata                const     0x800'5bf4    0x1c  terminal.o [1]
+  .rodata                const     0x800'5c10    0x1c  terminal_user.o [1]
+  .rodata                const     0x800'5c2c    0x1c  terminal_user.o [1]
+  .rodata                const     0x800'5c48    0x18  microrl.o [1]
+  .rodata                const     0x800'5c60    0x18  stm32g4xx_hal_uart.o [1]
+  .rodata                const     0x800'5c78    0x18  terminal_user.o [1]
+  .rodata                const     0x800'5c90    0x18  terminal_user.o [1]
+  .rodata                const     0x800'5ca8    0x14  main.o [1]
+  .rodata                const     0x800'5cbc    0x14  microrl.o [1]
+  .rodata                const     0x800'5cd0    0x14  terminal_user.o [1]
+  Initializer bytes      const     0x800'5ce4    0x14  <for P2-1>
+  .rodata                const     0x800'5cf8    0x10  system_stm32g4xx.o [1]
+  .text                  ro code   0x800'5d08    0x10  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5d18    0x10  system_stm32g4xx.o [1]
+  .rodata                const     0x800'5d28     0xc  terminal_user.o [1]
+  .text                  ro code   0x800'5d34     0xc  cstartup_M.o [5]
+  .rodata                const     0x800'5d40     0x8  main.o [1]
+  .rodata                const     0x800'5d48     0x8  microrl.o [1]
+  .rodata                const     0x800'5d50     0x8  system_stm32g4xx.o [1]
+  .rodata                const     0x800'5d58     0x8  tasks.o [1]
+  .rodata                const     0x800'5d60     0x8  terminal.o [1]
+  .rodata                const     0x800'5d68     0x8  terminal_user.o [1]
+  .rodata                const     0x800'5d70     0x8  terminal_user.o [1]
+  .rodata                const     0x800'5d78     0x8  terminal_user.o [1]
+  .rodata                const     0x800'5d80     0x8  terminal_user.o [1]
+  .rodata                const     0x800'5d88     0x8  terminal_user.o [1]
+  .rodata                const     0x800'5d90     0x8  timers.o [1]
+  .rodata                const     0x800'5d98     0x8  timers.o [1]
+  SHT$$PREINIT_ARRAY               0x800'5da0     0x0  <Block>
+  SHT$$INIT_ARRAY                  0x800'5da0     0x8  <Block>
+    .init_array          const     0x800'5da0     0x4  terminal_usartbridge.o [1]
+    .init_array          const     0x800'5da4     0x4  terminal_user.o [1]
+  __iar_tls$$INIT_ARRAY            0x800'5da8     0x0  <Block>
+  .rodata                const     0x800'5da8     0x4  heap_4.o [1]
+  .rodata                const     0x800'5dac     0x4  port.o [1]
+  .text                  ro code   0x800'5db0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5db4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5db8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dbc     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dc0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dc4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dc8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dcc     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dd0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dd4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dd8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5ddc     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5de0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5de4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5de8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dec     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5df0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5df4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5df8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5dfc     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e00     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e04     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e08     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e0c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e10     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e14     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e18     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e1c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e20     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e24     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e28     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e2c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e30     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e34     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e38     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e3c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e40     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e44     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e48     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e4c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e50     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e54     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e58     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e5c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e60     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e64     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e68     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e6c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e70     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e74     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e78     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e7c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e80     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e84     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e88     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e8c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e90     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e94     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e98     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5e9c     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5ea0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5ea4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5ea8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5eac     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5eb0     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5eb4     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5eb8     0x4  startup_stm32g431xx.o [1]
+  .text                  ro code   0x800'5ebc     0x4  startup_stm32g431xx.o [1]
+  .rodata                const     0x800'5ec0     0x0  zero_init3.o [5]
+  .rodata                const     0x800'5ec0     0x0  copy_init3.o [5]
+                                 - 0x800'5ec0  0x5ce8
+
+"P2", part 1 of 3:                               0x14
+  P2-1                            0x2000'0000    0x14  <Init block>
+    .data                inited   0x2000'0000     0x4  microrl.o [1]
+    .data                inited   0x2000'0004     0x4  port.o [1]
+    .data                inited   0x2000'0008     0x4  stm32g4xx_hal.o [1]
+    .data                inited   0x2000'000c     0x4  stm32g4xx_hal.o [1]
+    .data                inited   0x2000'0010     0x4  system_stm32g4xx.o [1]
+                                - 0x2000'0014    0x14
+
+"P2", part 2 of 3:                             0x5c00
+  .bss                   zero     0x2000'0014  0x5800  heap_4.o [1]
+  .bss                   zero     0x2000'5814    0xf0  tasks.o [1]
+  .bss                   zero     0x2000'5904    0xec  terminal_user.o [1]
+  .bss                   zero     0x2000'59f0    0xa4  terminal_usartbridge.o [1]
+  .bss                   zero     0x2000'5a94    0x40  queue.o [1]
+  .bss                   zero     0x2000'5ad4    0x28  terminal.o [1]
+  .bss                   zero     0x2000'5afc    0x14  tasks.o [1]
+  .bss                   zero     0x2000'5b10    0x14  tasks.o [1]
+  .bss                   zero     0x2000'5b24    0x14  tasks.o [1]
+  .bss                   zero     0x2000'5b38    0x14  tasks.o [1]
+  .bss                   zero     0x2000'5b4c    0x14  tasks.o [1]
+  .bss                   zero     0x2000'5b60    0x14  timers.o [1]
+  .bss                   zero     0x2000'5b74    0x14  timers.o [1]
+  .bss                   zero     0x2000'5b88     0x8  heap_4.o [1]
+  .bss                   zero     0x2000'5b90     0x4  heap_4.o [1]
+  .bss                   zero     0x2000'5b94     0x4  heap_4.o [1]
+  .bss                   zero     0x2000'5b98     0x4  heap_4.o [1]
+  .bss                   zero     0x2000'5b9c     0x4  heap_4.o [1]
+  .bss                   zero     0x2000'5ba0     0x4  heap_4.o [1]
+  .bss                   zero     0x2000'5ba4     0x4  heap_4.o [1]
+  .bss                   zero     0x2000'5ba8     0x4  main.o [1]
+  .bss                   zero     0x2000'5bac     0x4  port.o [1]
+  .bss                   zero     0x2000'5bb0     0x4  stm32g4xx_hal.o [1]
+  .bss                   zero     0x2000'5bb4     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bb8     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bbc     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bc0     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bc4     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bc8     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bcc     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bd0     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bd4     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bd8     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bdc     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5be0     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5be4     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5be8     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bec     0x4  tasks.o [1]
+  .bss                   zero     0x2000'5bf0     0x4  terminal.o [1]
+  .bss                   zero     0x2000'5bf4     0x4  terminal_user.o [1]
+  .bss                   zero     0x2000'5bf8     0x4  terminal_user.o [1]
+  .bss                   zero     0x2000'5bfc     0x4  timers.o [1]
+  .bss                   zero     0x2000'5c00     0x4  timers.o [1]
+  .bss                   zero     0x2000'5c04     0x4  timers.o [1]
+  .bss                   zero     0x2000'5c08     0x4  timers.o [1]
+  .bss                   zero     0x2000'5c0c     0x4  timers.o [1]
+  .bss                   zero     0x2000'5c10     0x1  port.o [1]
+                                - 0x2000'5c11  0x5bfd
+
+"P2", part 3 of 3:                              0x400
+  CSTACK                          0x2000'5c18   0x400  <Block>
+    CSTACK               uninit   0x2000'5c18   0x400  <Block tail>
+                                - 0x2000'6018   0x400
 
 Unused ranges:
 
          From           To      Size
          ----           --      ----
-   0x800'3350   0x801'ffff  0x1'ccb0
-  0x2000'1d68  0x2000'7fff    0x6298
+   0x800'5ec0   0x801'ffff  0x1'a140
+  0x2000'5c14  0x2000'5c17       0x4
+  0x2000'6018  0x2000'7fff    0x1fe8
 
 
 *******************************************************************************
@@ -333,14 +406,16 @@ Unused ranges:
           Address      Size
           -------      ----
 Zero (__iar_zero_init3)
-    1 destination range, total size 0x1955:
-          0x2000'0010  0x1955
+    1 destination range, total size 0x5bfd:
+          0x2000'0014  0x5bfd
 
 Copy (__iar_copy_init3)
-    1 source range, total size 0x10:
-           0x800'31f4    0x10
-    1 destination range, total size 0x10:
-          0x2000'0000    0x10
+    1 source range, total size 0x14:
+           0x800'5ce4    0x14
+    1 destination range, total size 0x14:
+          0x2000'0000    0x14
+
+Extra (__iar_cstart_call_ctors)
 
 
 
@@ -348,329 +423,490 @@ Copy (__iar_copy_init3)
 *** MODULE SUMMARY
 ***
 
-    Module                  ro code  ro data  rw data
-    ------                  -------  -------  -------
+    Module                   ro code  ro data  rw data
+    ------                   -------  -------  -------
 command line/config:
-    -------------------------------------------------
+    --------------------------------------------------
     Total:
 
 D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj: [1]
-    cmsis_os2.o                 472             1'724
-    heap_4.o                    648        4    3'104
-    list.o                      154
-    main.o                      368       48        4
-    port.o                      604        8        9
-    portasm.o                   176
-    queue.o                   1'908                64
-    startup_stm32g431xx.o       764
-    stm32g4xx_hal.o             168        8       12
-    stm32g4xx_hal_cortex.o      292
-    stm32g4xx_hal_gpio.o        556
-    stm32g4xx_hal_msp.o          68
-    stm32g4xx_hal_pwr.o          16
-    stm32g4xx_hal_pwr_ex.o      284
-    stm32g4xx_hal_rcc.o       2'008
-    stm32g4xx_it.o               34
-    system_stm32g4xx.o           16       20        4
-    tasks.o                   2'660        8    1'280
-    timers.o                  1'236       16      300
-    -------------------------------------------------
-    Total:                   12'432      112    6'501
+    cmsis_os.o                   428
+    hal_callback.o                24
+    heap_4.o                     648        4   22'560
+    list.o                       154
+    main.o                       404       28        4
+    microrl.o                  2'404       56        4
+    port.o                       604        8        9
+    portasm.o                    176
+    queue.o                    1'968                64
+    startup_stm32g431xx.o        760
+    stm32g4xx_hal.o              168        8       12
+    stm32g4xx_hal_cortex.o       340
+    stm32g4xx_hal_dma.o          268
+    stm32g4xx_hal_gpio.o         556
+    stm32g4xx_hal_msp.o           68
+    stm32g4xx_hal_pwr.o           16
+    stm32g4xx_hal_pwr_ex.o       284
+    stm32g4xx_hal_rcc.o        2'068
+    stm32g4xx_hal_uart.o       4'712       24
+    stm32g4xx_hal_uart_ex.o        6
+    stm32g4xx_it.o                34
+    system_stm32g4xx.o            16       28        4
+    tasks.o                    2'584        8      400
+    terminal.o                   516       36       44
+    terminal_usartbridge.o       448        4      164
+    terminal_user.o              760      960      244
+    timers.o                   1'188       16       60
+    --------------------------------------------------
+    Total:                    21'602    1'180   23'569
 
 dl7M_tlf.a: [2]
-    exit.o                        4
-    low_level_init.o              4
-    -------------------------------------------------
-    Total:                        8
-
-m7M_tls.a: [3]
-    fpinit_M.o                   34
-    -------------------------------------------------
-    Total:                       34
-
-rt7M_tl.a: [4]
-    ABImemcpy.o                 166
-    ABImemset.o                 102
-    cexit.o                      10
-    cmain.o                      30
-    copy_init3.o                 46
-    cstartup_M.o                 12
-    data_init.o                  40
-    memset.o                     20
-    zero_init3.o                 58
-    -------------------------------------------------
-    Total:                      484
-
-shb_l.a: [5]
-    exit.o                       20
-    unwind_debug.o                         1
-    -------------------------------------------------
-    Total:                       20        1
-
-    Gaps                          7        2
-    Linker created                        36    1'024
------------------------------------------------------
-    Grand Total:             12'985      151    7'525
+    cppinit.o                     24
+    exit.o                         4
+    low_level_init.o               4
+    --------------------------------------------------
+    Total:                        32
+
+dlpp7M_tl_fc.a: [3]
+    --------------------------------------------------
+    Total:
+
+m7M_tls.a: [4]
+    fpinit_M.o                    34
+    --------------------------------------------------
+    Total:                        34
+
+rt7M_tl.a: [5]
+    ABImemcpy.o                  166
+    ABImemmove.o                 150
+    ABImemset.o                  102
+    I64DivMod.o                  560
+    I64DivZer.o                    2
+    cexit.o                       10
+    cmain.o                       30
+    cmain_call_ctors.o            32
+    copy_init3.o                  46
+    cstartup_M.o                  12
+    data_init.o                   40
+    memset.o                      20
+    strcmp.o                      18
+    strcpy.o                      24
+    strlen.o                      54
+    zero_init3.o                  58
+    --------------------------------------------------
+    Total:                     1'324
+
+shb_l.a: [6]
+    exit.o                        20
+    unwind_debug.o                          1
+    --------------------------------------------------
+    Total:                        20        1
+
+    Gaps                          21        2
+    Linker created                         40    1'024
+------------------------------------------------------
+    Grand Total:              23'033    1'223   24'593
 
 
 *******************************************************************************
 *** ENTRY LIST
 ***
 
-Entry                       Address   Size  Type      Object
------                       -------   ----  ----      ------
-.iar.init_table$$Base    0x800'3158          --   Gb  - Linker created -
-.iar.init_table$$Limit   0x800'317c          --   Gb  - Linker created -
-?main                    0x800'317d         Code  Gb  cmain.o [4]
-AHBPrescTable            0x800'31c4   0x10  Data  Gb  system_stm32g4xx.o [1]
-BusFault_Handler         0x800'30ff    0x2  Code  Gb  stm32g4xx_it.o [1]
-CSTACK$$Base            0x2000'1968          --   Gb  - Linker created -
-CSTACK$$Limit           0x2000'1d68          --   Gb  - Linker created -
-DebugMon_Handler         0x800'3103    0x2  Code  Gb  stm32g4xx_it.o [1]
-Error_Handler()          0x800'2ed1    0x4  Code  Gb  main.o [1]
-HAL_GPIO_Init            0x800'2b39  0x1cc  Code  Gb  stm32g4xx_hal_gpio.o [1]
-HAL_GPIO_TogglePin       0x800'2d1d   0x1a  Code  Gb  stm32g4xx_hal_gpio.o [1]
-HAL_GPIO_WritePin        0x800'2d05   0x18  Code  Gb  stm32g4xx_hal_gpio.o [1]
-HAL_GetTick              0x800'29a9    0xc  Code  Wk  stm32g4xx_hal.o [1]
-HAL_IncTick              0x800'311d   0x18  Code  Wk  stm32g4xx_hal.o [1]
-HAL_Init                 0x800'2ed5   0x24  Code  Gb  stm32g4xx_hal.o [1]
-HAL_InitTick             0x800'29b5   0x60  Code  Wk  stm32g4xx_hal.o [1]
-HAL_MspInit              0x800'3039   0x3c  Code  Gb  stm32g4xx_hal_msp.o [1]
-HAL_NVIC_SetPriority     0x800'2aed   0x24  Code  Gb  stm32g4xx_hal_cortex.o [1]
+Entry                       Address    Size  Type      Object
+-----                       -------    ----  ----      ------
+.iar.init_table$$Base    0x800'5a8c           --   Gb  - Linker created -
+.iar.init_table$$Limit   0x800'5ab4           --   Gb  - Linker created -
+?main                    0x800'5bad          Code  Gb  cmain.o [5]
+AHBPrescTable            0x800'5cf8    0x10  Data  Gb  system_stm32g4xx.o [1]
+APBPrescTable            0x800'5d50     0x8  Data  Gb  system_stm32g4xx.o [1]
+BusFault_Handler         0x800'5a33     0x2  Code  Gb  stm32g4xx_it.o [1]
+CSTACK$$Base            0x2000'5c18           --   Gb  - Linker created -
+CSTACK$$Limit           0x2000'6018           --   Gb  - Linker created -
+DebugMon_Handler         0x800'5a37     0x2  Code  Gb  stm32g4xx_it.o [1]
+Error_Handler            0x800'560d     0x4  Code  Gb  main.o [1]
+HAL_DMA_Abort            0x800'1475    0x78  Code  Gb  stm32g4xx_hal_dma.o [1]
+HAL_DMA_Abort_IT         0x800'14ed    0x94  Code  Gb  stm32g4xx_hal_dma.o [1]
+HAL_GPIO_Init            0x800'28d1   0x1cc  Code  Gb  stm32g4xx_hal_gpio.o [1]
+HAL_GPIO_TogglePin       0x800'2ab5    0x1a  Code  Gb  stm32g4xx_hal_gpio.o [1]
+HAL_GPIO_WritePin        0x800'2a9d    0x18  Code  Gb  stm32g4xx_hal_gpio.o [1]
+HAL_GetTick              0x800'1ffd     0xc  Code  Wk  stm32g4xx_hal.o [1]
+HAL_IncTick              0x800'5a51    0x18  Code  Wk  stm32g4xx_hal.o [1]
+HAL_Init                 0x800'5611    0x24  Code  Gb  stm32g4xx_hal.o [1]
+HAL_InitTick             0x800'2025    0x60  Code  Wk  stm32g4xx_hal.o [1]
+HAL_MspInit              0x800'5775    0x3c  Code  Gb  stm32g4xx_hal_msp.o [1]
+HAL_NVIC_EnableIRQ       0x800'2363     0xe  Code  Gb  stm32g4xx_hal_cortex.o [1]
+HAL_NVIC_SetPriority     0x800'233f    0x24  Code  Gb  stm32g4xx_hal_cortex.o [1]
 HAL_NVIC_SetPriorityGrouping
-                         0x800'2ae1    0xc  Code  Gb  stm32g4xx_hal_cortex.o [1]
+                         0x800'2333     0xc  Code  Gb  stm32g4xx_hal_cortex.o [1]
 HAL_PWREx_ControlVoltageScaling
-                         0x800'2f0d   0xf4  Code  Gb  stm32g4xx_hal_pwr_ex.o [1]
+                         0x800'5649    0xf4  Code  Gb  stm32g4xx_hal_pwr_ex.o [1]
 HAL_PWREx_DisableUCPDDeadBattery
-                         0x800'3001    0xc  Code  Gb  stm32g4xx_hal_pwr_ex.o [1]
+                         0x800'573d     0xc  Code  Gb  stm32g4xx_hal_pwr_ex.o [1]
 HAL_PWR_EnableBkUpAccess
-                         0x800'3029    0xc  Code  Gb  stm32g4xx_hal_pwr.o [1]
-HAL_RCC_ClockConfig      0x800'26a9  0x1f4  Code  Gb  stm32g4xx_hal_rcc.o [1]
+                         0x800'5765     0xc  Code  Gb  stm32g4xx_hal_pwr.o [1]
+HAL_RCC_ClockConfig      0x800'1a91   0x1f4  Code  Gb  stm32g4xx_hal_rcc.o [1]
+HAL_RCC_GetHCLKFreq      0x800'1d01     0x6  Code  Gb  stm32g4xx_hal_rcc.o [1]
+HAL_RCC_GetPCLK1Freq     0x800'1d07    0x1a  Code  Gb  stm32g4xx_hal_rcc.o [1]
+HAL_RCC_GetPCLK2Freq     0x800'1d21    0x1a  Code  Gb  stm32g4xx_hal_rcc.o [1]
 HAL_RCC_GetSysClockFreq
-                         0x800'289d   0x7c  Code  Gb  stm32g4xx_hal_rcc.o [1]
-HAL_RCC_OscConfig        0x800'21d1  0x4d8  Code  Gb  stm32g4xx_hal_rcc.o [1]
-HAL_SYSTICK_Config       0x800'2b11    0xc  Code  Gb  stm32g4xx_hal_cortex.o [1]
-HardFault_Handler        0x800'30fb    0x2  Code  Gb  stm32g4xx_it.o [1]
-KernelState             0x2000'18ec    0x4  Data  Lc  cmsis_os2.o [1]
-MemManage_Handler        0x800'30fd    0x2  Code  Gb  stm32g4xx_it.o [1]
-NMI_Handler              0x800'30f9    0x2  Code  Gb  stm32g4xx_it.o [1]
-NVIC_EncodePriority      0x800'2a71   0x40  Code  Lc  stm32g4xx_hal_cortex.o [1]
-PendSV_Handler           0x800'18b5         Code  Gb  portasm.o [1]
+                         0x800'1c85    0x7c  Code  Gb  stm32g4xx_hal_rcc.o [1]
+HAL_RCC_OscConfig        0x800'15b9   0x4d8  Code  Gb  stm32g4xx_hal_rcc.o [1]
+HAL_SYSTICK_Config       0x800'2371     0xc  Code  Gb  stm32g4xx_hal_cortex.o [1]
+HAL_UARTEx_RxFifoFullCallback
+                         0x800'1589     0x2  Code  Wk  stm32g4xx_hal_uart_ex.o [1]
+HAL_UARTEx_TxFifoEmptyCallback
+                         0x800'1587     0x2  Code  Wk  stm32g4xx_hal_uart_ex.o [1]
+HAL_UARTEx_WakeupCallback
+                         0x800'1585     0x2  Code  Wk  stm32g4xx_hal_uart_ex.o [1]
+HAL_UART_IRQHandler      0x800'02b9   0x3a4  Code  Gb  stm32g4xx_hal_uart.o [1]
+HAL_UART_Init            0x800'01d9    0x7e  Code  Gb  stm32g4xx_hal_uart.o [1]
+HAL_UART_Receive_IT      0x800'0257    0x5e  Code  Gb  stm32g4xx_hal_uart.o [1]
+HAL_UART_RxCpltCallback
+                         0x800'200d    0x18  Code  Gb  hal_callback.o [1]
+HAL_UART_RxCpltCallbackTerminal()
+                         0x800'211d    0x20  Code  Gb  terminal_usartbridge.o [1]
+HardFault_Handler        0x800'5a2f     0x2  Code  Gb  stm32g4xx_it.o [1]
+MemManage_Handler        0x800'5a31     0x2  Code  Gb  stm32g4xx_it.o [1]
+NMI_Handler              0x800'5a2d     0x2  Code  Gb  stm32g4xx_it.o [1]
+NVIC_EncodePriority      0x800'22c3    0x40  Code  Lc  stm32g4xx_hal_cortex.o [1]
+PendSV_Handler           0x800'53cd          Code  Gb  portasm.o [1]
 RCC_GetSysClockFreqFromPLLSource
-                         0x800'2919   0x46  Code  Lc  stm32g4xx_hal_rcc.o [1]
-Region$$Table$$Base      0x800'3158          --   Gb  - Linker created -
-Region$$Table$$Limit     0x800'317c          --   Gb  - Linker created -
-SVC_Handler              0x800'190d         Code  Gb  portasm.o [1]
-SVC_Setup                0x800'1251    0xe  Code  Lc  cmsis_os2.o [1]
-StartDefaultTask(void *)
-                         0x800'2d91   0x16  Code  Gb  main.o [1]
-SysTick_Config           0x800'2ab1   0x30  Code  Lc  stm32g4xx_hal_cortex.o [1]
-SysTick_Handler          0x800'3105   0x14  Code  Gb  stm32g4xx_it.o [1]
-SystemClock_Config()     0x800'2e2b   0x90  Code  Gb  main.o [1]
-SystemCoreClock         0x2000'000c    0x4  Data  Gb  system_stm32g4xx.o [1]
-SystemInit               0x800'31e5    0xc  Code  Gb  system_stm32g4xx.o [1]
-USB_LP_IRQHandler        0x800'3119    0x2  Code  Gb  stm32g4xx_it.o [1]
-UsageFault_Handler       0x800'3101    0x2  Code  Gb  stm32g4xx_it.o [1]
+                         0x800'1d3b    0x46  Code  Lc  stm32g4xx_hal_rcc.o [1]
+Region$$Table$$Base      0x800'5a8c           --   Gb  - Linker created -
+Region$$Table$$Limit     0x800'5ab4           --   Gb  - Linker created -
+SHT$$INIT_ARRAY$$Base    0x800'5da0           --   Gb  - Linker created -
+SHT$$INIT_ARRAY$$Limit   0x800'5da8           --   Gb  - Linker created -
+SHT$$PREINIT_ARRAY$$Base
+                         0x800'5da0           --   Gb  - Linker created -
+SHT$$PREINIT_ARRAY$$Limit
+                         0x800'5da0           --   Gb  - Linker created -
+SVC_Handler              0x800'5425          Code  Gb  portasm.o [1]
+SbsTerminal::SbsTerminal()
+                         0x800'25fd    0x12  Code  Gb  terminal_user.o [1]
+SbsTerminal::clear(int, char const *const *)
+                         0x800'27bb    0x40  Code  Gb  terminal_user.o [1]
+SbsTerminal::configure()
+                         0x800'260f    0x42  Code  Gb  terminal_user.o [1]
+SbsTerminal::execute(int, char const *const *)
+                         0x800'2651    0x7e  Code  Gb  terminal_user.o [1]
+SbsTerminal::help(int, char const *const *)
+                         0x800'26d1    0xcc  Code  Gb  terminal_user.o [1]
+SbsTerminal::help_connection()
+                         0x800'279d     0x6  Code  Gb  terminal_user.o [1]
+SbsTerminal::put_byte(char)
+                         0x800'27fb    0x16  Code  Gb  terminal_user.o [1]
+SbsTerminal::sigint()    0x800'26cf     0x2  Code  Gb  terminal_user.o [1]
+SbsTerminal::version(int, char const *const *)
+                         0x800'27a3    0x18  Code  Gb  terminal_user.o [1]
+StartupTask(void const *)
+                         0x800'54ad    0x30  Code  Gb  main.o [1]
+SysTick_Config           0x800'2303    0x30  Code  Lc  stm32g4xx_hal_cortex.o [1]
+SysTick_Handler          0x800'5a39    0x14  Code  Gb  stm32g4xx_it.o [1]
+SystemClock_Config()     0x800'5561    0x90  Code  Gb  main.o [1]
+SystemCoreClock         0x2000'0010     0x4  Data  Gb  system_stm32g4xx.o [1]
+SystemInit               0x800'5d19     0xc  Code  Gb  system_stm32g4xx.o [1]
+Terminal::Terminal()     0x800'2401    0x42  Code  Gb  terminal.o [1]
+Terminal::Terminal() [subobject]
+                         0x800'239d     0xc  Code  Gb  terminal.o [1]
+Terminal::addPrint(void (*)(char const *))
+                         0x800'2547    0x16  Code  Gb  terminal.o [1]
+Terminal::clearScreen()
+                         0x800'255d    0x18  Code  Gb  terminal.o [1]
+Terminal::completion(int, char const *const *)
+                         0x800'2535    0x10  Code  Gb  terminal.o [1]
+Terminal::configure()    0x800'2443    0x6a  Code  Gb  terminal.o [1]
+Terminal::execute(int, char const *const *)
+                         0x800'252f     0x6  Code  Gb  terminal.o [1]
+Terminal::insert(int)    0x800'24ad    0x12  Code  Gb  terminal.o [1]
+Terminal::print(char const *)
+                         0x800'24bf    0x28  Code  Gb  terminal.o [1]
+Terminal::printeol()     0x800'2521     0xe  Code  Gb  terminal.o [1]
+Terminal::printl(char const *)
+                         0x800'24e7    0x18  Code  Gb  terminal.o [1]
+Terminal::printll(char const *)
+                         0x800'24ff    0x22  Code  Gb  terminal.o [1]
+Terminal::sigint()       0x800'2545     0x2  Code  Gb  terminal.o [1]
+UARTPrescTable           0x800'5c60    0x18  Data  Gb  stm32g4xx_hal_uart.o [1]
+UART_AdvFeatureConfig    0x800'09e9    0xda  Code  Gb  stm32g4xx_hal_uart.o [1]
+UART_CheckIdleState      0x800'0ac3    0xd6  Code  Gb  stm32g4xx_hal_uart.o [1]
+UART_DMAAbortOnError     0x800'0e15    0x14  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_EndRxTransfer       0x800'0d91    0x60  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_EndTransmit_IT      0x800'0e29    0x2c  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_RxISR_16BIT         0x800'0f4d    0xf0  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_RxISR_16BIT_FIFOEN
+                         0x800'1231   0x1f6  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_RxISR_8BIT          0x800'0e55    0xee  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_RxISR_8BIT_FIFOEN   0x800'103d   0x1f2  Code  Lc  stm32g4xx_hal_uart.o [1]
+UART_SetConfig           0x800'0661   0x37a  Code  Gb  stm32g4xx_hal_uart.o [1]
+UART_Start_Receive_IT    0x800'0c37   0x15a  Code  Gb  stm32g4xx_hal_uart.o [1]
+UART_WaitOnFlagUntilTimeout
+                         0x800'0b99    0x9e  Code  Gb  stm32g4xx_hal_uart.o [1]
+USART3_IRQHandler        0x800'2113     0xa  Code  Gb  terminal_usartbridge.o [1]
+USB_LP_IRQHandler        0x800'5a4d     0x2  Code  Gb  stm32g4xx_it.o [1]
+UsageFault_Handler       0x800'5a35     0x2  Code  Gb  stm32g4xx_it.o [1]
+UsartBridgeTerminal::InitUsart()
+                         0x800'216d    0xbc  Code  Gb  terminal_usartbridge.o [1]
+UsartBridgeTerminal::UsartBridgeTerminal()
+                         0x800'20a1    0x14  Code  Gb  terminal_usartbridge.o [1]
+UsartBridgeTerminal::configure()
+                         0x800'20b5    0x28  Code  Gb  terminal_usartbridge.o [1]
+UsartBridgeTerminal::print(char const *)
+                         0x800'20dd    0x36  Code  Gb  terminal_usartbridge.o [1]
+UsartBridgeTerminal::recvByte()
+                         0x800'213d    0x12  Code  Gb  terminal_usartbridge.o [1]
+UsartBridgeTerminal::sendByte(unsigned char)
+                         0x800'214f    0x1e  Code  Gb  terminal_usartbridge.o [1]
+Virtual function table for SbsTerminal
+                         0x800'5c10    0x1c  Data  Gb  terminal_user.o [1]
+Virtual function table for Terminal
+                         0x800'5bf4    0x1c  Data  Gb  terminal.o [1]
 [local to main_cpp]::MX_GPIO_Init()
-                         0x800'2da7   0x84  Code  Lc  main.o [1]
+                         0x800'54dd    0x84  Code  Lc  main.o [1]
+[local to terminal_user_cpp]::__NVIC_SystemReset()
+                         0x800'25e3    0x1a  Code  Lc  terminal_user.o [1]
+__NVIC_EnableIRQ         0x800'2279    0x1e  Code  Lc  stm32g4xx_hal_cortex.o [1]
 __NVIC_GetPriorityGrouping
-                         0x800'2a37    0xc  Code  Lc  stm32g4xx_hal_cortex.o [1]
-__NVIC_SetPriority       0x800'1221   0x30  Code  Lc  cmsis_os2.o [1]
-__NVIC_SetPriority       0x800'2a45   0x2c  Code  Lc  stm32g4xx_hal_cortex.o [1]
+                         0x800'226b     0xc  Code  Lc  stm32g4xx_hal_cortex.o [1]
+__NVIC_SetPriority       0x800'2297    0x2c  Code  Lc  stm32g4xx_hal_cortex.o [1]
 __NVIC_SetPriorityGrouping
-                         0x800'2a15   0x22  Code  Lc  stm32g4xx_hal_cortex.o [1]
-__aeabi_memcpy           0x800'20f1         Code  Gb  ABImemcpy.o [4]
-__aeabi_memcpy4          0x800'2111         Code  Gb  ABImemcpy.o [4]
-__aeabi_memcpy8          0x800'2111         Code  Gb  ABImemcpy.o [4]
-__aeabi_memset           0x800'0ec5         Code  Gb  ABImemset.o [4]
-__cmain                  0x800'317d         Code  Gb  cmain.o [4]
-__exit                   0x800'31b1   0x14  Code  Gb  exit.o [5]
-__iar_Memset             0x800'0ec5         Code  Gb  ABImemset.o [4]
-__iar_Memset_word        0x800'0ecd         Code  Gb  ABImemset.o [4]
-__iar_copy_init3         0x800'307d   0x2e  Code  Gb  copy_init3.o [4]
-__iar_data_init3         0x800'30ad   0x28  Code  Gb  data_init.o [4]
-__iar_debug_exceptions   0x800'30aa    0x1  Data  Gb  unwind_debug.o [5]
-__iar_init_vfp           0x800'3135         Code  Gb  fpinit_M.o [3]
-__iar_program_start      0x800'3211         Code  Gb  cstartup_M.o [4]
-__iar_zero_init3         0x800'2197   0x3a  Code  Gb  zero_init3.o [4]
-__low_level_init         0x800'319b    0x4  Code  Gb  low_level_init.o [2]
-__vector_table           0x800'0000         Data  Gb  startup_stm32g431xx.o [1]
-_call_main               0x800'3189         Code  Gb  cmain.o [4]
-_exit                    0x800'31a5         Code  Gb  cexit.o [4]
-_main                    0x800'3197         Code  Gb  cmain.o [4]
-defaultTaskHandle       0x2000'1908    0x4  Data  Gb  main.o [1]
-defaultTask_attributes   0x800'30d4   0x24  Data  Lc  main.o [1]
-exit                     0x800'319f    0x4  Code  Gb  exit.o [2]
-main                     0x800'2d65   0x2a  Code  Gb  main.o [1]
-memset                   0x800'2ef9   0x14  Code  Gb  memset.o [4]
-osDelay                  0x800'1399   0x22  Code  Gb  cmsis_os2.o [1]
-osKernelInitialize       0x800'125f   0x26  Code  Gb  cmsis_os2.o [1]
-osKernelStart            0x800'1285   0x30  Code  Gb  cmsis_os2.o [1]
-osThreadNew              0x800'12b5   0xe4  Code  Gb  cmsis_os2.o [1]
+                         0x800'2249    0x22  Code  Lc  stm32g4xx_hal_cortex.o [1]
+__aeabi_ldiv0            0x800'2085          Code  Gb  I64DivZer.o [5]
+__aeabi_memcpy           0x800'3675          Code  Gb  ABImemcpy.o [5]
+__aeabi_memcpy4          0x800'3695          Code  Gb  ABImemcpy.o [5]
+__aeabi_memcpy8          0x800'3695          Code  Gb  ABImemcpy.o [5]
+__aeabi_memmove          0x800'3749          Code  Gb  ABImemmove.o [5]
+__aeabi_memmove4         0x800'3749          Code  Gb  ABImemmove.o [5]
+__aeabi_memmove8         0x800'3749          Code  Gb  ABImemmove.o [5]
+__aeabi_memset           0x800'2afd          Code  Gb  ABImemset.o [5]
+__aeabi_uldivmod         0x800'1dcd          Code  Gb  I64DivMod.o [5]
+__call_ctors             0x800'5b95    0x18  Code  Gb  cppinit.o [2]
+__cmain                  0x800'5bad          Code  Gb  cmain.o [5]
+__exit                   0x800'5be1    0x14  Code  Gb  exit.o [6]
+__iar_Memset             0x800'2afd          Code  Gb  ABImemset.o [5]
+__iar_Memset_word        0x800'2b05          Code  Gb  ABImemset.o [5]
+__iar_copy_init3         0x800'158b    0x2e  Code  Gb  copy_init3.o [5]
+__iar_cstart_call_ctors
+                         0x800'5b75    0x20  Code  Gb  cmain_call_ctors.o [5]
+__iar_data_init3         0x800'5951    0x28  Code  Gb  data_init.o [5]
+__iar_debug_exceptions   0x800'200a     0x1  Data  Gb  unwind_debug.o [6]
+__iar_init_vfp           0x800'5a69          Code  Gb  fpinit_M.o [4]
+__iar_program_start      0x800'5d35          Code  Gb  cstartup_M.o [5]
+__iar_tls$$INIT_ARRAY$$Base
+                         0x800'5da8           --   Gb  - Linker created -
+__iar_tls$$INIT_ARRAY$$Limit
+                         0x800'5da8           --   Gb  - Linker created -
+__iar_zero_init3         0x800'143b    0x3a  Code  Gb  zero_init3.o [5]
+__low_level_init         0x800'5bcb     0x4  Code  Gb  low_level_init.o [2]
+__sti__routine           0x800'2089     0xa  Code  Lc  terminal_usartbridge.o [1]
+__sti__routine           0x800'25d9     0xa  Code  Lc  terminal_user.o [1]
+__vector_table           0x800'0000          Data  Gb  startup_stm32g431xx.o [1]
+_call_main               0x800'5bb9          Code  Gb  cmain.o [5]
+_exit                    0x800'5bd5          Code  Gb  cexit.o [5]
+_main                    0x800'5bc7          Code  Gb  cmain.o [5]
+completion_terminal      0x800'23e7    0x1a  Code  Gb  terminal.o [1]
+escape_process           0x800'30bb    0xfa  Code  Lc  microrl.o [1]
+execute_terminal         0x800'23bb    0x1a  Code  Gb  terminal.o [1]
+exit                     0x800'5bcf     0x4  Code  Gb  exit.o [2]
+helloNull               0x2000'5bf0     0x4  Data  Gb  terminal.o [1]
+hist_erase_older         0x800'2b65    0x14  Code  Lc  microrl.o [1]
+hist_is_space_for_new    0x800'2b79    0x3a  Code  Lc  microrl.o [1]
+hist_restore_line        0x800'2c59   0x1c4  Code  Lc  microrl.o [1]
+hist_save_line           0x800'2bb3    0xa6  Code  Lc  microrl.o [1]
+hist_search              0x800'3083    0x38  Code  Lc  microrl.o [1]
+inHandlerMode            0x800'34df    0x12  Code  Lc  cmsis_os.o [1]
+main                     0x800'547d    0x30  Code  Gb  main.o [1]
+makeFreeRtosPriority     0x800'34c9    0x16  Code  Lc  cmsis_os.o [1]
+memset                   0x800'5635    0x14  Code  Gb  memset.o [5]
+microrl_backspace        0x800'3253    0x5e  Code  Lc  microrl.o [1]
+microrl_init             0x800'2fef    0x6a  Code  Gb  microrl.o [1]
+microrl_insert_char      0x800'333d   0x176  Code  Gb  microrl.o [1]
+microrl_insert_text      0x800'31b5    0x9e  Code  Lc  microrl.o [1]
+microrl_set_complete_callback
+                         0x800'3071     0x6  Code  Gb  microrl.o [1]
+microrl_set_execute_callback
+                         0x800'3077     0x6  Code  Gb  microrl.o [1]
+microrl_set_sigint_callback
+                         0x800'307d     0x6  Code  Gb  microrl.o [1]
+new_line_handler         0x800'32b1    0x8c  Code  Gb  microrl.o [1]
+osDelay                  0x800'3529    0x1c  Code  Gb  cmsis_os.o [1]
+osKernelStart            0x800'34f1     0xa  Code  Gb  cmsis_os.o [1]
+osMessageCreate          0x800'3545    0x12  Code  Gb  cmsis_os.o [1]
+osMessageGet             0x800'35bd    0xb2  Code  Gb  cmsis_os.o [1]
+osMessagePut             0x800'3557    0x66  Code  Gb  cmsis_os.o [1]
+osThreadCreate           0x800'34fb    0x2e  Code  Gb  cmsis_os.o [1]
+pTerminal               0x2000'5bf4     0x4  Data  Gb  terminal_user.o [1]
 pcInterruptPriorityRegisters
-                         0x800'3238    0x4  Data  Lc  port.o [1]
+                         0x800'5dac     0x4  Data  Lc  port.o [1]
+print_prompt             0x800'2e75     0xe  Code  Lc  microrl.o [1]
+print_terminal           0x800'23a9    0x12  Code  Gb  terminal.o [1]
+print_usartbridge(char const *)
+                         0x800'2093     0xe  Code  Gb  terminal_usartbridge.o [1]
+prompt_default          0x2000'0000     0x4  Data  Gb  microrl.o [1]
 prvAddCurrentTaskToDelayedList
-                         0x800'0ba1   0x6c  Code  Lc  tasks.o [1]
+                         0x800'4159    0x6c  Code  Lc  tasks.o [1]
 prvAddNewTaskToReadyList
-                         0x800'03cb   0x9e  Code  Lc  tasks.o [1]
+                         0x800'3933    0x9e  Code  Lc  tasks.o [1]
 prvCheckForValidListAndQueue
-                         0x800'1839   0x4c  Code  Lc  timers.o [1]
-prvCheckForValidListAndQueue{1}{2}{3}{4}::ucStaticTimerQueueStorage
-                        0x2000'1670   0xa0  Data  Lc  timers.o [1]
-prvCheckForValidListAndQueue{1}{2}{3}{4}::xStaticTimerQueue
-                        0x2000'17c8   0x50  Data  Lc  timers.o [1]
+                         0x800'535d    0x46  Code  Lc  timers.o [1]
 prvCheckTasksWaitingTermination
-                         0x800'0a1b   0x3e  Code  Lc  tasks.o [1]
-prvCopyDataFromQueue     0x800'1f9d   0x36  Code  Lc  queue.o [1]
-prvCopyDataToQueue       0x800'1f01   0x9c  Code  Lc  queue.o [1]
-prvDeleteTCB             0x800'0a5d   0x44  Code  Lc  tasks.o [1]
-prvGetNextExpireTime     0x800'15cb   0x28  Code  Lc  timers.o [1]
-prvHeapInit              0x800'0de1   0x62  Code  Lc  heap_4.o [1]
-prvIdleTask              0x800'09a1   0x24  Code  Lc  tasks.o [1]
-prvInitialiseNewQueue    0x800'1ad3   0x36  Code  Lc  queue.o [1]
-prvInitialiseNewTask     0x800'02e5   0xe6  Code  Lc  tasks.o [1]
-prvInitialiseTaskLists   0x800'09c5   0x56  Code  Lc  tasks.o [1]
+                         0x800'4005    0x3e  Code  Lc  tasks.o [1]
+prvCopyDataFromQueue     0x800'4855    0x36  Code  Lc  queue.o [1]
+prvCopyDataToQueue       0x800'47b9    0x9c  Code  Lc  queue.o [1]
+prvDeleteTCB             0x800'4043    0x12  Code  Lc  tasks.o [1]
+prvGetNextExpireTime     0x800'50ef    0x28  Code  Lc  timers.o [1]
+prvHeapInit              0x800'4b4d    0x62  Code  Lc  heap_4.o [1]
+prvIdleTask              0x800'3f8d    0x24  Code  Lc  tasks.o [1]
+prvInitialiseNewQueue    0x800'42d9    0x36  Code  Lc  queue.o [1]
+prvInitialiseNewTask     0x800'384d    0xe6  Code  Lc  tasks.o [1]
+prvInitialiseTaskLists   0x800'3fb1    0x54  Code  Lc  tasks.o [1]
 prvInsertBlockIntoFreeList
-                         0x800'0e43   0x5e  Code  Lc  heap_4.o [1]
+                         0x800'4baf    0x5e  Code  Lc  heap_4.o [1]
 prvInsertTimerInActiveList
-                         0x800'161b   0x52  Code  Lc  timers.o [1]
-prvIsQueueEmpty          0x800'2041   0x1c  Code  Lc  queue.o [1]
-prvIsQueueFull           0x800'205d   0x1e  Code  Lc  queue.o [1]
-prvProcessExpiredTimer   0x800'14cf   0x6c  Code  Lc  timers.o [1]
+                         0x800'513f    0x52  Code  Lc  timers.o [1]
+prvIsQueueEmpty          0x800'48f9    0x1c  Code  Lc  queue.o [1]
+prvIsQueueFull           0x800'4915    0x1e  Code  Lc  queue.o [1]
+prvProcessExpiredTimer   0x800'4ff3    0x6c  Code  Lc  timers.o [1]
 prvProcessReceivedCommands
-                         0x800'166d  0x13e  Code  Lc  timers.o [1]
+                         0x800'5191   0x13e  Code  Lc  timers.o [1]
 prvProcessTimerOrBlockTask
-                         0x800'1557   0x74  Code  Lc  timers.o [1]
+                         0x800'507b    0x74  Code  Lc  timers.o [1]
 prvResetNextTaskUnblockTime
-                         0x800'0aa1   0x26  Code  Lc  tasks.o [1]
-prvSampleTimeNow         0x800'15f3   0x28  Code  Lc  timers.o [1]
+                         0x800'4055    0x26  Code  Lc  tasks.o [1]
+prvSampleTimeNow         0x800'5117    0x28  Code  Lc  timers.o [1]
 prvSampleTimeNow::xLastTime
-                        0x2000'1960    0x4  Data  Lc  timers.o [1]
-prvSwitchTimerLists      0x800'17ab   0x8e  Code  Lc  timers.o [1]
-prvTaskExitError         0x800'0fed   0x2a  Code  Lc  port.o [1]
-prvTimerTask             0x800'153d   0x1a  Code  Lc  timers.o [1]
-prvUnlockQueue           0x800'1fd3   0x6e  Code  Lc  queue.o [1]
-pvPortMalloc             0x800'0c3d  0x128  Code  Gb  heap_4.o [1]
-pxCurrentTCB            0x2000'1914    0x4  Data  Gb  tasks.o [1]
-pxCurrentTimerList      0x2000'1950    0x4  Data  Lc  timers.o [1]
-pxDelayedTaskList       0x2000'1918    0x4  Data  Lc  tasks.o [1]
-pxEnd                   0x2000'18f0    0x4  Data  Lc  heap_4.o [1]
+                        0x2000'5c0c     0x4  Data  Lc  timers.o [1]
+prvSwitchTimerLists      0x800'52cf    0x8e  Code  Lc  timers.o [1]
+prvTaskExitError         0x800'4cf5    0x2a  Code  Lc  port.o [1]
+prvTimerTask             0x800'5061    0x1a  Code  Lc  timers.o [1]
+prvUnlockQueue           0x800'488b    0x6e  Code  Lc  queue.o [1]
+pvPortMalloc             0x800'49a9   0x128  Code  Gb  heap_4.o [1]
+pxCurrentTCB            0x2000'5bb4     0x4  Data  Gb  tasks.o [1]
+pxCurrentTimerList      0x2000'5bfc     0x4  Data  Lc  timers.o [1]
+pxDelayedTaskList       0x2000'5bb8     0x4  Data  Lc  tasks.o [1]
+pxEnd                   0x2000'5b90     0x4  Data  Lc  heap_4.o [1]
 pxOverflowDelayedTaskList
-                        0x2000'191c    0x4  Data  Lc  tasks.o [1]
-pxOverflowTimerList     0x2000'1954    0x4  Data  Lc  timers.o [1]
-pxPortInitialiseStack    0x800'0fc5   0x28  Code  Gb  port.o [1]
-pxReadyTasksLists       0x2000'0c10  0x460  Data  Lc  tasks.o [1]
-ucHeap                  0x2000'0010  0xc00  Data  Lc  heap_4.o [1]
-ucMaxSysCallPriority    0x2000'1964    0x1  Data  Lc  port.o [1]
-ulMaxPRIGROUPValue      0x2000'190c    0x4  Data  Lc  port.o [1]
-uwTick                  0x2000'1910    0x4  Data  Gb  stm32g4xx_hal.o [1]
-uwTickFreq              0x2000'0008    0x4  Data  Gb  stm32g4xx_hal.o [1]
-uwTickPrio              0x2000'0004    0x4  Data  Gb  stm32g4xx_hal.o [1]
-uxCriticalNesting       0x2000'0000    0x4  Data  Lc  port.o [1]
-uxCurrentNumberOfTasks  0x2000'1924    0x4  Data  Lc  tasks.o [1]
+                        0x2000'5bbc     0x4  Data  Lc  tasks.o [1]
+pxOverflowTimerList     0x2000'5c00     0x4  Data  Lc  timers.o [1]
+pxPortInitialiseStack    0x800'4ccd    0x28  Code  Gb  port.o [1]
+pxReadyTasksLists       0x2000'5814    0xf0  Data  Lc  tasks.o [1]
+sbsTerminal             0x2000'5904    0xec  Data  Gb  terminal_user.o [1]
+sigint_terminal          0x800'23d5    0x12  Code  Gb  terminal.o [1]
+split                    0x800'2e1d    0x58  Code  Lc  microrl.o [1]
+startupTaskHandle       0x2000'5ba8     0x4  Data  Gb  main.o [1]
+strcmp                   0x800'371d          Code  Gb  strcmp.o [5]
+strcpy                   0x800'3731          Code  Gb  strcpy.o [5]
+strlen                   0x800'25a1          Code  Gb  strlen.o [5]
+terminalUsartBridge     0x2000'59f0    0xa4  Data  Gb  terminal_usartbridge.o [1]
+terminal_backspace       0x800'2e83    0x10  Code  Lc  microrl.o [1]
+terminal_move_cursor     0x800'2efb    0x5a  Code  Lc  microrl.o [1]
+terminal_newline         0x800'2e93     0xe  Code  Lc  microrl.o [1]
+terminal_print_line      0x800'2f93    0x5c  Code  Lc  microrl.o [1]
+terminal_reset_cursor    0x800'2f55    0x3e  Code  Lc  microrl.o [1]
+terminaltTaskHandle     0x2000'5bf8     0x4  Data  Gb  terminal_user.o [1]
+tmpCommand              0x2000'5ad4    0x28  Data  Lc  terminal.o [1]
+u16bit_to_str            0x800'2ea1    0x5a  Code  Lc  microrl.o [1]
+ucHeap                  0x2000'0014  0x5800  Data  Lc  heap_4.o [1]
+ucMaxSysCallPriority    0x2000'5c10     0x1  Data  Lc  port.o [1]
+ulMaxPRIGROUPValue      0x2000'5bac     0x4  Data  Lc  port.o [1]
+uwTick                  0x2000'5bb0     0x4  Data  Gb  stm32g4xx_hal.o [1]
+uwTickFreq              0x2000'000c     0x4  Data  Gb  stm32g4xx_hal.o [1]
+uwTickPrio              0x2000'0008     0x4  Data  Gb  stm32g4xx_hal.o [1]
+uxCriticalNesting       0x2000'0004     0x4  Data  Lc  port.o [1]
+uxCurrentNumberOfTasks  0x2000'5bc4     0x4  Data  Lc  tasks.o [1]
 uxDeletedTasksWaitingCleanUp
-                        0x2000'1920    0x4  Data  Lc  tasks.o [1]
-uxListRemove             0x800'0f9d   0x28  Code  Gb  list.o [1]
-uxSchedulerSuspended    0x2000'194c    0x4  Data  Lc  tasks.o [1]
-uxTaskNumber            0x2000'1940    0x4  Data  Lc  tasks.o [1]
-uxTopReadyPriority      0x2000'192c    0x4  Data  Lc  tasks.o [1]
-vApplicationGetIdleTaskMemory
-                         0x800'13c9   0x18  Code  Wk  cmsis_os2.o [1]
-vApplicationGetIdleTaskMemory::Idle_Stack
-                        0x2000'1470  0x200  Data  Lc  cmsis_os2.o [1]
-vApplicationGetIdleTaskMemory::Idle_TCB
-                        0x2000'1710   0x5c  Data  Lc  cmsis_os2.o [1]
-vApplicationGetTimerTaskMemory
-                         0x800'1965   0x18  Code  Wk  cmsis_os2.o [1]
-vApplicationGetTimerTaskMemory::Timer_Stack
-                        0x2000'1070  0x400  Data  Lc  cmsis_os2.o [1]
-vApplicationGetTimerTaskMemory::Timer_TCB
-                        0x2000'176c   0x5c  Data  Lc  cmsis_os2.o [1]
-vListInitialise          0x800'0f2b   0x1e  Code  Gb  list.o [1]
-vListInitialiseItem      0x800'0f49    0x6  Code  Gb  list.o [1]
-vListInsert              0x800'0f67   0x36  Code  Gb  list.o [1]
-vListInsertEnd           0x800'0f4f   0x18  Code  Gb  list.o [1]
-vPortEnableVFP           0x800'1949         Code  Gb  portasm.o [1]
-vPortEnterCritical       0x800'10e5   0x34  Code  Gb  port.o [1]
-vPortExitCritical        0x800'1119   0x2c  Code  Gb  port.o [1]
-vPortFree                0x800'0d65   0x7c  Code  Gb  heap_4.o [1]
-vPortStartFirstTask      0x800'1929         Code  Gb  portasm.o [1]
+                        0x2000'5bc0     0x4  Data  Lc  tasks.o [1]
+uxListRemove             0x800'4ca3    0x28  Code  Gb  list.o [1]
+uxSchedulerSuspended    0x2000'5bec     0x4  Data  Lc  tasks.o [1]
+uxTaskNumber            0x2000'5be0     0x4  Data  Lc  tasks.o [1]
+uxTopReadyPriority      0x2000'5bcc     0x4  Data  Lc  tasks.o [1]
+vListInitialise          0x800'4c31    0x1e  Code  Gb  list.o [1]
+vListInitialiseItem      0x800'4c4f     0x6  Code  Gb  list.o [1]
+vListInsert              0x800'4c6d    0x36  Code  Gb  list.o [1]
+vListInsertEnd           0x800'4c55    0x18  Code  Gb  list.o [1]
+vPortEnableVFP           0x800'5461          Code  Gb  portasm.o [1]
+vPortEnterCritical       0x800'4ded    0x34  Code  Gb  port.o [1]
+vPortExitCritical        0x800'4e21    0x2c  Code  Gb  port.o [1]
+vPortFree                0x800'4ad1    0x7c  Code  Gb  heap_4.o [1]
+vPortStartFirstTask      0x800'5441          Code  Gb  portasm.o [1]
 vPortValidateInterruptPriority
-                         0x800'116d   0x4e  Code  Gb  port.o [1]
-vQueueAddToRegistry      0x800'207b   0x26  Code  Gb  queue.o [1]
+                         0x800'4e75    0x4e  Code  Gb  port.o [1]
+vQueueAddToRegistry      0x800'4933    0x26  Code  Gb  queue.o [1]
 vQueueWaitForMessageRestricted
-                         0x800'20a5   0x4c  Code  Gb  queue.o [1]
-vTaskDelay               0x800'0469   0x4e  Code  Gb  tasks.o [1]
+                         0x800'495d    0x4c  Code  Gb  queue.o [1]
+vTaskDelay               0x800'3a7b    0x4e  Code  Gb  tasks.o [1]
+vTaskDelete              0x800'39d1    0xaa  Code  Gb  tasks.o [1]
 vTaskInternalSetTimeOutState
-                         0x800'08e5   0x12  Code  Gb  tasks.o [1]
-vTaskMissedYield         0x800'0991    0xa  Code  Gb  tasks.o [1]
-vTaskPlaceOnEventList    0x800'07c9   0x34  Code  Gb  tasks.o [1]
+                         0x800'3ed5    0x12  Code  Gb  tasks.o [1]
+vTaskMissedYield         0x800'3f7b     0xa  Code  Gb  tasks.o [1]
+vTaskPlaceOnEventList    0x800'3db3    0x34  Code  Gb  tasks.o [1]
 vTaskPlaceOnEventListRestricted
-                         0x800'0819   0x40  Code  Gb  tasks.o [1]
-vTaskStartScheduler      0x800'04b7   0x9a  Code  Gb  tasks.o [1]
-vTaskSuspendAll          0x800'0551    0xc  Code  Gb  tasks.o [1]
-vTaskSwitchContext       0x800'0757   0x72  Code  Gb  tasks.o [1]
-xActiveTimerList1       0x2000'18bc   0x14  Data  Lc  timers.o [1]
-xActiveTimerList2       0x2000'18d0   0x14  Data  Lc  timers.o [1]
-xBlockAllocatedBit      0x2000'1904    0x4  Data  Lc  heap_4.o [1]
-xDelayedTaskList1       0x2000'1858   0x14  Data  Lc  tasks.o [1]
-xDelayedTaskList2       0x2000'186c   0x14  Data  Lc  tasks.o [1]
-xFreeBytesRemaining     0x2000'18f4    0x4  Data  Lc  heap_4.o [1]
-xHeapStructSize          0x800'3234    0x4  Data  Lc  heap_4.o [1]
-xIdleTaskHandle         0x2000'1948    0x4  Data  Lc  tasks.o [1]
+                         0x800'3dfd    0x40  Code  Gb  tasks.o [1]
+vTaskStartScheduler      0x800'3ac9    0x72  Code  Gb  tasks.o [1]
+vTaskSuspendAll          0x800'3b3b     0xc  Code  Gb  tasks.o [1]
+vTaskSwitchContext       0x800'3d41    0x72  Code  Gb  tasks.o [1]
+vTerminal(void const *)
+                         0x800'2811    0x32  Code  Gb  terminal_user.o [1]
+xActiveTimerList1       0x2000'5b60    0x14  Data  Lc  timers.o [1]
+xActiveTimerList2       0x2000'5b74    0x14  Data  Lc  timers.o [1]
+xBlockAllocatedBit      0x2000'5ba4     0x4  Data  Lc  heap_4.o [1]
+xDelayedTaskList1       0x2000'5afc    0x14  Data  Lc  tasks.o [1]
+xDelayedTaskList2       0x2000'5b10    0x14  Data  Lc  tasks.o [1]
+xFreeBytesRemaining     0x2000'5b94     0x4  Data  Lc  heap_4.o [1]
+xHeapStructSize          0x800'5da8     0x4  Data  Lc  heap_4.o [1]
+xIdleTaskHandle         0x2000'5be8     0x4  Data  Lc  tasks.o [1]
 xMinimumEverFreeBytesRemaining
-                        0x2000'18f8    0x4  Data  Lc  heap_4.o [1]
-xNextTaskUnblockTime    0x2000'1944    0x4  Data  Lc  tasks.o [1]
-xNumOfOverflows         0x2000'193c    0x4  Data  Lc  tasks.o [1]
+                        0x2000'5b98     0x4  Data  Lc  heap_4.o [1]
+xNextTaskUnblockTime    0x2000'5be4     0x4  Data  Lc  tasks.o [1]
+xNumOfOverflows         0x2000'5bdc     0x4  Data  Lc  tasks.o [1]
 xNumberOfSuccessfulAllocations
-                        0x2000'18fc    0x4  Data  Lc  heap_4.o [1]
+                        0x2000'5b9c     0x4  Data  Lc  heap_4.o [1]
 xNumberOfSuccessfulFrees
-                        0x2000'1900    0x4  Data  Lc  heap_4.o [1]
-xPendedTicks            0x2000'1934    0x4  Data  Lc  tasks.o [1]
-xPendingReadyList       0x2000'1880   0x14  Data  Lc  tasks.o [1]
-xPortStartScheduler      0x800'1017   0xce  Code  Gb  port.o [1]
-xPortSysTickHandler      0x800'1145   0x28  Code  Gb  port.o [1]
-xQueueGenericCreateStatic
-                         0x800'1a11   0xc2  Code  Gb  queue.o [1]
-xQueueGenericReset       0x800'197d   0x94  Code  Gb  queue.o [1]
-xQueueGenericSend        0x800'1b09  0x1a6  Code  Gb  queue.o [1]
+                        0x2000'5ba0     0x4  Data  Lc  heap_4.o [1]
+xPendedTicks            0x2000'5bd4     0x4  Data  Lc  tasks.o [1]
+xPendingReadyList       0x2000'5b24    0x14  Data  Lc  tasks.o [1]
+xPortStartScheduler      0x800'4d1f    0xce  Code  Gb  port.o [1]
+xPortSysTickHandler      0x800'4e4d    0x28  Code  Gb  port.o [1]
+xQueueGenericCreate      0x800'428d    0x4c  Code  Gb  queue.o [1]
+xQueueGenericReset       0x800'41f9    0x94  Code  Gb  queue.o [1]
+xQueueGenericSend        0x800'430f   0x1a6  Code  Gb  queue.o [1]
 xQueueGenericSendFromISR
-                         0x800'1caf   0xe4  Code  Gb  queue.o [1]
-xQueueReceive            0x800'1d93  0x16a  Code  Gb  queue.o [1]
-xQueueRegistry          0x2000'1818   0x40  Data  Gb  queue.o [1]
-xSchedulerRunning       0x2000'1930    0x4  Data  Lc  tasks.o [1]
-xStart                  0x2000'18e4    0x8  Data  Lc  heap_4.o [1]
-xSuspendedTaskList      0x2000'18a8   0x14  Data  Lc  tasks.o [1]
-xTaskCheckForTimeOut     0x800'08fd   0x8e  Code  Gb  tasks.o [1]
-xTaskCreate              0x800'0273   0x72  Code  Gb  tasks.o [1]
-xTaskCreateStatic        0x800'01d9   0x9a  Code  Gb  tasks.o [1]
-xTaskGetSchedulerState   0x800'0ac7   0x20  Code  Gb  tasks.o [1]
-xTaskGetTickCount        0x800'0645    0x8  Code  Gb  tasks.o [1]
-xTaskIncrementTick       0x800'064d  0x10a  Code  Gb  tasks.o [1]
+                         0x800'44b5    0xe4  Code  Gb  queue.o [1]
+xQueueReceive            0x800'4599   0x16a  Code  Gb  queue.o [1]
+xQueueReceiveFromISR     0x800'4709    0xb0  Code  Gb  queue.o [1]
+xQueueRegistry          0x2000'5a94    0x40  Data  Gb  queue.o [1]
+xSchedulerRunning       0x2000'5bd0     0x4  Data  Lc  tasks.o [1]
+xStart                  0x2000'5b88     0x8  Data  Lc  heap_4.o [1]
+xSuspendedTaskList      0x2000'5b4c    0x14  Data  Lc  tasks.o [1]
+xTaskCheckForTimeOut     0x800'3eed    0x8e  Code  Gb  tasks.o [1]
+xTaskCreate              0x800'37e1    0x6c  Code  Gb  tasks.o [1]
+xTaskGetSchedulerState   0x800'4081    0x20  Code  Gb  tasks.o [1]
+xTaskGetTickCount        0x800'3c2f     0x8  Code  Gb  tasks.o [1]
+xTaskIncrementTick       0x800'3c37   0x10a  Code  Gb  tasks.o [1]
 xTaskPriorityDisinherit
-                         0x800'0ae7   0x8e  Code  Gb  tasks.o [1]
+                         0x800'40a1    0x8e  Code  Gb  tasks.o [1]
 xTaskRemoveFromEventList
-                         0x800'0859   0x82  Code  Gb  tasks.o [1]
-xTaskResumeAll           0x800'055d   0xe8  Code  Gb  tasks.o [1]
+                         0x800'3e45    0x82  Code  Gb  tasks.o [1]
+xTaskResumeAll           0x800'3b47    0xe8  Code  Gb  tasks.o [1]
 xTasksWaitingTermination
-                        0x2000'1894   0x14  Data  Lc  tasks.o [1]
-xTickCount              0x2000'1928    0x4  Data  Lc  tasks.o [1]
-xTimerCreateTimerTask    0x800'13e1   0x6c  Code  Gb  timers.o [1]
-xTimerGenericCommand     0x800'144d   0x82  Code  Gb  timers.o [1]
-xTimerQueue             0x2000'1958    0x4  Data  Lc  timers.o [1]
-xTimerTaskHandle        0x2000'195c    0x4  Data  Lc  timers.o [1]
-xYieldPending           0x2000'1938    0x4  Data  Lc  tasks.o [1]
+                        0x2000'5b38    0x14  Data  Lc  tasks.o [1]
+xTickCount              0x2000'5bc8     0x4  Data  Lc  tasks.o [1]
+xTimerCreateTimerTask    0x800'4f29    0x48  Code  Gb  timers.o [1]
+xTimerGenericCommand     0x800'4f71    0x82  Code  Gb  timers.o [1]
+xTimerQueue             0x2000'5c04     0x4  Data  Lc  timers.o [1]
+xTimerTaskHandle        0x2000'5c08     0x4  Data  Lc  timers.o [1]
+xYieldPending           0x2000'5bd8     0x4  Data  Lc  tasks.o [1]
 
 
 [1] = D:\FlyElectronics\tuber\project\ewarm\desk\Debug\Obj
 [2] = dl7M_tlf.a
-[3] = m7M_tls.a
-[4] = rt7M_tl.a
-[5] = shb_l.a
-
-  12'985 bytes of readonly  code memory
-     151 bytes of readonly  data memory
-   7'525 bytes of readwrite data memory
+[3] = dlpp7M_tl_fc.a
+[4] = m7M_tls.a
+[5] = rt7M_tl.a
+[6] = shb_l.a
+
+  23'033 bytes of readonly  code memory
+   1'223 bytes of readonly  data memory
+  24'593 bytes of readwrite data memory
 
 Errors: none
 Warnings: none

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 416 - 351
project/ewarm/desk/desk.dep


+ 28 - 2
project/ewarm/desk/desk.ewp

@@ -353,13 +353,15 @@
                     <state>$PROJ_DIR$/../../../desk/libs</state>
                     <state>$PROJ_DIR$/../../../desk/user</state>
                     <state>$PROJ_DIR$/../../../desk/modules</state>
+                    <state>$PROJ_DIR$/../../../desk/modules/terminal</state>
                     <state>$PROJ_DIR$/../../../desk/libs/stm32/hal/Inc</state>
                     <state>$PROJ_DIR$/../../../desk/libs/stm32/cmsis</state>
-                    <state>$PROJ_DIR$/../../../desk/libs/thirdparty/freertos/CMSIS_RTOS_V2</state>
+                    <state>$PROJ_DIR$/../../../desk/libs/thirdparty/freertos/CMSIS_RTOS</state>
                     <state>$PROJ_DIR$/../../../desk/libs/thirdparty/freertos/portable/IAR/ARM_CM4F</state>
                     <state>$PROJ_DIR$/../../../desk/libs/thirdparty/freertos/include</state>
                     <state>$PROJ_DIR$/../../../desk/libs/thirdparty/freertos</state>
                     <state>$PROJ_DIR$/../../../desk/libs/thirdparty/oled_ssd1327</state>
+                    <state>$PROJ_DIR$/../../../thirdparty_libs/microrl</state>
                 </option>
                 <option>
                     <name>CCStdIncCheck</name>
@@ -2322,7 +2324,7 @@
             <group>
                 <name>freertos</name>
                 <file>
-                    <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\CMSIS_RTOS_V2\cmsis_os2.c</name>
+                    <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\CMSIS_RTOS\cmsis_os.c</name>
                 </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\croutine.c</name>
@@ -2355,6 +2357,12 @@
                     <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\timers.c</name>
                 </file>
             </group>
+            <group>
+                <name>microrl</name>
+                <file>
+                    <name>$PROJ_DIR$\..\..\..\thirdparty_libs\microrl\microrl.c</name>
+                </file>
+            </group>
             <group>
                 <name>oled_ssd1327</name>
                 <file>
@@ -2371,12 +2379,30 @@
     </group>
     <group>
         <name>modules</name>
+        <group>
+            <name>terminal</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\desk\modules\terminal\terminal.cpp</name>
+            </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\desk\modules\terminal\terminal_usartbridge.cpp</name>
+            </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\desk\modules\terminal\terminal_user.cpp</name>
+            </file>
+        </group>
     </group>
     <group>
         <name>user</name>
         <file>
             <name>$PROJ_DIR$\..\..\..\desk\user\app_freertos.c</name>
         </file>
+        <file>
+            <name>$PROJ_DIR$\..\..\..\desk\user\FreeRTOSConfig.h</name>
+        </file>
+        <file>
+            <name>$PROJ_DIR$\..\..\..\desk\user\hal_callback.cpp</name>
+        </file>
         <file>
             <name>$PROJ_DIR$\..\..\..\desk\user\main.cpp</name>
         </file>

+ 27 - 3
project/ewarm/desk/desk.ewt

@@ -18,7 +18,7 @@
                     <analyzeTimeoutEnabled>1</analyzeTimeoutEnabled>
                     <analyzeTimeout>600</analyzeTimeout>
                     <enableParallel>1</enableParallel>
-                    <parallelThreads>8</parallelThreads>
+                    <parallelThreads>4</parallelThreads>
                     <enableFalsePositives>0</enableFalsePositives>
                     <messagesLimitEnabled>1</messagesLimitEnabled>
                     <messagesLimit>100</messagesLimit>
@@ -1202,7 +1202,7 @@
                     <analyzeTimeoutEnabled>1</analyzeTimeoutEnabled>
                     <analyzeTimeout>600</analyzeTimeout>
                     <enableParallel>1</enableParallel>
-                    <parallelThreads>8</parallelThreads>
+                    <parallelThreads>4</parallelThreads>
                     <enableFalsePositives>0</enableFalsePositives>
                     <messagesLimitEnabled>1</messagesLimitEnabled>
                     <messagesLimit>100</messagesLimit>
@@ -2568,7 +2568,7 @@
             <group>
                 <name>freertos</name>
                 <file>
-                    <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\CMSIS_RTOS_V2\cmsis_os2.c</name>
+                    <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\CMSIS_RTOS\cmsis_os.c</name>
                 </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\croutine.c</name>
@@ -2601,6 +2601,12 @@
                     <name>$PROJ_DIR$\..\..\..\desk\libs\thirdparty\freertos\timers.c</name>
                 </file>
             </group>
+            <group>
+                <name>microrl</name>
+                <file>
+                    <name>$PROJ_DIR$\..\..\..\thirdparty_libs\microrl\microrl.c</name>
+                </file>
+            </group>
             <group>
                 <name>oled_ssd1327</name>
                 <file>
@@ -2617,12 +2623,30 @@
     </group>
     <group>
         <name>modules</name>
+        <group>
+            <name>terminal</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\desk\modules\terminal\terminal.cpp</name>
+            </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\desk\modules\terminal\terminal_usartbridge.cpp</name>
+            </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\desk\modules\terminal\terminal_user.cpp</name>
+            </file>
+        </group>
     </group>
     <group>
         <name>user</name>
         <file>
             <name>$PROJ_DIR$\..\..\..\desk\user\app_freertos.c</name>
         </file>
+        <file>
+            <name>$PROJ_DIR$\..\..\..\desk\user\FreeRTOSConfig.h</name>
+        </file>
+        <file>
+            <name>$PROJ_DIR$\..\..\..\desk\user\hal_callback.cpp</name>
+        </file>
         <file>
             <name>$PROJ_DIR$\..\..\..\desk\user\main.cpp</name>
         </file>

+ 14 - 14
project/ewarm/desk/settings/desk.dnx

@@ -16,7 +16,7 @@
         <ShowSource>1</ShowSource>
     </Trace1>
     <DebugChecksum>
-        <Checksum>3155786882</Checksum>
+        <Checksum>1448152765</Checksum>
     </DebugChecksum>
     <Disassembly>
         <InstrCount>0</InstrCount>
@@ -50,12 +50,12 @@
         <MultiCoreRunAll>1</MultiCoreRunAll>
     </Simulator>
     <StLinkDriver>
-        <stlinkserialNo>67101537</stlinkserialNo>
+        <stlinkserialNo>67161124</stlinkserialNo>
         <stlinkfoundProbes />
-        <stlinkResetStyle>0</stlinkResetStyle>
-        <stlinkResetStrategy>0</stlinkResetStrategy>
         <CStepIntDis>_ 0</CStepIntDis>
         <LeaveTargetRunning>_ 0</LeaveTargetRunning>
+        <stlinkResetStyle>0</stlinkResetStyle>
+        <stlinkResetStrategy>0</stlinkResetStrategy>
     </StLinkDriver>
     <SWOTraceHWSettings>
         <OverrideDefaultClocks>0</OverrideDefaultClocks>
@@ -120,6 +120,12 @@
         <ShowTimeSum>1</ShowTimeSum>
         <SumSortOrder>0</SumSortOrder>
     </EventLog>
+    <DisassembleMode>
+        <mode>0</mode>
+    </DisassembleMode>
+    <Breakpoints2>
+        <Count>0</Count>
+    </Breakpoints2>
     <TermIOLog>
         <LoggingEnabled>_ 0</LoggingEnabled>
         <LogFile>_ ""</LogFile>
@@ -129,6 +135,10 @@
         <LogFile>_ ""</LogFile>
         <Category>_ 0</Category>
     </LogFile>
+    <Aliases>
+        <Count>0</Count>
+        <SuppressDialog>0</SuppressDialog>
+    </Aliases>
     <DriverProfiling>
         <Enabled>0</Enabled>
         <Mode>3</Mode>
@@ -142,14 +152,4 @@
     <CallStackStripe>
         <ShowTiming>1</ShowTiming>
     </CallStackStripe>
-    <DisassembleMode>
-        <mode>0</mode>
-    </DisassembleMode>
-    <Breakpoints2>
-        <Count>0</Count>
-    </Breakpoints2>
-    <Aliases>
-        <Count>0</Count>
-        <SuppressDialog>0</SuppressDialog>
-    </Aliases>
 </settings>

+ 11 - 11
project/ewarm/robot/robot.dep

@@ -6,29 +6,29 @@
         <name>Debug</name>
         <outputs>
             <file>$PROJ_DIR$\main.cpp</file>
-            <file>$PROJ_DIR$\Debug\Obj\main.xcl</file>
             <file>$PROJ_DIR$\Debug\Obj\main.o</file>
+            <file>$PROJ_DIR$\Debug\Obj\main.xcl</file>
             <file>$PROJ_DIR$\Debug\Exe\robot.out</file>
         </outputs>
         <file>
-            <name>$PROJ_DIR$\main.cpp</name>
+            <name>[ROOT_NODE]</name>
             <outputs>
                 <tool>
-                    <name>ICCARM</name>
-                    <file> 2</file>
-                </tool>
-                <tool>
-                    <name>BICOMP</name>
-                    <file> 1</file>
+                    <name>ILINK</name>
+                    <file> 3</file>
                 </tool>
             </outputs>
         </file>
         <file>
-            <name>[ROOT_NODE]</name>
+            <name>$PROJ_DIR$\main.cpp</name>
             <outputs>
                 <tool>
-                    <name>ILINK</name>
-                    <file> 3</file>
+                    <name>ICCARM</name>
+                    <file> 1</file>
+                </tool>
+                <tool>
+                    <name>BICOMP</name>
+                    <file> 2</file>
                 </tool>
             </outputs>
         </file>

+ 684 - 0
thirdparty_libs/microrl/microrl.c

@@ -0,0 +1,684 @@
+/*
+Author: Samoylov Eugene aka Helius (ghelius@gmail.com)
+BUGS and TODO:
+-- add echo_off feature
+-- rewrite history for use more than 256 byte buffer
+*/
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "microrl.h"
+#ifdef _USE_LIBC_STDIO
+#include <stdio.h>
+#endif
+
+//#define DBG(...) fprintf(stderr, "\033[33m");fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\033[0m");
+
+char * prompt_default = _PROMPT_DEFAULT;
+
+#ifdef _USE_HISTORY
+
+#ifdef _HISTORY_DEBUG
+//*****************************************************************************
+// print buffer content on screen
+static void print_hist (ring_history_t * pThis)
+{
+	printf ("\n");
+	for (int i = 0; i < _RING_HISTORY_LEN; i++) {
+		if (i == pThis->begin)
+			printf ("b");
+		else 
+			printf (" ");
+	}
+	printf ("\n");
+	for (int i = 0; i < _RING_HISTORY_LEN; i++) {
+		if (isalpha(pThis->ring_buf[i]))
+			printf ("%c", pThis->ring_buf[i]);
+		else 
+			printf ("%d", pThis->ring_buf[i]);
+	}
+	printf ("\n");
+	for (int i = 0; i < _RING_HISTORY_LEN; i++) {
+		if (i == pThis->end)
+			printf ("e");
+		else 
+			printf (" ");
+	}
+	printf ("\n");
+}
+#endif
+
+//*****************************************************************************
+// remove older message from ring buffer
+static void hist_erase_older (ring_history_t * pThis)
+{
+	int new_pos = pThis->begin + pThis->ring_buf [pThis->begin] + 1;
+	if (new_pos >= _RING_HISTORY_LEN)
+		new_pos = new_pos - _RING_HISTORY_LEN;
+	
+	pThis->begin = new_pos;
+}
+
+//*****************************************************************************
+// check space for new line, remove older while not space
+static int hist_is_space_for_new (ring_history_t * pThis, int len)
+{
+	if (pThis->ring_buf [pThis->begin] == 0)
+		return true;
+	if (pThis->end >= pThis->begin) {
+		if (_RING_HISTORY_LEN - pThis->end + pThis->begin - 1 > len)
+			return true;
+	}	else {
+		if (pThis->begin - pThis->end - 1> len)
+			return true;
+	}
+	return false;
+}
+
+//*****************************************************************************
+// put line to ring buffer
+static void hist_save_line (ring_history_t * pThis, char * line, int len)
+{
+	if (len > _RING_HISTORY_LEN - 2)
+		return;
+	while (!hist_is_space_for_new (pThis, len)) {
+		hist_erase_older (pThis);
+	}
+	// if it's first line
+	if (pThis->ring_buf [pThis->begin] == 0) 
+		pThis->ring_buf [pThis->begin] = len;
+	
+	// store line
+	if (len < _RING_HISTORY_LEN-pThis->end-1)
+		memcpy (pThis->ring_buf + pThis->end + 1, line, len);
+	else {
+		int part_len = _RING_HISTORY_LEN-pThis->end-1;
+		memcpy (pThis->ring_buf + pThis->end + 1, line, part_len);
+		memcpy (pThis->ring_buf, line + part_len, len - part_len);
+	}
+	pThis->ring_buf [pThis->end] = len;
+	pThis->end = pThis->end + len + 1;
+	if (pThis->end >= _RING_HISTORY_LEN)
+		pThis->end -= _RING_HISTORY_LEN;
+	pThis->ring_buf [pThis->end] = 0;
+	pThis->cur = 0;
+#ifdef _HISTORY_DEBUG
+	print_hist (pThis);
+#endif
+}
+
+//*****************************************************************************
+// copy saved line to 'line' and return size of line
+static int hist_restore_line (ring_history_t * pThis, char * line, int dir)
+{
+	int cnt = 0;
+	// count history record	
+	int header = pThis->begin;
+	while (pThis->ring_buf [header] != 0) {
+		header += pThis->ring_buf [header] + 1;
+		if (header >= _RING_HISTORY_LEN)
+			header -= _RING_HISTORY_LEN; 
+		cnt++;
+	}
+
+	if (dir == _HIST_UP) {
+		if (cnt >= pThis->cur) {
+			int header = pThis->begin;
+			int j = 0;
+			// found record for 'pThis->cur' index
+			while ((pThis->ring_buf [header] != 0) && (cnt - j -1 != pThis->cur)) {
+				header += pThis->ring_buf [header] + 1;
+				if (header >= _RING_HISTORY_LEN)
+					header -= _RING_HISTORY_LEN;
+				j++;
+			}
+			if (pThis->ring_buf[header]) {
+					pThis->cur++;
+				// obtain saved line
+				if (pThis->ring_buf [header] + header + 1< _RING_HISTORY_LEN) {
+					memset (line, 0, _COMMAND_LINE_LEN);
+					memcpy (line, pThis->ring_buf + header + 1, pThis->ring_buf[header]);
+				} else {
+					int part0 = _RING_HISTORY_LEN - header - 1;
+					memset (line, 0, _COMMAND_LINE_LEN);
+					memcpy (line, pThis->ring_buf + header + 1, part0);
+					memcpy (line + part0, pThis->ring_buf, pThis->ring_buf[header] - part0);
+				}
+				return pThis->ring_buf[header];
+			}
+		}
+	} else {
+		if (pThis->cur > 0) {
+				pThis->cur--;
+			int header = pThis->begin;
+			int j = 0;
+
+			while ((pThis->ring_buf [header] != 0) && (cnt - j != pThis->cur)) {
+				header += pThis->ring_buf [header] + 1;
+				if (header >= _RING_HISTORY_LEN)
+					header -= _RING_HISTORY_LEN;
+				j++;
+			}
+			if (pThis->ring_buf [header] + header < _RING_HISTORY_LEN) {
+				memcpy (line, pThis->ring_buf + header + 1, pThis->ring_buf[header]);
+			} else {
+				int part0 = _RING_HISTORY_LEN - header - 1;
+				memcpy (line, pThis->ring_buf + header + 1, part0);
+				memcpy (line + part0, pThis->ring_buf, pThis->ring_buf[header] - part0);
+			}
+			return pThis->ring_buf[header];
+		} else {
+			/* empty line */
+			return 0;
+		}
+	}
+	return -1;
+}
+#endif
+
+
+
+
+
+
+
+
+//*****************************************************************************
+// split cmdline to tkn array and return nmb of token
+static int split (microrl_t * pThis, int limit, char const ** tkn_arr)
+{
+	int i = 0;
+	int ind = 0;
+	while (1) {
+		// go to the first whitespace (zerro for us)
+		while ((pThis->cmdline [ind] == '\0') && (ind < limit)) {
+			ind++;
+		}
+		if (!(ind < limit)) return i;
+		tkn_arr[i++] = pThis->cmdline + ind;
+		if (i >= _COMMAND_TOKEN_NMB) {
+			return -1;
+		}
+		// go to the first NOT whitespace (not zerro for us)
+		while ((pThis->cmdline [ind] != '\0') && (ind < limit)) {
+			ind++;
+		}
+		if (!(ind < limit)) return i;
+	}
+	//return i;
+}
+
+
+//*****************************************************************************
+inline static void print_prompt (microrl_t * pThis)
+{
+	pThis->print (pThis->prompt_str);
+}
+
+//*****************************************************************************
+inline static void terminal_backspace (microrl_t * pThis)
+{
+		pThis->print ("\033[D \033[D");
+}
+
+//*****************************************************************************
+inline static void terminal_newline (microrl_t * pThis)
+{
+	pThis->print (ENDL);
+}
+
+#ifndef _USE_LIBC_STDIO
+//*****************************************************************************
+// convert 16 bit value to string
+// 0 value not supported!!! just make empty string
+// Returns pointer to a buffer tail
+static char *u16bit_to_str (unsigned int nmb, char * buf)
+{
+	char tmp_str [6] = {0,};
+	int i = 0, j;
+	if (nmb <= 0xFFFF) {
+		while (nmb > 0) {
+			tmp_str[i++] = (nmb % 10) + '0';
+			nmb /=10;
+		}
+		for (j = 0; j < i; ++j)
+			*(buf++) = tmp_str [i-j-1];
+	}
+	*buf = '\0';
+	return buf;
+}
+#endif
+
+
+//*****************************************************************************
+// set cursor at position from begin cmdline (after prompt) + offset
+static void terminal_move_cursor (microrl_t * pThis, int offset)
+{
+	char str[16] = {0,};
+#ifdef _USE_LIBC_STDIO 
+	if (offset > 0) {
+		snprintf (str, 16, "\033[%dC", offset);
+	} else if (offset < 0) {
+		snprintf (str, 16, "\033[%dD", -(offset));
+	}
+#else 
+	char *endstr;
+	strcpy (str, "\033[");
+	if (offset > 0) {
+		endstr = u16bit_to_str (offset, str+2);
+		strcpy (endstr, "C");
+	} else if (offset < 0) {
+		endstr = u16bit_to_str (-(offset), str+2);
+		strcpy (endstr, "D");
+	} else
+		return;
+#endif	
+	pThis->print (str);
+}
+
+//*****************************************************************************
+static void terminal_reset_cursor (microrl_t * pThis)
+{
+	char str[16];
+#ifdef _USE_LIBC_STDIO
+	snprintf (str, 16, "\033[%dD\033[%dC", \
+						_COMMAND_LINE_LEN + _PROMPT_LEN + 2, _PROMPT_LEN);
+
+#else
+	char *endstr;
+	strcpy (str, "\033[");
+	endstr = u16bit_to_str ( _COMMAND_LINE_LEN + _PROMPT_LEN + 2,str+2);
+	strcpy (endstr, "D\033["); endstr += 3;
+	endstr = u16bit_to_str (_PROMPT_LEN, endstr);
+	strcpy (endstr, "C");
+#endif
+	pThis->print (str);
+}
+
+//*****************************************************************************
+// print cmdline to screen, replace '\0' to wihitespace 
+static void terminal_print_line (microrl_t * pThis, int pos, int cursor)
+{
+	pThis->print ("\033[K");    // delete all from cursor to end
+
+	char nch [] = {0,0};
+	int i;
+	for (i = pos; i < pThis->cmdlen; i++) {
+		nch [0] = pThis->cmdline [i];
+		if (nch[0] == '\0')
+			nch[0] = ' ';
+		pThis->print (nch);
+	}
+	
+	terminal_reset_cursor (pThis);
+	terminal_move_cursor (pThis, cursor);
+}
+
+//*****************************************************************************
+void microrl_init (microrl_t * pThis, void (*print) (const char *)) 
+{
+	memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
+#ifdef _USE_HISTORY
+	memset(pThis->ring_hist.ring_buf, 0, _RING_HISTORY_LEN);
+	pThis->ring_hist.begin = 0;
+	pThis->ring_hist.end = 0;
+	pThis->ring_hist.cur = 0;
+#endif
+	pThis->cmdlen =0;
+	pThis->cursor = 0;
+	pThis->execute = NULL;
+	pThis->get_completion = NULL;
+#ifdef _USE_CTLR_C
+	pThis->sigint = NULL;
+#endif
+	pThis->prompt_str = prompt_default;
+	pThis->print = print;
+#ifdef _ENABLE_INIT_PROMPT
+	print_prompt (pThis);
+#endif
+}
+
+//*****************************************************************************
+void microrl_set_complete_callback (microrl_t * pThis, char ** (*get_completion)(int, const char* const*))
+{
+	pThis->get_completion = get_completion;
+}
+
+//*****************************************************************************
+void microrl_set_execute_callback (microrl_t * pThis, int (*execute)(int, const char* const*))
+{
+	pThis->execute = execute;
+}
+#ifdef _USE_CTLR_C
+//*****************************************************************************
+void microrl_set_sigint_callback (microrl_t * pThis, void (*sigintf)(void))
+{
+	pThis->sigint = sigintf;
+}
+#endif
+
+#ifdef _USE_ESC_SEQ
+static void hist_search (microrl_t * pThis, int dir)
+{
+	int len = hist_restore_line (&pThis->ring_hist, pThis->cmdline, dir);
+	if (len >= 0) {
+		pThis->cursor = pThis->cmdlen = len;
+		terminal_reset_cursor (pThis);
+		terminal_print_line (pThis, 0, pThis->cursor);
+	}
+}
+
+//*****************************************************************************
+// handling escape sequences
+static int escape_process (microrl_t * pThis, char ch)
+{
+	if (ch == '[') {
+		pThis->escape_seq = _ESC_BRACKET;
+		return 0;
+	} else if (pThis->escape_seq == _ESC_BRACKET) {
+		if (ch == 'A') {
+#ifdef _USE_HISTORY
+			hist_search (pThis, _HIST_UP);
+#endif
+			return 1;
+		} else if (ch == 'B') {
+#ifdef _USE_HISTORY
+			hist_search (pThis, _HIST_DOWN);
+#endif
+			return 1;
+		} else if (ch == 'C') {
+			if (pThis->cursor < pThis->cmdlen) {
+				terminal_move_cursor (pThis, 1);
+				pThis->cursor++;
+			}
+			return 1;
+		} else if (ch == 'D') {
+			if (pThis->cursor > 0) {
+				terminal_move_cursor (pThis, -1);
+				pThis->cursor--;
+			}
+			return 1;
+		} else if (ch == '7') {
+			pThis->escape_seq = _ESC_HOME;
+			return 0;
+		} else if (ch == '8') {
+			pThis->escape_seq = _ESC_END;
+			return 0;
+		} 
+	} else if (ch == '~') {
+		if (pThis->escape_seq == _ESC_HOME) {
+			terminal_reset_cursor (pThis);
+			pThis->cursor = 0;
+			return 1;
+		} else if (pThis->escape_seq == _ESC_END) {
+			terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
+			pThis->cursor = pThis->cmdlen;
+			return 1;
+		}
+	}
+
+	/* unknown escape sequence, stop */
+	return 1;
+}
+#endif
+
+//*****************************************************************************
+// insert len char of text at cursor position
+static int microrl_insert_text (microrl_t * pThis, char * text, int len)
+{
+	int i;
+	if (pThis->cmdlen + len < _COMMAND_LINE_LEN) {
+		memmove (pThis->cmdline + pThis->cursor + len,
+						 pThis->cmdline + pThis->cursor,
+						 pThis->cmdlen - pThis->cursor);
+		for (i = 0; i < len; i++) {
+			pThis->cmdline [pThis->cursor + i] = text [i];
+			if (pThis->cmdline [pThis->cursor + i] == ' ') {
+				pThis->cmdline [pThis->cursor + i] = 0;
+			}
+		}
+		pThis->cursor += len;
+		pThis->cmdlen += len;
+		pThis->cmdline [pThis->cmdlen] = '\0';
+		return true;
+	}
+	return false;
+}
+
+//*****************************************************************************
+// remove one char at cursor
+static void microrl_backspace (microrl_t * pThis)
+{
+	if (pThis->cursor > 0) {
+		terminal_backspace (pThis);
+		memmove (pThis->cmdline + pThis->cursor-1,
+						 pThis->cmdline + pThis->cursor,
+						 pThis->cmdlen-pThis->cursor+1);
+		pThis->cursor--;
+		pThis->cmdline [pThis->cmdlen] = '\0';
+		pThis->cmdlen--;
+	}
+}
+
+
+#ifdef _USE_COMPLETE
+
+//*****************************************************************************
+static int common_len (char ** arr)
+{
+	int i;
+	int j;
+	char *shortest = arr[0];
+	int shortlen = strlen(shortest);
+
+	for (i = 0; arr[i] != NULL; ++i)
+		if (strlen(arr[i]) < shortlen) {
+			shortest = arr[i];
+			shortlen = strlen(shortest);
+		}
+
+	for (i = 0; i < shortlen; ++i)
+		for (j = 0; arr[j] != 0; ++j)
+			if (shortest[i] != arr[j][i])
+				return i;
+
+	return i;
+}
+
+//*****************************************************************************
+static void microrl_get_complite (microrl_t * pThis) 
+{
+	char const * tkn_arr[_COMMAND_TOKEN_NMB];
+	char ** compl_token; 
+	
+	if (pThis->get_completion == NULL) // callback was not set
+		return;
+	
+	int status = split (pThis, pThis->cursor, tkn_arr);
+	if (pThis->cmdline[pThis->cursor-1] == '\0')
+		tkn_arr[status++] = "";
+	compl_token = pThis->get_completion (status, tkn_arr);
+	if (compl_token[0] != NULL) {
+		int i = 0;
+		int len;
+
+		if (compl_token[1] == NULL) {
+			len = strlen (compl_token[0]);
+		} else {
+			len = common_len (compl_token);
+			terminal_newline (pThis);
+			while (compl_token [i] != NULL) {
+				pThis->print (compl_token[i]);
+				pThis->print (" ");
+				i++;
+			}
+			terminal_newline (pThis);
+			print_prompt (pThis);
+		}
+		
+		if (len) {
+			microrl_insert_text (pThis, compl_token[0] + strlen(tkn_arr[status-1]), 
+																	len - strlen(tkn_arr[status-1]));
+			if (compl_token[1] == NULL) 
+				microrl_insert_text (pThis, " ", 1);
+		}
+		terminal_reset_cursor (pThis);
+		terminal_print_line (pThis, 0, pThis->cursor);
+	} 
+}
+#endif
+
+//*****************************************************************************
+void new_line_handler(microrl_t * pThis){
+	char const * tkn_arr [_COMMAND_TOKEN_NMB];
+	int status;
+
+	terminal_newline (pThis);
+#ifdef _USE_HISTORY
+	if (pThis->cmdlen > 0)
+		hist_save_line (&pThis->ring_hist, pThis->cmdline, pThis->cmdlen);
+#endif
+	status = split (pThis, pThis->cmdlen, tkn_arr);
+	if (status == -1){
+		//          pThis->print ("ERROR: Max token amount exseed\n");
+		pThis->print ("ERROR:too many tokens");
+		pThis->print (ENDL);
+	}
+	if ((status > 0) && (pThis->execute != NULL))
+		pThis->execute (status, tkn_arr);
+	print_prompt (pThis);
+	pThis->cmdlen = 0;
+	pThis->cursor = 0;
+	memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
+#ifdef _USE_HISTORY
+	pThis->ring_hist.cur = 0;
+#endif
+}
+
+//*****************************************************************************
+
+void microrl_insert_char (microrl_t * pThis, int ch)
+{
+#ifdef _USE_ESC_SEQ
+	if (pThis->escape) {
+		if (escape_process(pThis, ch))
+			pThis->escape = 0;
+	} else {
+#endif
+		switch (ch) {
+			//-----------------------------------------------------
+#ifdef _ENDL_CR
+			case KEY_CR:
+				new_line_handler(pThis);
+			break;
+			case KEY_LF:
+			break;
+#elif defined(_ENDL_CRLF)
+			case KEY_CR:
+				pThis->tmpch = KEY_CR;
+			break;
+			case KEY_LF:
+			if (pThis->tmpch == KEY_CR)
+				new_line_handler(pThis);
+			break;
+#elif defined(_ENDL_LFCR)
+			case KEY_LF:
+				pThis->tmpch = KEY_LF;
+			break;
+			case KEY_CR:
+			if (pThis->tmpch == KEY_LF)
+				new_line_handler(pThis);
+			break;
+#else
+			case KEY_CR:
+			break;
+			case KEY_LF:
+				new_line_handler(pThis);
+			break;
+#endif
+			//-----------------------------------------------------
+#ifdef _USE_COMPLETE
+			case KEY_HT:
+				microrl_get_complite (pThis);
+			break;
+#endif
+			//-----------------------------------------------------
+			case KEY_ESC:
+#ifdef _USE_ESC_SEQ
+				pThis->escape = 1;
+#endif
+			break;
+			//-----------------------------------------------------
+			case KEY_NAK: // ^U
+					while (pThis->cursor > 0) {
+					microrl_backspace (pThis);
+				}
+				terminal_print_line (pThis, 0, pThis->cursor);
+			break;
+			//-----------------------------------------------------
+			case KEY_VT:  // ^K
+				pThis->print ("\033[K");
+				pThis->cmdlen = pThis->cursor;
+			break;
+			//-----------------------------------------------------
+			case KEY_ENQ: // ^E
+				terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
+				pThis->cursor = pThis->cmdlen;
+			break;
+			//-----------------------------------------------------
+			case KEY_SOH: // ^A
+				terminal_reset_cursor (pThis);
+				pThis->cursor = 0;
+			break;
+			//-----------------------------------------------------
+			case KEY_ACK: // ^F
+			if (pThis->cursor < pThis->cmdlen) {
+				terminal_move_cursor (pThis, 1);
+				pThis->cursor++;
+			}
+			break;
+			//-----------------------------------------------------
+			case KEY_STX: // ^B
+			if (pThis->cursor) {
+				terminal_move_cursor (pThis, -1);
+				pThis->cursor--;
+			}
+			break;
+			//-----------------------------------------------------
+			case KEY_DLE: //^P
+#ifdef _USE_HISTORY
+			hist_search (pThis, _HIST_UP);
+#endif
+			break;
+			//-----------------------------------------------------
+			case KEY_SO: //^N
+#ifdef _USE_HISTORY
+			hist_search (pThis, _HIST_DOWN);
+#endif
+			break;
+			//-----------------------------------------------------
+			case KEY_DEL: // Backspace
+			case KEY_BS: // ^U
+				microrl_backspace (pThis);
+				terminal_print_line (pThis, pThis->cursor, pThis->cursor);
+			break;
+#ifdef _USE_CTLR_C
+			case KEY_ETX:
+			if (pThis->sigint != NULL)
+				pThis->sigint();
+			break;
+#endif
+			//-----------------------------------------------------
+			default:
+			if (((ch == ' ') && (pThis->cmdlen == 0)) || IS_CONTROL_CHAR(ch))
+				break;
+			if (microrl_insert_text (pThis, (char*)&ch, 1))
+				terminal_print_line (pThis, pThis->cursor-1, pThis->cursor);
+			
+			break;
+		}
+#ifdef _USE_ESC_SEQ
+	}
+#endif
+}

+ 128 - 0
thirdparty_libs/microrl/microrl.h

@@ -0,0 +1,128 @@
+#ifndef _MICRORL_H_
+#define _MICRORL_H_
+
+#include "MicroRLConfig.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#define true  1
+#define false 0
+
+ /* define the Key codes */
+#define KEY_NUL 0 /**< ^@ Null character */
+#define KEY_SOH 1 /**< ^A Start of heading, = console interrupt */
+#define KEY_STX 2 /**< ^B Start of text, maintenance mode on HP console */
+#define KEY_ETX 3 /**< ^C End of text */
+#define KEY_EOT 4 /**< ^D End of transmission, not the same as ETB */
+#define KEY_ENQ 5 /**< ^E Enquiry, goes with ACK; old HP flow control */
+#define KEY_ACK 6 /**< ^F Acknowledge, clears ENQ logon hand */
+#define KEY_BEL 7 /**< ^G Bell, rings the bell... */
+#define KEY_BS  8 /**< ^H Backspace, works on HP terminals/computers */
+#define KEY_HT  9 /**< ^I Horizontal tab, move to next tab stop */
+#define KEY_LF  10  /**< ^J Line Feed */
+#define KEY_VT  11  /**< ^K Vertical tab */
+#define KEY_FF  12  /**< ^L Form Feed, page eject */
+#define KEY_CR  13  /**< ^M Carriage Return*/
+#define KEY_SO  14  /**< ^N Shift Out, alternate character set */
+#define KEY_SI  15  /**< ^O Shift In, resume defaultn character set */
+#define KEY_DLE 16  /**< ^P Data link escape */
+#define KEY_DC1 17  /**< ^Q XON, with XOFF to pause listings; "okay to send". */
+#define KEY_DC2 18  /**< ^R Device control 2, block-mode flow control */
+#define KEY_DC3 19  /**< ^S XOFF, with XON is TERM=18 flow control */
+#define KEY_DC4 20  /**< ^T Device control 4 */
+#define KEY_NAK 21  /**< ^U Negative acknowledge */
+#define KEY_SYN 22  /**< ^V Synchronous idle */
+#define KEY_ETB 23  /**< ^W End transmission block, not the same as EOT */
+#define KEY_CAN 24  /**< ^X Cancel line, MPE echoes !!! */
+#define KEY_EM  25  /**< ^Y End of medium, Control-Y interrupt */
+#define KEY_SUB 26  /**< ^Z Substitute */
+#define KEY_ESC 27  /**< ^[ Escape, next character is not echoed */
+#define KEY_FS  28  /**< ^\ File separator */
+#define KEY_GS  29  /**< ^] Group separator */
+#define KEY_RS  30  /**< ^^ Record separator, block-mode terminator */
+#define KEY_US  31  /**< ^_ Unit separator */
+
+#define KEY_DEL 127 /**< Delete (not a real control character...) */
+
+#define IS_CONTROL_CHAR(x) ((x)<=31)
+
+// direction of history navigation
+#define _HIST_UP   0
+#define _HIST_DOWN 1
+// esc seq internal codes
+#define _ESC_BRACKET  1
+#define _ESC_HOME     2
+#define _ESC_END      3
+
+#ifdef _USE_HISTORY
+// history struct, contain internal variable
+// history store in static ring buffer for memory saving
+typedef struct {
+	char ring_buf [_RING_HISTORY_LEN];
+	int begin;
+	int end;
+	int cur;
+} ring_history_t;
+#endif
+
+// microrl struct, contain internal library data
+typedef struct {
+#ifdef _USE_ESC_SEQ
+	char escape_seq;
+	char escape;
+#endif
+#if (defined(_ENDL_CRLF) || defined(_ENDL_LFCR))
+	char tmpch;
+#endif
+#ifdef _USE_HISTORY
+	ring_history_t ring_hist;          // history object
+#endif
+	char * prompt_str;                 // pointer to prompt string
+	char cmdline [_COMMAND_LINE_LEN];  // cmdline buffer
+	int cmdlen;                        // last position in command line
+	int cursor;                        // input cursor
+	int (*execute) (int argc, const char * const * argv );            // ptr to 'execute' callback
+	char ** (*get_completion) (int argc, const char * const * argv ); // ptr to 'completion' callback
+	void (*print) (const char *);                                     // ptr to 'print' callback
+#ifdef _USE_CTLR_C
+	void (*sigint) (void);
+#endif
+} microrl_t;
+
+// init internal data, calls once at start up
+void microrl_init (microrl_t * pThis, void (*print)(const char*));
+
+// set echo mode (true/false), using for disabling echo for password input
+// echo mode will enabled after user press Enter.
+void microrl_set_echo (int);
+
+// set pointer to callback complition func, that called when user press 'Tab'
+// callback func description:
+//   param: argc - argument count, argv - pointer array to token string
+//   must return NULL-terminated string, contain complite variant splitted by 'Whitespace'
+//   If complite token found, it's must contain only one token to be complitted
+//   Empty string if complite not found, and multiple string if there are some token
+void microrl_set_complete_callback (microrl_t * pThis, char ** (*get_completion)(int, const char* const*));
+
+// pointer to callback func, that called when user press 'Enter'
+// execute func param: argc - argument count, argv - pointer array to token string
+void microrl_set_execute_callback (microrl_t * pThis, int (*execute)(int, const char* const*));
+
+// set callback for Ctrl+C terminal signal
+#ifdef _USE_CTLR_C
+void microrl_set_sigint_callback (microrl_t * pThis, void (*sigintf)(void));
+#endif
+
+// insert char to cmdline (for example call in usart RX interrupt)
+void microrl_insert_char (microrl_t * pThis, int ch);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+
+#endif

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov