ECE 471/571 STM32 FreeRTOS Example - Thread safe data processing with Mutex

In STM32CubeMX

  1. Initialize all peripherals with in default mode? - yes
  2. System Core
  3. enable UART3
  4. Middleware - enable FreeRTOS
  5. System Core Again

Adapt and compile a project

  1. Open Core/Src/main.c
  2. Update the following code fragment:
    /* USER CODE BEGIN 0 */
    signed portBASE_TYPE xSerialGetChar( char *pcRxedChar, TickType_t xBlockTime )
    {
        /* Get the next character from the buffer.  Return false if no characters
        are available, or arrive before xBlockTime expires. */
        if( xQueueReceive( uart3_rx_queueHandle, pcRxedChar, xBlockTime ) )
        {
            return pdTRUE;
        } else {
            return pdFALSE;
        }
    }
    
    signed portBASE_TYPE xSerialPutChar( char cOutChar, TickType_t xBlockTime )
    {
        signed portBASE_TYPE xReturn;
    
        if( xQueueSend( uart3_tx_queueHandle, &cOutChar, xBlockTime ) == pdPASS )
        {
            xReturn = pdPASS;
            __HAL_UART_ENABLE_IT(&huart3, UART_IT_TXE);
        } else {
            xReturn = pdFAIL;
        }
    
        return xReturn;
    }
    
    BaseType_t uart3_gets(char * str, BaseType_t len)
    {
        BaseType_t result = 0;
    
        while( xSemaphoreTake(uart3_rx_accessHandle, 1000 / portTICK_PERIOD_MS ) != pdTRUE )
          ; // wait up to forever for the mutex access
    
        while(len>0)
        {
            while( xSerialGetChar(str, 1000) != pdTRUE )
                ; // wait up to forever to receive a character
            if ( *str == '\n' ) {
                break;
            }
            --len;
            ++result;
            ++str;
        }
        *str = '\0'; // terminate the string instead of '\n'
    
        xSemaphoreGive(uart3_rx_accessHandle);
    
        return(result);
    }
    
    BaseType_t uart3_puts(const char * str)
    {
        BaseType_t result = 0;
    
        while( xSemaphoreTake(uart3_tx_accessHandle, 1000 / portTICK_PERIOD_MS ) != pdTRUE )
            ; // wait up to forever for the mutex access
    
        while( *str != '\0' ) {
            while( xSerialPutChar(*str, 1000) != pdTRUE )
                ; // wait up to forever to send a character
            ++result;
            ++str;
        }
    
        xSemaphoreGive(uart3_tx_accessHandle);
    
        return(result);
    }
    
    BaseType_t uart3_write(const void * buffer, BaseType_t len)
    {
        BaseType_t result = 0;
    
        while( xSemaphoreTake(uart3_tx_accessHandle, 1000 / portTICK_PERIOD_MS ) != pdTRUE )
            ; // wait up to forever for the mutex access
    
        while( len>0 ) {
            while( xSerialPutChar(* (char*)buffer, 1000 / portTICK_PERIOD_MS ) != pdTRUE )
                ; // wait up to forever to send a character
            --len;
            ++result;
            ++buffer;
        }
    
        xSemaphoreGive(uart3_tx_accessHandle);
    
        return(result);
    }
    /* USER CODE END 0 */
    
  3. Update the following code fragment:
      /* USER CODE BEGIN 2 */
      __HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);
      /* USER CODE END 2 */
    
  4. Update the following code fragment:
    void StartDefaultTask(void const * argument)
    {
      /* USER CODE BEGIN 5 */
          /* Infinite loop */
          for(;;)
          {
    
            osDelay(500);
          }
      /* USER CODE END 5 */ 
    }
    
  5. Update the following code fragment:
    void StartDefaultTask(void const * argument)
    {
      /* USER CODE BEGIN 5 */
          /* Infinite loop */
          for(;;)
          {
    
            osDelay(1000);
          }
      /* USER CODE END 5 */ 
    }
    
  6. Update the following code fragment:
    void task_process_send1(void const * argument)
    {
      /* USER CODE BEGIN task_process_send1 */
      /* Infinite loop */
      for(;;)
      {
        uart3_puts("++++");
      }
      /* USER CODE END task_process_send1 */
    }
    
  7. Update the following code fragment:
    void task_process_send2(void const * argument)
    {
      /* USER CODE BEGIN task_process_send2 */
      /* Infinite loop */
      for(;;)
      {
        uart3_puts("---");
      }
      /* USER CODE END task_process_send2 */
    }
    
  8. Update the following code fragment:
    void task_competing_process(void const * argument)
    {
      /* USER CODE BEGIN task_competing_process */
      /* Infinite loop */
      TickType_t xLastWakeTime = xTaskGetTickCount();
      for(;;)
      {
        xSerialPutChar('X', 1);
    	vTaskDelayUntil( &xLastWakeTime, (100 / portTICK_PERIOD_MS) );
      }
      /* USER CODE END task_competing_process */
    }
    
  1. Open Core/Inc/main.h
  2. Update the following code fragment:
    /* USER CODE BEGIN Includes */
    #include "cmsis_os.h"
    /* USER CODE END Includes */
    
  3. Update the following code fragment:
    /* USER CODE BEGIN EM */
    extern osMessageQId uart3_rx_queueHandle;
    extern osMessageQId uart3_tx_queueHandle;
    /* USER CODE END EM */
    
  1. Open Core/Src/stm32f7xx_it.c
  2. Update the following code fragment:
    void USART3_IRQHandler(void)
    {
      /* USER CODE BEGIN USART3_IRQn 0 */
      BaseType_t xSchedulerChanged = pdFALSE;
      uint8_t buffer;
    
      if( __HAL_UART_GET_IT( &huart3, UART_IT_TXE ) == SET )
      {
        /* The interrupt was caused by the THR becoming empty.  Are there any more characters to transmit? */
        if( xQueueReceiveFromISR(uart3_tx_queueHandle, &buffer, &xSchedulerChanged ) == pdTRUE )
        {
          /* A character was retrieved from the queue so can be sent to the THR now. */
          HAL_UART_Transmit(&huart3, &buffer, 1, 0);
        }
        else
        {
          __HAL_UART_DISABLE_IT( &huart3, UART_IT_TXE);
        }
      }
    
      HAL_StatusTypeDef status = HAL_UART_Receive(&huart3, &buffer, 1, 0); // we are inside an interrupt - timeout of 0!
      if ( HAL_OK == status ) {
        xQueueSendFromISR(uart3_rx_queueHandle, &buffer, &xSchedulerChanged);
      }
      portYIELD_FROM_ISR( xSchedulerChanged );
    
      /* USER CODE END USART3_IRQn 0 */
      HAL_UART_IRQHandler(&huart3);
      /* USER CODE BEGIN USART3_IRQn 1 */
    
      /* USER CODE END USART3_IRQn 1 */
    }
    

web site front local main page local list page general bookmarks software bookmarks go back copyright info