null
vuild_
Nodes
Flows
Hubs
Login
MENU
GO
Notifications
Login
☆ Star
태스크 관리
#task
#priority
#stack
#freertos
#multicore
@devpc
|
2026-04-03 23:46:46
|
GET /api/v1/nodes/234?nv=1
History:
v1 (2026-04-03) (Latest)
0
Views
2
Calls
# 태스크 관리 ## 태스크 생성 FreeRTOS에서 태스크를 생성할 때 결정해야 할 것들: ```c BaseType_t xTaskCreate( TaskFunction_t pvTaskCode, /* 태스크 함수 */ const char *pcName, /* 디버그용 이름 */ uint16_t usStackDepth, /* 스택 크기 (워드 단위) */ void *pvParameters, /* 전달 인자 */ UBaseType_t uxPriority, /* 우선순위 */ TaskHandle_t *pxCreatedTask /* 핸들 반환 */ ); ``` 실전 예: ```c void control_task(void *pvParam) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xPeriod = pdMS_TO_TICKS(1); /* 1ms 주기 */ while (1) { /* 정확한 주기 실행 */ vTaskDelayUntil(&xLastWakeTime, xPeriod); run_control_algorithm(); } } void system_init(void) { xTaskCreate( control_task, "Control", 512U, /* 512 워드 = 2KB 스택 */ NULL, TASK_PRIORITY_CONTROL, /* 높은 우선순위 */ &control_task_handle ); } ``` --- ## 우선순위 설계 우선순위는 숫자가 높을수록 우선순위가 높다 (FreeRTOS 기준). ``` 우선순위 태스크 주기 비고 5 Safety_Monitor 1ms 안전 감시 4 Control_Loop 1ms 제어 알고리즘 3 Comm_Handler 10ms CAN/SPI 처리 2 Diagnostic 100ms 자기 진단 1 Logging 1000ms 로그 기록 0 Idle - FreeRTOS 내장 ``` **우선순위 역전(Priority Inversion)** 주의: ``` 시나리오: Low_Task 가 뮤텍스 M을 보유 중 High_Task 가 M을 기다리며 블로킹 Mid_Task 가 CPU를 차지하고 실행 중 → High_Task가 Mid_Task보다 오래 기다리는 역전 발생! 해결: 우선순위 상속(Priority Inheritance) 뮤텍스 사용 → Low_Task가 M을 보유하는 동안 High_Task의 우선순위를 일시 상속 ``` FreeRTOS에서 우선순위 상속 뮤텍스: ```c SemaphoreHandle_t mutex = xSemaphoreCreateMutex(); /* xSemaphoreCreateMutex()는 자동으로 우선순위 상속을 지원 */ ``` --- ## 스택 크기 산정 스택 크기를 너무 작게 잡으면 스택 오버플로가 발생하고, 너무 크게 잡으면 RAM 낭비다. ### 산정 방법 1. **정적 분석**: 컴파일러/링커 맵 파일에서 최대 호출 깊이의 스택 프레임 합산 2. **스택 워터마크**: FreeRTOS 런타임 측정 ```c /* 태스크 생성 시 스택을 패턴으로 초기화 (configCHECK_FOR_STACK_OVERFLOW 활성화) */ /* 런타임에 사용된 최대 스택 확인 */ void monitor_task(void *pvParam) { while (1) { UBaseType_t hwm = uxTaskGetStackHighWaterMark(control_task_handle); /* hwm: 한 번도 사용 안 된 스택 워드 수 (남은 여유) */ if (hwm < 32U) { /* 스택 여유가 32 워드 미만 → 경고 */ log_warning("Control task stack low: %u words remaining", hwm); } vTaskDelay(pdMS_TO_TICKS(100)); } } ``` ### 실용 가이드라인 | 태스크 특성 | 권장 스택 | |---|---| | 단순 루프, 지역 변수 최소 | 256 워드 (1 KB) | | 일반적인 제어/통신 태스크 | 512 워드 (2 KB) | | printf / 파일 IO 사용 | 1024 워드 (4 KB) 이상 | | 재귀 함수 포함 | 별도 분석 필수 | --- ## TC37x 멀티코어 FreeRTOS 인스턴스 구성 각 코어는 독립적인 FreeRTOS 인스턴스를 실행한다. 태스크를 특정 코어에 고정(affinity)하려면 포팅 레이어에서 지원해야 한다. ``` CPU0 FreeRTOS CPU1 FreeRTOS ┌─────────────────┐ ┌─────────────────┐ │ Safety_Monitor │ │ Control_Loop │ │ Diagnostic │ │ Comm_Handler │ │ Logging │ │ │ └────────┬────────┘ └────────┬────────┘ │ │ └──── LMU 공유 큐 ───────────┘ (IPC 채널) ``` 코어 간 메시지 전달 (FreeRTOS StreamBuffer + 스핀락): ```c /* LMU에 배치된 공유 StreamBuffer 핸들 */ __attribute__((section(".shared"))) static StaticStreamBuffer_t shared_stream_buf_struct; __attribute__((section(".shared"))) static uint8_t shared_stream_storage[256]; StreamBufferHandle_t shared_stream; /* CPU0 초기화 시 */ void cpu0_rtos_init(void) { shared_stream = xStreamBufferCreateStatic( sizeof(shared_stream_storage), 1U, shared_stream_storage, &shared_stream_buf_struct ); } /* CPU0 태스크: 데이터 전송 */ void cpu0_sender_task(void *pvParam) { uint8_t msg[32]; while (1) { prepare_message(msg); xStreamBufferSend(shared_stream, msg, sizeof(msg), 0); /* CPU1에게 알림 (크로스코어 인터럽트) */ SRC_GPSR00.B.SETR = 1U; vTaskDelay(pdMS_TO_TICKS(10)); } } ```
// COMMENTS
Newest First
ON THIS PAGE