목록분류 전체보기 (312)
지노랩 /JinoLab
FreeRTOS에서는 여러 태스크가 서로 데이터를 주고받거나 작업 순서를 보장(동기화)해야 할 때, **세마포어(Semaphore)**를 자주 사용합니다. 특히 **이진 세마포어(Binary Semaphore)**는 “A 태스크가 데이터를 준비했을 때 B 태스크를 깨워서 처리하도록 한다”는 매우 대표적인 동기화 패턴을 간단히 구현할 수 있게 해줍니다. 본 글에서는 **“이진 세마포어를 사용해 두 태스크를 순차적으로 동기화하는 방법”**을 단계별로 살펴보겠습니다.1. 왜 동기화(Synchronization)가 필요한가?가령 다음과 같은 시나리오를 생각해 봅시다.Task 1(Producer): 센서에서 데이터를 읽어서 처리 결과(또는 가공 결과)를 준비한다.Task 2(Consumer): Task 1이 준비..
실시간 운영체제(RTOS)에서는 여러 태스크(Task)와 인터럽트(ISR)가 공유 자원(Resource)을 안전하게 사용하거나 이벤트를 신호(Signaling)하기 위해 **세마포어(Semaphore)**라는 커널 객체를 자주 사용합니다. FreeRTOS는 이 세마포어를 두 가지 주요 유형으로 제공합니다:Binary Semaphore (이진 세마포어)Counting Semaphore (카운팅 세마포어)본 글에서는 두 가지 세마포어의 특징과 용도를 정리하고, 실전 예시로 언제 어떻게 사용하면 좋을지 살펴보겠습니다.1. Binary Semaphore (이진 세마포어)1-1. 구조와 동작 원리값의 범위: 오직 0 또는 1 두 값만 가질 수 있습니다.값이 1일 때 → “세마포어 토큰(=열쇠)이 있다(Availa..
FreeRTOS를 사용하다 보면 “세마포어를 어떻게 생성하고, 내부적으로 어떤 정보가 관리되는가”가 궁금해질 때가 많습니다.이 글에서는 세마포어가 막 생성되었을 때 커널 내부에서 어떻게 관리되고, 각 태스크가 어떻게 대기·획득되는지 단계별로 살펴보겠습니다.1. 세마포어란 무엇인가?**세마포어(Semaphore)**는 여러 태스크(Task)나 ISR(Interrupt Service Routine)이“공유 자원(리소스)” 또는 “이벤트 신호”를 주고받으며 동기화(Synchronization) 또는 **상호 배제(Mutual Exclusion)**를 구현하게 하는 커널 객체입니다.FreeRTOS에서는 크게 두 종류의 세마포어를 지원합니다.Binary Semaphore (이진 세마포어)0 또는 1의 값만 가짐...
프로그램이 복수의 작업(스레드/태스크)을 동시에 수행하는 멀티태스킹 환경에서,여러 작업이 협력하여 원하는 결과를 올바르게 만들어내려면❗ “동기화” 와 ❗ “상호 배제” 개념을 반드시 이해해야 합니다.특히 임베디드 시스템에서는 FreeRTOS와 같은 실시간 운영체제를 많이 사용하므로,FreeRTOS가 제공하는 세마포어(Semaphore)·뮤텍스(Mutex) 같은 커널 객체를 활용해이 두 개념을 실전에서 어떻게 구현하는지 살펴보는 것이 중요합니다.1. 동기화(Synchronization)란?1-1. 일상(Real World) 예시“동기화”란 쉽게 말해 **“일정한 규칙(또는 시점)에 따라 여러 주체가 함께 움직인다”**는 의미입니다.예를 들어, 내일 오전 11시에 상사와 1:1 미팅이 잡혀 있다고 합시다.명..
FreeRTOS의 **소프트웨어 타이머(Software Timer)**는 실제 하드웨어 타이머 없이, 오로지 코드만으로 일정 주기마다 특정 콜백 함수를 호출해 주는 기능입니다.“500ms마다 LED를 깜빡이게 하고 싶다”거나 “1초마다 특정 작업을 수행해야 한다” 같은 반복적이고 주기적인 작업을 간편하게 처리할 수 있도록 도와줍니다.1. 하드웨어 타이머 vs. 소프트웨어 타이머1-1. 하드웨어 타이머MCU(예: STM32)의 타이머 페리페럴(TIM1, TIM2, …)을 직접 설정초단위(μs, ns) 정밀도 가능설정 단계타이머 클럭 분주(프리스케일러) 설정자동 리로드 레지스터(ARR)에 주기 값 설정인터럽트(업데이트 이벤트, CC 인터럽트 등) 활성화ISR(Interrupt Service Routine)에..
이 예제에서는 FreeRTOS 큐(Queue), 소프트웨어 타이머(Software Timer), 그리고 **태스크(Task)**와 **태스크 알림(Task Notification)**을 결합하여,UART로부터 사용자의 명령을 받아LED 이펙트 제어(LED 플래싱 패턴)실시간 시계(RTC) 설정 / 조회기능을 수행하는 심플한 콘솔 애플리케이션을 완성해 봅니다.1. 전체 구조 및 흐름 개요이 애플리케이션은 크게 **4개의 주요 구성 요소(모듈)**으로 나눌 수 있습니다.UART 입출력 모듈사용자로부터 **명령어(Command)**를 받아 파싱응답(메뉴, 에러 메시지 등)을 다시 UART로 출력명령어 처리(Task)“사용자 입력 → 큐(Queue)로 전송 → 명령어 파싱 태스크(CommandParserTask..
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 │ 함수 호출·지역변수 │ └──────────────┘ │ │..