인프런 커뮤니티 질문&답변

chucky2님의 프로필 이미지
chucky2

작성한 질문수

FreeRTOS 프로그래밍

소스코드 분석-configUSE_IDLE_HOOK

[질문/해결완료] configUSE_IDLE_HOOK를 1로 설정시 기존 task printf 문 동작 불가능

해결된 질문

작성

·

310

1

freertosconfig.h에서 configUSE_IDLE_HOOK를 1로 설정하면 vApplicationIdleHook() 정상적으로 호출되지만,

기존 task에서 printf로 출력한 string이 uart를 통해서 출력되지 않습니다.

기존 task1 및 2에 break point를 설정하고 동작시켜본 결과, task switching을 정상적으로 수행되는것은 확인했습니다.

이유가 뭘까요?

우측의 expression에는 각 task에서 1씩 증가한 전역변수 값인데 정상적으로 증가하면서 동작하고 있습니다.

답변 2

0

chucky2님의 프로필 이미지
chucky2
질문자

idle hook 함수에서 출력량을 줄여주었더니 아래와 같이 정상 동작합니다.

image

반영한 source:

void vApplicationIdleHook (void)
{
#if (defined (cms_enable_print_at_idel_hook) && ( cms_enable_print_at_idel_hook == 1))
	printf("T1 %d, T2 %d, T3 %d, Idle %d\n", task1timer, task2timer, task3timer, idletimer);
#else
    if(idletimer % 100000 == 0)
    {
        printf("."); fflush(stdout);
    }
    idletimer++;
#endif
}

0

홍영기님의 프로필 이미지
홍영기
지식공유자

안녕하세요. chucky2님!

모두 화면에 출력되었지만, 압도적인? printf(".") 출력량 때문에 다른 내용들은 가려서 보이지 않았을 겁니다. 아래 코드를 참고하여 테스트 해보시고 결과를 알려주세요.

void vApplicationIdleHook (void)
{
	idletimer++;
	if(idletimer % 1000 == 0)
	{
		printf("."); fflush(stdout);
	}
}

 

혹시 필요하실지 몰라 전체 소스(task.c)를 올려드립니다.

/*
 * task.c
 *
 *  Created on: Dec 22, 2020
 *      Author: admin
 */

/* FreeRTOS.org includes. */
#include "main.h"
#include "cmsis_os.h"
#include <stdio.h>

//#define CMSIS_OS

/* task's priority */
#define TASK_MAIN_PRIO	20
#define TASK_1_PRIO		10
#define TASK_2_PRIO		 9
#define TASK_3_PRIO		 8

struct Param_types {	/* struct for parameter passing to task */
       char *msg;
       int  P1,P2;
} Param_Tbl;

/* The task functions. */
static void TaskMain( void const *pvParameters );
static void Task1( void const *pvParameters );
static void Task2( const struct Param_types *Param );
static void Task3( const struct Param_types *Param );

#ifdef CMSIS_OS
osThreadId defaultTaskHandle;
osThreadId xHandleMain, xHandle1, xHandle2, xHandle3;
#else
TaskHandle_t xHandleMain, xHandle1, xHandle2, xHandle3;
#endif

int	task1timer, task2timer, task3timer, idletimer;

/*-----------------------------------------------------------*/

void USER_THREADS( void )
{

	/* Setup the hardware for use with the Beagleboard. */
	//prvSetupHardware();
#ifdef CMSIS_OS
	osThreadDef(defaultTask, TaskMain, osPriorityHigh, 0, 256);
	defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
#else
	/* Create one of the two tasks. */
	xTaskCreate(	(TaskFunction_t)TaskMain,		/* Pointer to the function that implements the task. */
					"TaskMain",	/* Text name for the task.  This is to facilitate debugging only. */
					256,		/* Stack depth - most small microcontrollers will use much less stack than this. */
					NULL,		/* We are not using the task parameter. */
					TASK_MAIN_PRIO,	/* This task will run at this priority */
					&xHandleMain );		/* We are not using the task handle. */
#endif
}

