목록2025/06 (89)
지노랩 /JinoLab
FreeRTOS 큐는 태스크 간 또는 ISR↔태스크 간 데이터를 주고받기 위한 강력한 도구입니다.이 글에서는 큐에서 데이터를 꺼낼 때 사용하는 두 가지 핵심 API—xQueueReceive() (큐에서 꺼내는 기본 함수)xQueuePeek() (큐 머리(Head) 내용을 확인만 하는 함수)—의 매개변수, 반환값, 동작 원리 및 실전 예제를 중심으로 자세히 설명합니다.1. 왜 데이터 수신 API가 중요한가?FIFO 통신문(First-In, First-Out)생산자(Producer) 태스크가 xQueueSendToBack() 또는 xQueueSendToFront()로 큐에 데이터를 넣으면,소비자(Consumer) 태스크가 xQueueReceive()를 통해 큐 머리(Head)에 쌓여 있는 데이터를 꺼내 처리..
FreeRTOS에서 **큐(Queue)**는 태스크 간 또는 ISR과 태스크 간 데이터를 주고받는 기본 메커니즘입니다.이 글에서는 큐에 데이터를 넣는 두 가지 주요 API—xQueueSendToFront()와 xQueueSendToBack()—를 왜, 언제, 어떻게 사용하는지를 “블로그 포스트” 스타일로 자세히 안내합니다. 각 매개변수의 의미부터 동작 원리, 예제 코드, 주의사항까지 빠짐없이 다룹니다.1. 큐에 데이터를 보내는 이유태스크 간 통신: 센서값, 명령, 로그 등을 생산자(Producer) 태스크가 큐에 넣으면 소비자(Consumer) 태스크가 꺼내 처리우선순위 조절:xQueueSendToBack(): 일반적인 “FIFO(First-In, First-Out)” 방식. 데이터가 큐의 끝(Tail)..
FreeRTOS에서 큐(Queue)는 태스크 간, 또 태스크와 ISR 간에 데이터를 안전하게 주고받기 위해 가장 기본이자 강력한 동기화 수단입니다. 이번 글에서는 큐를 **“어떻게 생성하는지”**에 초점을 맞추어, FreeRTOS의 xQueueCreate() API를 하나하나 해설하며, 실제 사용 예제까지 살펴보겠습니다.1. 큐를 왜 동적으로 생성하는가?FreeRTOS는 가벼운 RTOS이지만, “몇 개짜리 큐를 만들고, 아이템 하나는 몇 바이트인지” 미리 컴파일 타임에 알 수 없는 경우가 많습니다. 예를 들어:센서 개수가 OTA(Over-The-Air) 업데이트마다 바뀔 수 있다.데이터 구조체 형식이 프로젝트별로 달라진다.한 번에 몇 개의 데이터를 버퍼링해야 할지 런타임 중 결정되어야 한다.이럴 때 **..
임베디드 시스템에서 여러 태스크(Task)가 데이터를 안전하게 주고받는 방법은 여러 가지가 있습니다. 그중 가장 많이 사용되는 것이 바로 **큐(Queue)**입니다. 이 글에서는 FreeRTOS의 큐가 무엇이고, 어떤 특징을 가지며, 어떻게 생성·사용하는지를 자세히 살펴봅니다.1. 큐(Queue)란 무엇인가?**큐(Queue)**는 컴퓨터 공학에서 “FIFO(First In, First Out)” 구조를 구현한 자료구조입니다.입력(Enqueue): 큐의 끝(“tail”)에 데이터를 추가출력(Dequeue): 큐의 앞(“head”)에서 데이터를 제거만약 큐가 “영화관 매표소 앞의 줄”과 같다면, 가장 먼저 줄에 선 사람이 티켓을 먼저 받고 입장하는 것과 같습니다. [Head] ── 첫 번째 요소(데이..
LED 블링킹 예제(003 LED_Block_Tasks)에서 50 mA → ≈ 18 mA로!1. 문제: Block 지연으로 CPU 가 놀고 있다 🤦♂️vTaskDelay()를 써서 LED 를 토글하면, 각 태스크는 Blocked 로 빠지고 스케줄러는 Idle Task 를 실행합니다.Tracealyzer 로 보면 대부분의 시간(흰색)이 Idle Task 구간이죠.“Idle 동안 코어 클럭을 끄면 전력이 확 줄 텐데…?”2. 해결: Idle Hook 에서 Sleep 진입Idle Task 는 매 사이클 아래 과정을 거칩니다.내부 정리/클린업(TCB 반환 등)사용자 Hook 함수 호출 ➜ 여기서 저전력 진입!2-1. FreeRTOS 설정FreeRTOSConfig.h#define configUSE_IDLE_H..
Idle Hook, Tick Hook, Malloc-Failed Hook, Stack-Overflow Hook―언제 호출되고, 왜 필요할까?1. Hook Function이란?FreeRTOS 커널이 특정 이벤트(아이들 상태, RTOS 틱, 메모리 부족 등)를 감지했을 때 사용자가 미리 등록한 함수를 자동 호출해 주는 ‘콜백’ 메커니즘입니다.코어 수정 없이 애플리케이션 레벨에서 커널 동작을 확장별도 태스크를 만들지 않아 RAM·CPU 절약Hook 사용 여부는 FreeRTOSConfig.h 안의 configUSE_… 매크로로 스위치!2. Idle Task Hook항목 내용매크로configUSE_IDLE_HOOK (1 로 설정)함수 시그니처void vApplicationIdleHook(void);호출 시점모든 ..
FreeRTOS의 “ISR-Safe API” 완전 정복 가이드1. 두 개의 세계, 두 개의 규칙 구분Task Context (Thread Mode)Interrupt Context (Handler Mode)실행 시점스케줄러가 선택한 뒤 CPU에서 실행하드웨어 이벤트가 즉시 CPU를 점유가능 동작스케줄러에게 “나 잠시 Block 시켜” 요청 가능 (예: vTaskDelay(), xQueueReceive())Block 금지 — 인터럽트 루틴은 짧고 빠르게 끝나야 함API 이름일반 FreeRTOS API…FromISR() 접미사 API핵심: 인터럽트 안에서는 “Block 동작”이 불가능하다.따라서 동일 API를 공용으로 쓰면, 내부에서 “지금 Task냐 ISR이냐” 를 매번 분기해야 하고, 일부 파라미터가 무..
**configMAX_SYSCALL_INTERRUPT_PRIORITY(또는 configMAX_API_CALL_INTERRUPT_PRIORITY)**가 도대체 무슨 의미인지 헷갈리셨다면, 이 글로 한 방에 정리해 보세요!1. 왜 또 다른 우선순위 매크로가 있을까?FreeRTOS 커널은 SysTick / PendSV / SVC 같은 ‘커널 전용 인터럽트’를 가장 낮은 우선순위(예: 0xF0)로 고정해 둡니다.그러나 사용자 인터럽트(UART, ADC, TIM 등)는 상황에 따라 RTOS API를 호출해야 할 때가 있고, 또 어떤 ISR은 완전 실시간(순수 Bare-metal) 로 동작해야 하기도 합니다.그래서 “API를 부를 수 있는 ISR”와 “절대 부르면 안 되는 ISR” 간 경계값이 필요합니다.이 값이 ..
configKERNEL_INTERRUPT_PRIORITY와 configMAX_SYSCALL_INTERRUPT_PRIORITY― 이름도 길고 헷갈리는 이 두 매크로를 한번에 정리합니다.1. 왜 별도 설정이 필요할까?구분 목적 실행 컨텍스트커널 인터럽트(SysTick, PendSV, SVC)• RTOS 핵심 동작 – 틱 발생 – 컨텍스트 스위치 등Handler Mode애플리케이션 인터럽트(UART, ADC, TIM 등)• 사용자 코드(ISR)에서 FreeRTOS API 호출 가능Handler ModeFreeRTOS는 “커널 인터럽트는 가장 낮은 우선순위” 로,“사용자 ISR은 그보다 높되, 임계구역 보호를 위해 일정 범위 안” 에 있도록 규칙을 정해두었습니다.2. configKERNEL_INTERRUPT_P..
“값이 작으면 높은 건가? 낮은 건가?”RTOS를 처음 접하면 한 시스템 안에 ‘두 종류’의 우선순위가 존재한다는 사실이 꽤 혼란스럽습니다.이 글에서는 FreeRTOS 태스크 우선순위와 ARM Cortex-M 인터럽트 우선순위를 한눈에 비교해 정리합니다.1. RTOS 태스크 우선순위항목 설명대상태스크(Task) = 사용자 공간에서 실행되는 C 함수(스레드)실행 모드Thread Mode (비특권 또는 특권)스케줄러FreeRTOS 커널값의 의미숫자가 클수록 ‘더 높은(priority) 우선순위’예) pri 3 > pri 1범위0 ~ (configMAX_PRIORITIES – 1)📝 Tip : 같은 우선순위를 갖는 태스크는 Round-Robin(타임 슬라이스) 방식으로 CPU를 번갈아 사용합니다.2. 하드웨..
vTaskDelete() 한 방으로 끝! …이라고 생각했다가 메모리 누수·우선순위 문제를 겪지 않으셨나요?이번 글에서는 “언제‧어떻게” 태스크를 지워야 하는지, 그리고 “왜 안 지우는 편이 더 좋을 때가 많은지” 를 정리합니다.1. xTaskCreate() → RAM의 두 가지 소비구성 요소 어디에 저장? 역할TCB (Task Control Block)힙(Heap)우선순위, 상태(Ready/Blocked 등), 스택 포인터 등 ‘메타 데이터’개별 스택힙(Heap)태스크 로컬 변수·컨텍스트 저장즉, 태스크 수만큼 TCB + 스택 크기가 힙에서 빠져나갑니다.“지워주면 메모리 바로 돌아올까?” → NO!2. vTaskDelete()의 실체void vTaskDelete( TaskHandle_t xTaskToDe..
멀티태스킹이 즐비한 임베디드 세상에서 “데이터 꼬임”과 “경쟁 조건”을 막는 핵심 비법!1. 왜 ‘동기화( Synchronization )’가 필요할까?상황 문제 해결생산자–소비자센서 Task A가 데이터를 만들고, 표시 Task B가 소비B가 “언제” 데이터를 읽어야 할지 모름 → 폴링으로 CPU 낭비A가 이벤트/알림을 보내고 B는 대기(Block) 후 깨어남Task ↔️ ISR키 입력 ISR이 큐에 문자 저장, LCD Task가 표시큐가 비어있을 때 LCD Task가 계속 돌면 배터리 소모큐에 데이터 들어오면 ISR이 알림 → Task Ready결국 “필요할 때만 깨우자” 가 동기화의 핵심입니다.2. FreeRTOS가 제공하는 3종 세트객체 핵심 용도 특징Semaphore▪ Counting▪ Bina..
― TCB·스택·힙·heap_1~5.c까지 싹 정리 ―“Task를 만든 순간, TCB와 스택이 ‘힙’을 파먹는다.”임베디드 RAM 구조와 FreeRTOS 동적 메모리 전략을 확실히 잡아두세요!1. MCU RAM 속 ‘세 구역’ - 글로벌·STACK·HEAP┌─────────────────┐ High Addr│ Stack │ ← ① SP (Stack Pointer)│ (task마다 별도) │├─────────────────┤│ Heap │ ← ② pvPortMalloc 이 영역을 소비│ (커널 동적객체) │├─────────────────┤│ .bss / .data │ ← ③ 전역·static 변수└─────────────────┘ Low AddrSta..
“코드는 플래시에, 데이터는 램에,스택은 위에서, 힙은 아래에서!”1. MCU 메모리 두 축 — Flash vs. RAM구분 Flash (ROM) RAM (SRAM)용도- 펌웨어·상수(문자열, const) 저장- 인터럽트 벡터 테이블- 전역·정적 변수- 스택(지역 변수 등)- 힙(동적 메모리)특징전원 OFF 후에도 데이터 보존, 쓰기 느림휘발성, 읽기·쓰기 빠름크기 비율RAM 보다 여러 배 큼 (F401RE: 512 KB)Flash 대비 작음 (F401RE: 96 KB)2. RAM 내부 구조 한눈에 ▲ High Addr │ │ ┌──────────────┐ ← SP 초기값 │ │ Stack │ 함수 호출·지역변수 │ └──────────────┘ │ │..
― 임베디드 스택 구조를 5 분 만에 이해하기“FreeRTOS는 커널만 제공한다.나머지는 내가 붙인다!”1. 전체 그림 한눈에 보기┌────────────────────────────────────────┐│ Application ││ • Task 1 (센서 수집) ││ • Task 2 (통신) ││ • Task 3 (UI 업데이트) │└───────▲───────────────▲───────────────┘ │ FreeRTOS API │┌───────┴───────────────────────────────┐│ FreeRTOS ..
― 오픈소스 FreeRTOS vs. 상업용 OpenRTOS·SafeRTOS 한눈에 비교1. FreeRTOS(커뮤니티 버전) – 0원으로 쓰는 RTOS항목 내용가격 / 로열티완전 무료, 판매 수량과 무관하게 로열티 0원라이선스MIT → 기존 GPL+링커예외(과거 버전)보다 훨씬 느슨함 · 커널 수정분은 공개 의무(MIT 조건) · 응용코드(앱·드라이버)는 공개할 필요 없음기술지원공식 포럼·깃허브 이슈만 제공(유료 지원 無)안전규격(SIL/IEC 61508 등)인증 대상 아님 – 세이프티 필수 제품엔 부적합법적 보호(IP, 배상)제공 안 됨🔑 정리“일반 임베디드 제품”이라면 FreeRTOS만으로 충분.커널 쪽을 손봤다면 수정한 파일만 MIT 규정에 맞춰 공개하면 종료!2. SafeRTOS – IEC 615..
“세마포어·큐 없이도 1 사이클 만에 끝나는 가장 가벼운 IPC”1. Task Notification이 뭐길래?특징 설명초경량 IPC별도 커널 객체(세마포어, 큐) 생성 X → RAM, CPU 사용 최소1 Task = 1 Notification ValueTask 생성 시 0 으로 초기화되는 32-bit 변수 포함동시에 3가지 기능① 이벤트 통지 (Unblock) ② 값 전달(32-bit) ③ 비트플래그 동기화ISR 연동FromISR 전용 API 지원 → 인터럽트에서도 안전하게 전송🔖 핵심xTaskNotify() 로 보내고, xTaskNotifyWait() 로 받는다.옵션(eAction)에 따라 값을 덮어쓰거나, 1씩 증가하거나, 비트를 OR할 수 있다.2. API 한눈에 보기사용처 함수 주요 파라미터수..
FreeRTOS 입문하면 vTaskDelay() 만 줄줄 쓰다가“주기가 흐트러져요…😵” 라는 난관을 꼭 맞닥뜨립니다.두 API 차이와 활용 팁을 블로그 포스팅 포맷으로 깔끔히 정리해 봤습니다.1️⃣ 왜 ‘딜레이 API’를 써야 할까? 목적 기존 방법문제점RTOS식 해결CPU 비우기(for/while 지연 대체)HAL_Delay(), busy-wait100 % CPU 점유vTaskDelay()정확한 주기 유지(주기성 태스크)vTaskDelay() 남발실행 지점 ‘밀림’vTaskDelayUntil()2️⃣ vTaskDelay( ticks )“지금부터 n 틱 동안 잠깐 쉰다.”/* 500 ms 동안 Blocked 상태 진입 */vTaskDelay( pdMS_TO_TICKS(500) );입력값: RTOS Ti..
RTOS를 쓰다 보면“태스크가 안 돌아요…” “언제 깨어나는 거죠?” 같은 질문을 매번 하게 됩니다.이번 글에서는 가장 헷갈리는 BLOCKED 상태와 SUSPENDED 상태를 중심으로,Delay API·동기화 오브젝트까지 실전 위주로 정리했습니다.1. 4대 최상위(Task) 상태 복습상태 의미 전이(Transition)RunningCPU 독점 실행 중❌ (오직 1 개)Ready실행 조건 만족 ➜ CPU 할당만 대기▸ 스케줄러가 우선순위 기준 선택Blocked이벤트·시간·자원 을 기다리며 “잠시 쉼”▸ 이벤트/타임아웃 발생 → ReadySuspended사용자 호출로 ‘중단’ – 커널도 안 깨움▸ vTaskResume() 으로만 Ready포인트Blocked ↔ Ready 는 자동 전환Suspended ↔ R..
“내 태스크가 왜 안 돌지?”RTOS 디버깅에서 가장 먼저 확인해야 할 것은 현재 태스크의 상태입니다.이번 포스팅에서는 FreeRTOS(프리RTOS)를 기준으로 4 가지 최상위(Task) 상태와 전이(transition)를 한 번에 정리해 드립니다.0. 배경 지식용어 의미 기억 포인트태스크(Task)FreeRTOS가 스케줄링하는 실행 단위(=쓰레드)메모리: 전용 스택 + TCB(Task Control Block)스케줄러어떤 태스크를 CPU에 올릴지 결정Tick(타이머 인터럽트)마다 동작PSP / MSPProcess Stack / Main Stack 포인터• PSP → 각 태스크 전용 스택• MSP → 커널·인터럽트 스택1. Running – “CPU는 내 꺼!”단일 코어 MCU에서는 오직 하나의 태스크만..