cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS + UART Strange Behavior

ELee.9
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

4 REPLIES 4
Karl Yamashita
Lead III

Where is the rest of the code uses g_iCount?

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

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.

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.

Thanks for reply.

I changed the buf size to 32, it works perfectly.

Your answer was really perfect!

Super Thanks.