Skip to main content
Visitor II
March 13, 2023
Solved

FreeRTOS + UART Strange Behavior

  • March 13, 2023
  • 1 reply
  • 1513 views

Hi, I'm trying to practice FreeRTOS with my STM32F769I-Eval kit.

I made two task with different priority and print global variable with semaphore.

When I run my code, terminal print decreased value every time.

0693W00000aIn9qQAC.png 

I don't know why. Here is my code.

int main(void)
{
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
 
 /* MPU Configuration--------------------------------------------------------*/
 MPU_Config();
 
 /* 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_USART1_UART_Init();
 /* USER CODE BEGIN 2 */
 
 /* USER CODE END 2 */
 
 /* USER CODE BEGIN RTOS_MUTEX */
 /* add mutexes, ... */
 /* USER CODE END RTOS_MUTEX */
 
 /* Create the semaphores(s) */
 /* definition and creation of mySemaphore */
 osSemaphoreDef(mySemaphore);
 mySemaphoreHandle = osSemaphoreCreate(osSemaphore(mySemaphore), 1);
 
 /* 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 queue(s) */
 /* definition and creation of myQueue */
 osMessageQDef(myQueue, 16, uint16_t);
 myQueueHandle = osMessageCreate(osMessageQ(myQueue), NULL);
 
 /* 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);
 
 /* definition and creation of myTestTask01 */
 osThreadDef(myTestTask01, StartTask02, osPriorityLow, 0, 128);
 myTestTask01Handle = osThreadCreate(osThread(myTestTask01), (void *)mySemaphoreHandle);
 
 /* definition and creation of myTestTask02 */
 osThreadDef(myTestTask02, StartTask03, osPriorityIdle, 0, 128);
 myTestTask02Handle = osThreadCreate(osThread(myTestTask02), (void *)mySemaphoreHandle);
 
 /* 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 */
}
void StartTask02(void const * argument)
{
 /* USER CODE BEGIN StartTask02 */
 char buf[256];
 osSemaphoreId semaphore = (osSemaphoreId)argument;
 /* Infinite loop */
 for(;;)
 {
 if(semaphore != NULL)
 {
 if(osSemaphoreWait(semaphore, osWaitForever) == osOK)
 {
 sprintf(buf, "Task02! : %d\r\n", g_iCount);
 HAL_UART_Transmit(&huart1, (uint8_t*)buf, strlen(buf), 100);
 
 osSemaphoreRelease(semaphore);
 }
 
 osDelay(500); 
 }
 }
 /* USER CODE END StartTask02 */
}
 
/* USER CODE BEGIN Header_StartTask03 */
/**
* @brief Function implementing the myTestTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask03 */
void StartTask03(void const * argument)
{
 /* USER CODE BEGIN StartTask03 */
 char buf[256];
 osSemaphoreId semaphore = (osSemaphoreId)argument;
 /* Infinite loop */
 for(;;)
 {
 if(semaphore != NULL)
 {
 if(osSemaphoreWait(semaphore, osWaitForever) == osOK)
 {
 sprintf(buf, "Task03! : %d\r\n", g_iCount);
 HAL_UART_Transmit(&huart1, (uint8_t*)buf, strlen(buf), 100);
 
 
 osSemaphoreRelease(semaphore);
 }
 osDelay(500);
 }
 }
 /* USER CODE END StartTask03 */
}

Please let me know why this starnge behavior happen.

Thanks.

    This topic has been closed for replies.
    Best answer by hs2

    The task stack size of only 128 is probably too small. Especially because you’re using printf-family functions usually requiring much more stack.

    You really should enable FreeRTOS stack checking and define configASSERT for development.

    1 reply

    Graduate II
    March 14, 2023

    Where is the rest of the code uses g_iCount?

    ELee.9Author
    Visitor II
    March 14, 2023

    Sorry, I didn't place my code. But I found the answer myself. I set the value to 0 in main instead out of main function. ​

    __IO int g_iCount;
    /* USER CODE END PV */
     
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MPU_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART1_UART_Init(void);
    void StartDefaultTask(void const * argument);
    void StartTask02(void const * argument);
    void StartTask03(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 */
     
     /* MPU Configuration--------------------------------------------------------*/
     MPU_Config();
     
     /* 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 */
     g_iCount = 0;
     /* USER CODE END SysInit */
     
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_USART1_UART_Init();
     /* USER CODE BEGIN 2 */
     
     /* USER CODE END 2 */
     
     /* USER CODE BEGIN RTOS_MUTEX */
     /* add mutexes, ... */
     /* USER CODE END RTOS_MUTEX */
     
     /* Create the semaphores(s) */
     /* definition and creation of mySemaphore */
     osSemaphoreDef(mySemaphore);
     mySemaphoreHandle = osSemaphoreCreate(osSemaphore(mySemaphore), 1);
     
     /* 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 queue(s) */
     /* definition and creation of myQueue */
     osMessageQDef(myQueue, 16, uint16_t);
     myQueueHandle = osMessageCreate(osMessageQ(myQueue), NULL);
     
     /* 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);
     
     /* definition and creation of myTestTask01 */
     osThreadDef(myTestTask01, StartTask02, osPriorityLow, 0, 128);
     myTestTask01Handle = osThreadCreate(osThread(myTestTask01), (void *)mySemaphoreHandle);
     
     /* definition and creation of myTestTask02 */
     osThreadDef(myTestTask02, StartTask03, osPriorityIdle, 0, 128);
     myTestTask02Handle = osThreadCreate(osThread(myTestTask02), (void *)mySemaphoreHandle);
     
     /* 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 */
    }

    After set the value in main function, It works correctly.

    hs2Answer
    Visitor II
    March 14, 2023

    The task stack size of only 128 is probably too small. Especially because you’re using printf-family functions usually requiring much more stack.

    You really should enable FreeRTOS stack checking and define configASSERT for development.