text: /**
    ******************************************************************************
    * File Name          : main.c
    * Description        : Main program body
    ******************************************************************************
    * This notice applies to any and all portions of this file
    * that are not between comment pairs USER CODE BEGIN and
    * USER CODE END. Other portions of this file, whether 
    * inserted by the user or by software development tools
    * are owned by their respective copyright owners.
    *
    * Copyright (c) 2018 STMicroelectronics International N.V. 
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without 
    * modification, are permitted, provided that the following conditions are met:
    *
    * 1. Redistribution of source code must retain the above copyright notice, 
    *    this list of conditions and the following disclaimer.
    * 2. 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.
    * 3. Neither the name of STMicroelectronics nor the names of other 
    *    contributors to this software may be used to endorse or promote products 
    *    derived from this software without specific written permission.
    * 4. This software, including modifications and/or derivative works of this 
    *    software, must execute solely and exclusively on microcontroller or
    *    microprocessor devices manufactured by or for STMicroelectronics.
    * 5. Redistribution and use of this software other than as permitted under 
    *    this license is void and will automatically terminate your rights under 
    *    this license. 
    *
    * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
    * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
    * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
    * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
    * SHALL STMICROELECTRONICS OR 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.
    *
    ******************************************************************************
    */
  /* Includes ------------------------------------------------------------------*/
  #include "main.h"
  #include "stm32f1xx_hal.h"
  #include "cmsis_os.h"
  
  /* USER CODE BEGIN Includes */
  
  /* USER CODE END Includes */
  
  /* Private variables ---------------------------------------------------------*/
  
  /* USER CODE BEGIN PV */
  /* Private variables ---------------------------------------------------------*/
  osThreadId pb13BlinkerTaskHandle;
  osThreadId pb14BlinkerTaskHandle;
  
  typedef struct {
    GPIO_TypeDef *GPIOx;
    uint16_t GPIO_Pin;
    uint32_t delay;
  } BlinkerArgumens;
  
  BlinkerArgumens argsPB13 = {GPIOB, GPIO_PIN_13, 1000};
  BlinkerArgumens argsPB14 = {GPIOB, GPIO_PIN_14, 300};
  /* USER CODE END PV */
  
  /* Private function prototypes -----------------------------------------------*/
  void SystemClock_Config(void);
  static void MX_GPIO_Init(void);
  
  /* USER CODE BEGIN PFP */
  /* Private function prototypes -----------------------------------------------*/
  void StartBlinkerTask(void const * argument);
  /* USER CODE END PFP */
  
  /* USER CODE BEGIN 0 */
  
  /* USER CODE END 0 */
  
  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();
  
    /* 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 */
  
    /* Create the thread(s) */
    
    /* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
  	osThreadDef(blinkerTask, StartBlinkerTask, osPriorityNormal, 0, 128);
  	
  	pb13BlinkerTaskHandle = osThreadCreate(osThread(blinkerTask), &argsPB13);
    pb14BlinkerTaskHandle = osThreadCreate(osThread(blinkerTask), &argsPB14);
    /* USER CODE END RTOS_THREADS */
  
    /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    /* USER CODE END RTOS_QUEUES */
   
  
    /* 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 */
  
  }
  
  /** System Clock Configuration
  */
  void SystemClock_Config(void)
  {
  
    RCC_OscInitTypeDef RCC_OscInitStruct;
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
  
      /**Initializes the CPU, AHB and APB busses clocks 
      */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = 16;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
      /**Initializes the CPU, AHB and APB busses clocks 
      */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    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_0) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
      /**Configure the Systick interrupt time 
      */
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  
      /**Configure the Systick 
      */
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  
    /* SysTick_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
  }
  
  /** Configure pins as 
          * Analog 
          * Input 
          * Output
          * EVENT_OUT
          * EXTI
  */
  static void MX_GPIO_Init(void)
  {
  
    GPIO_InitTypeDef GPIO_InitStruct;
  
    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
  
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_RESET);
  
    /*Configure GPIO pins : PB13 PB14 */
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
  }
  
  /* USER CODE BEGIN 4 */
  void StartBlinkerTask(void const * argument)
  {
    const BlinkerArgumens * pArgumens = (const BlinkerArgumens *)argument;
    while(1)
    {
      HAL_GPIO_TogglePin(pArgumens->GPIOx, pArgumens->GPIO_Pin);
      osDelay(pArgumens->delay);
    }
  }
  /* USER CODE END 4 */
  
  
  /**
    * @brief  Period elapsed callback in non blocking mode
    * @note   This function is called  when TIM1 interrupt took place, inside
    * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
    * a global variable "uwTick" used as application time base.
    * @param  htim : TIM handle
    * @retval None
    */
  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  {
  /* USER CODE BEGIN Callback 0 */
  
  /* USER CODE END Callback 0 */
    if (htim->Instance == TIM1) {
      HAL_IncTick();
    }
  /* USER CODE BEGIN Callback 1 */
  
  /* USER CODE END Callback 1 */
  }
  
  /**
    * @brief  This function is executed in case of error occurrence.
    * @param  None
    * @retval None
    */
  void _Error_Handler(char * file, int line)
  {
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    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
  
  /**
    * @}
    */ 
  
  /**
    * @}
  */ 
  
  /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  