[질문/해결완료] configUSE_IDLE_HOOK를 1로 설정시 기존 task printf 문 동작 불가능
freertosconfig.h에서 configUSE_IDLE_HOOK를 1로 설정하면 vApplicationIdleHook() 정상적으로 호출되지만,
기존 task에서 printf로 출력한 string이 uart를 통해서 출력되지 않습니다.
기존 task1 및 2에 break point를 설정하고 동작시켜본 결과, task switching을 정상적으로 수행되는것은 확인했습니다.
이유가 뭘까요?
우측의 expression에는 각 task에서 1씩 증가한 전역변수 값인데 정상적으로 증가하면서 동작하고 있습니다.

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

반영한 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);
}
}
만약에 포팅을 할때 1년에 한번 잡는 치명적인 문제를 해결하는 코드가 들어갔다고 가정하면
0
57
2
STM32 포팅할 때 STM32 Project가 없음
0
148
2
FreeRTOS 멀티코어 지원안됨?
0
83
2
[소스코드 분석-configUSE_TIME_SLICING] TASK1,2의 우선순위가 동일할 때, configUSE_TIME_SLICING값 변경에 따른 출력 변화
0
82
2
포팅 부탁드립니다!
0
57
1
포팅 부탁드립니다. <NUCLEO-G071RB>
0
64
2
상호배제 후 되지를 않아서 질문드립니다.
0
60
1
수료증 발급 기준 수정 요청
1
69
1
재진입가능여부에 관한 질문
1
66
1
01_TASKMAN프로젝트 디버깅 모드 실패
1
76
2
그러면 malloc/free가 아닌 동적할당자를 써서 메모리를 할당했기떄문에
1
69
2
실행순서
1
74
2
uart 전송중에는 스위칭이 금지되나요?
1
71
2
스택오버플로우 실습 중 stack size 설정 질문
0
79
2
포팅 원합니다.
2
75
2
코루틴 실습질문
1
99
2
TODO 2번 문제
1
140
4
10. 선점형 커널 그림 설명중 우선순위가 반대인 경우에도 Task B가 먼저 수행되나요?
1
80
2
디버거모드에 진입이 안됩니다.
0
175
2
prvExampleTaskHook 함수 호출 부분에 대해 문의드립니다.
0
119
2
보드 STM32H735IG와 강의 호환 여부 문의
1
151
3
[ L152RE ] 원샷 소프트타이머 실행 잘 되시나요?
1
157
2
Deferred Interrupt Processing 샘플 예제 문의 드립니다.
1
119
2
포팅 서비스 부탁드립니다
1
122
2