static void TaskMain( void const *pvParameters )
{
	const char *pcTaskName = "TaskMain";
	struct Param_types *Param;

	pvParameters = pvParameters; // for compiler warning

	/* Print out the name of this task. */
	printf( "%s is running\r\n", pcTaskName );

	// TASK CREATE
	/* TODO #1:
		Task1을 생성
		use 'xTaskCreate' */
#ifdef CMSIS_OS
	osThreadDef(Task1, Task1, osPriorityNormal, 0, 256);
	xHandle1 = osThreadCreate(osThread(Task1), NULL);
#else
	/* Create the other task in exactly the same way. */
	xTaskCreate(	(TaskFunction_t)Task1,		/* Pointer to the function that implements the task. */
					"Task1",	/* Text name for the task.  This is to facilitate debugging only. */
					256,		/* Stack depth - most small microcontrollers will use much less stack than this. */
					NULL,		/* We are not using the task parameter. */
					TASK_1_PRIO,	/* This task will run at this priority */
					&xHandle1 );		/* We are not using the task handle. */
#endif // TODO #1

	/* Create the other task in exactly the same way. */
	Param = &Param_Tbl;		/* get parameter tbl addr */
	Param->P1 = 111111;		/* set parameter */
	Param->P2 = 222222;
#ifdef CMSIS_OS
	osThreadDef(Task2, (void const *)Task2, osPriorityBelowNormal, 0, 256);
	xHandle2 = osThreadCreate (osThread(Task2), (void*)Param);
#else
	xTaskCreate( (TaskFunction_t)Task2, "Task2", 128, (void*)Param, TASK_2_PRIO, &xHandle2 );
#endif

#ifdef CMSIS_OS
	osThreadDef(Task3, (void const *)Task3, osPriorityBelowNormal, 0, 256);
	xHandle3 = osThreadCreate (osThread(Task3), (void*)Param);
#else
	xTaskCreate( (TaskFunction_t)Task3, "Task3", 128, (void*)Param, TASK_3_PRIO, &xHandle3 );
#endif

	/* TODO #2:
		Task1을 중지
		use 'vTaskSuspend' */
#if 0
	vTaskSuspend (xHandle1);
#endif // TODO #2

	/* TODO #4:
		Task1의 우선 순위를 'TASK_3_PRIO' 으로 변경
		use 'vTaskPrioritySet' and 'vTaskResume' */
#if 0
	vTaskPrioritySet (xHandle1, TASK_3_PRIO); // vTaskPrioritySet (NULL, 1);
	vTaskResume (xHandle1);
#endif // TODO #4

	/* delete self task */
	vTaskDelete (xHandleMain);	// vTaskDelete (NULL);
}

static void Task1( void const *pvParameters )
{
	const char *pcTaskName = "Task1";

	pvParameters = pvParameters; // for compiler warning

	/* Print out the name of this task. */
	printf( "%s is running\n", pcTaskName );

	printf("\n-------  Task1 information -------\n");
	printf("task1 name = %s \n",pcTaskGetName( xHandle1 ));
	printf("task1 priority = %d \n",(int)uxTaskPriorityGet( xHandle1 ));
//	printf("task1 status = %d \n",eTaskGetState( xHandle1 ));
	printf("----------------------------------\n");

	while(1) {
	/* TODO #3:
		코드를 실행 하여 보고
		vTaskDelay() 코드를 주석 처리한 후 그 결과를 설명한다 */
#if 1 // No comment
vTaskDelay (pdMS_TO_TICKS (1000));
printf("a"); fflush(stdout);	// 문자 'a' 출력
#endif // TODO #3

		task1timer++;
	}
}

static void Task2( const struct Param_types *Param )
{
	const char *pcTaskName = "Task2";

	/* Print out the name of this task. */
	printf( "%s is running\n", pcTaskName );

	printf("\n-------  Task2 parameter passed from main --------\n");
	printf("task2 first parameter = %d \n",Param->P1);
	printf("task2 second parameter = %d \n",Param->P2);
	printf("--------------------------------------------------\n");

	while(1) {
	/* TODO #3:
		코드를 실행 하여 보고
		vTaskDelay() 코드를 주석 처리한 후 그 결과를 설명한다 */
#if 1 // No comment
vTaskDelay (pdMS_TO_TICKS (1000));
//printf("b"); fflush(stdout);	// 문자 'b' 출력
printf("T1 %d, T2 %d, T3 %d, Idle %d\n", task1timer, task2timer, task3timer, idletimer);
#endif // TODO #3

		task2timer++;
	}
}

static void Task3( const struct Param_types *Param)
{
	while(1)
	{
		vTaskDelay(pdMS_TO_TICKS(5000));
		printf("T1 %d, T2 %d, T3 %d, Idle %d\n", task1timer, task2timer, task3timer, idletimer);
		fflush(stdout);
		task3timer++;
	}
}

/*-----------------------------------------------------------*/

void vApplicationIdleHook (void)
{
	idletimer++;
	if(idletimer % 1000 == 0)
	{
		printf("."); fflush(stdout);
	}
}

 

chucky2님의 프로필 이미지
chucky2

작성한 질문수

질문하기