cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 + STM32CubeMX + CMSIS-RTOS

Duy Tran
Associate II

Hello,

I am using my STM32L4R5 with CMSIS RTOS generated from STM32CubeMX. I followed the example and I wrote a program that wakes the CPU up from sleep mode every time I press the button (external interrupt)

/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
 
/* USER CODE END Variables */
osThreadId TxTaskHandle;
osThreadId RxTaskHandle;
osMessageQId QueueHandle;
osSemaphoreId TxSemaphoreHandle;
 
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void SYSCLKConfig_STOP(); 
/* USER CODE END FunctionPrototypes */
 
void StartTxTask(void const * argument);
void StartRxTask(void const * argument);
 
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
 
/* Pre/Post sleep processing prototypes */
void PreSleepProcessing(uint32_t *ulExpectedIdleTime);
void PostSleepProcessing(uint32_t *ulExpectedIdleTime);
 
/* USER CODE BEGIN PREPOSTSLEEP */
void PreSleepProcessing(uint32_t *ulExpectedIdleTime)
{
  /* Called by the kernel before it places the MCU into a sleep mode because
  configPRE_SLEEP_PROCESSING() is #defined to PreSleepProcessing().
 
  NOTE:  Additional actions can be taken here to get the power consumption
  even lower.  For example, peripherals can be turned off here, and then back
  on again in the post sleep processing function.  For maximum power saving
  ensure all unused pins are in their lowest power state. */
  /* Turn OFF LED */
//  BSP_LED_Off(LED1);
//  BSP_LED_Off(LED2);
//  BSP_LED_Off(LED3);
//  BSP_LED_DeInit(LED1);
//  BSP_LED_DeInit(LED2);
//  BSP_LED_DeInit(LED3);
 
  /* 
    (*ulExpectedIdleTime) is set to 0 to indicate that PreSleepProcessing contains
    its own wait for interrupt or wait for event instruction and so the kernel vPortSuppressTicksAndSleep 
    function does not need to execute the wfi instruction  
  */    
  *ulExpectedIdleTime = 0;
  
  /*Enter to sleep Mode using the HAL function HAL_PWR_EnterSLEEPMode with WFI instruction*/
  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);  
//  HAL_PWREx_EnterSTOP2Mode(PWR_SLEEPENTRY_WFI);
//  SYSCLKConfig_STOP();
}
 
void PostSleepProcessing(uint32_t *ulExpectedIdleTime)
{
  /* Called by the kernel when the MCU exits a sleep mode because
  configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */
 
  /* Avoid compiler warnings about the unused parameter. */
  (void) ulExpectedIdleTime;
 
//  BSP_LED_Init(LED1);
//  BSP_LED_Init(LED2);
//  BSP_LED_Init(LED3);
//  BSP_LED_Toggle(LED2);
}
/* USER CODE END PREPOSTSLEEP */
 
/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
 
  osSemaphoreDef(TxSemaphore);
  TxSemaphoreHandle = osSemaphoreCreate(osSemaphore(TxSemaphore), 2);
 
  osThreadDef(TxTask, StartTxTask, osPriorityNormal, 0, 128);
  TxTaskHandle = osThreadCreate(osThread(TxTask), NULL);
 
  /* definition and creation of RxTask */
  osThreadDef(RxTask, StartRxTask, osPriorityAboveNormal, 0, 128);
  RxTaskHandle = osThreadCreate(osThread(RxTask), NULL);
 
  osMessageQDef(Queue, 16, uint32_t);
  QueueHandle = osMessageCreate(osMessageQ(Queue), NULL);
 
}
 
/* USER CODE BEGIN Header_StartTxTask */
/**
  * @brief  Function implementing the TxTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartTxTask */
void StartTxTask(void const * argument)
{
 
  /* USER CODE BEGIN StartTxTask */
  osEvent event;
  
  /* Infinite loop */
  for(;;)
  {
//    if (TxSemaphoreHandle != NULL)
//    {
//      if (osSemaphoreWait(TxSemaphoreHandle, osWaitForever) == osOK)
//      {
//         BSP_LED_Toggle(LED3);
//      }
//    }
    event = osSignalWait(TX_SIGNAL, osWaitForever);
    if (event.value.signals == TX_SIGNAL)
    {
//      BSP_LED_On(LED2);
//      osDelay(TX_DELAY);
//      BSP_LED_Off(LED2);
      
      osMessagePut(QueueHandle, (uint32_t)QUEUED_VALUE, 0);
    }
  }
  /* USER CODE END StartTxTask */
}
 
