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.

This discussion is locked. Please start a new topic to ask your question.
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
Principal

Where is the rest of the code uses g_iCount?

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.
CAN Jammer an open source CAN bus hacking tool
CANableV3 Open Source

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.