/* USER CODE BEGIN Header_StartRxTask */
/**
* @brief Function implementing the RxTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartRxTask */
void StartRxTask(void const * argument)
{
  /* USER CODE BEGIN StartRxTask */
  osEvent event;
  
  /* Infinite loop */
  for(;;)
  {
    /* Wait until something arrives in the queue. */
    event = osMessageGet(QueueHandle, osWaitForever);
    
    if (event.status == osEventMessage)
    {
      if (event.value.v == QUEUED_VALUE)
      {
        BSP_LED_On(LED1);
        osDelay(LED_TOGGLE_DELAY);
        BSP_LED_Off(LED1);
      }
    }
    
  }
  /* USER CODE END StartRxTask */
}
 
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/**
  * @brief  Configures system clock after wake-up from STOP: enable MSI, PLL
  *         and select PLL as system clock source.
  * @param  None
  * @retval None
  */
static void SYSCLKConfig_STOP(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  uint32_t pFLatency = 0;
 
  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();
 
  /* Get the Oscillators configuration according to the internal RCC registers */
  HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_NONE;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* Get the Clocks configuration according to the internal RCC registers */
  HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
 
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType     = RCC_CLOCKTYPE_SYSCLK;
  RCC_ClkInitStruct.SYSCLKSource  = RCC_SYSCLKSOURCE_PLLCLK;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief  EXTI line detection callback.
  * @param  GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
  if (GPIO_Pin == USER_BUTTON_PIN)
  {
//    SystemClock_Config();
//    osSemaphoreRelease(TxSemaphoreHandle);
//    BSP_LED_Init(LED1);
    osSignalSet(TxTaskHandle, TX_SIGNAL);
  }
}

The program runs well with this, but when I change into stop mode by changing some lines in function void PreSleepProcessing(uint32_t *ulExpectedIdleTime) and void PostSleepProcessing(uint32_t *ulExpectedIdleTime), the MCU cannot wake-up even I pressed the button. I know that I must have missed something during the configuration before entering stop mode. I couldn't find any further instruction about this. Can someone give me some instruction or explanation?

void PreSleepProcessing(uint32_t *ulExpectedIdleTime)
{
  /* Called by the kernel before it places the MCU into a sleep mode because
  configPRE_SLEEP_PROCESSING() is #defined to PreSleepProcessing().
 
  NOTE:  Additional actions can be taken here to get the power consumption
  even lower.  For example, peripherals can be turned off here, and then back
  on again in the post sleep processing function.  For maximum power saving
  ensure all unused pins are in their lowest power state. */
  /* Turn OFF LED */
  BSP_LED_Off(LED1);
  BSP_LED_Off(LED2);
  BSP_LED_Off(LED3);
  BSP_LED_DeInit(LED1);
  BSP_LED_DeInit(LED2);
  BSP_LED_DeInit(LED3);
 
  /* 
    (*ulExpectedIdleTime) is set to 0 to indicate that PreSleepProcessing contains
    its own wait for interrupt or wait for event instruction and so the kernel vPortSuppressTicksAndSleep 
    function does not need to execute the wfi instruction  
  */    
  *ulExpectedIdleTime = 0;
  
  /*Enter to sleep Mode using the HAL function HAL_PWR_EnterSLEEPMode with WFI instruction*/
//  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);  
  HAL_PWREx_EnterSTOP2Mode(PWR_SLEEPENTRY_WFI);
  SYSCLKConfig_STOP();
}
 
void PostSleepProcessing(uint32_t *ulExpectedIdleTime)
{
  /* Called by the kernel when the MCU exits a sleep mode because
  configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */
 
  /* Avoid compiler warnings about the unused parameter. */
  (void) ulExpectedIdleTime;
 
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);
  BSP_LED_Toggle(LED2);
}

Thank you every much.

Best regards,

Duy

0 REPLIES 0