SlideShare une entreprise Scribd logo
1  sur  101
(주)우리별: www.wooribyul.co.kr
조경형: khcho@wooribyul.co.kr
핵심기술(핵심SW) 세미나
2014. 07. 09.
FreeRTOS™
Contents
 Concept of Real-Time system
 FreeRTOS™ Overview
 FreeRTOS™ Demo S/W 구조
 FreeRTOS™ Task
 Task Creation API
 Task Control API
 Public Scheduler Control API
 Public Task Utilities
 TASK API 예제
 CoRoutine API 예제
 Public Queue Management
 Message Queue API 예제
 Semaphore
 Semaphore API 예제
 Memory Management
시스템 하드웨어를 관리할 뿐 아니라 응용 소프트웨어를 실행하기 위하여 하드웨어 추상화 플랫폼과 공통
시스템 서비스를 제공하는 시스템 소프트웨어이다. 운영 체제는 실행되는 응용 프로그램들이 메모리와
CPU, 입출력 장치 등의 자원들을 사용할 수 있도록 만들어 주고, 이들을 추상화하여 파일시스템 등의 서비
스를 제공한다. 또한 멀티태스킹을 지원하는 경우, 여러 개의 응용 프로그램을 실행하고 있는 동안, 운영 체
제는 이러한 모든 프로세스들을 스케줄링하여 마치 그들이 동시에 수행되는 것처럼 보이는 효과를 낸다
 Kernel: Kernel은 일반인이 일반적으로 보지 못하는 낮은 수준의 프로세스를 제어한다. 얼마나 메모리를 읽고 쓸 것인지
, 어느 프로세스를 실행할 것인지, 모니터, 키보드, 마우스와 같은 장치를 통해 어떠한 정보를 주고받을 것인지, 네트워
크를 통해 받은 정보를 어떻게 해석할 것인지를 제어한다
 UI: 컴퓨터 사용자가 직접 프로그램을 제어하고 사용할 수 있게 하는 운영 체제의 기능이다
 목적
– 사용자에게 컴퓨터의 프로그램을 쉽고 효율적으로 실행할 수 있는 환경을 제공한다
– 컴퓨터 시스템 하드웨어 및 소프트웨어 자원을 여러 사용자 간에 효율적 할당, 관리, 보호하는 것
– 운영 체제는 제어 프로그램으로서 사용자 프로그램의 오류나 잘못된 자원 사용을 감시하는 것과 입출력 장치 등의 자원에 대한 연산과 제어
를 관리
 구성요소
Operating System (OS)
Concept of Real-Time system
– Kernel
– Mode
– Multitasking
– 네트워킹
– Interrupt
– 가상메모리
– 장치 드라이버
– UI, GUI
– 프로그램 실행
– 메모리 관리
– 디스크 접근 및 파일시스템
– 보안
 Real-Time System이란 사용할 수 있는 자원이 한정되어 있는 상황에서 작업 수행이 요청
되었을 때, 이를 제한된 시간안에 처리해 결과를 내주는 것을 말한다. 즉, 작업의 요청에
서 수행결과를 얻기까지의 시간적인 제약이 존재하는 시스템으로 그 제약의 엄격함에 따
라서 hard real-time system과 soft real-time system으로 나뉜다.
 hard real-time system
작업의 실행 시작이나 완료에 대한 시간 제약조건을 지키지 못하는 경우 시스템 치명적
인 영향을 주는 경우를 가리킨다. 예로 무기제어, 발전소제어, 철도자동제어, 미사일 자동
조준 등을 들수 있다. 보장되는 컴퓨팅과 시간의 정확성과 컴퓨팅에 대한 예측성을 가지
게 해주어야 한다.
 soft real-time system
작업실행에 대한 시간 제약이 있지만, 이를 지키지 못하더라도 전체 시스템에 큰 영향을
끼치지 않는 시스템을 말한다. 그 예로 동영상을 들 수 있다. 초당 일정한 프레임(Frame)
이상의 영상을 재생해야 한다는 제약이 있으나, 통신부하나 시스템의 다른 작업으로 인하
여 프레임(Frame)이 건너뛰어져도 동영상을 재생하고 있던 시스템에는 큰 영향을 끼치지
않는다.
Real-Time System 이란?
Concept of Real-Time system(cont.)
단위프로그램
단위프로그램
 Foreground/background system
소형이면서 복잡하지 않은 시스템은
옆의 그림과 같이 설계한다. 이런 시스
템을 foreground/background system
또는 super-loop라고 한다.
 Foreground process는 interrupt level
background process는 task level이라
고 부른다.
 일정한 시간 내에 수행해야 할 중요한
동작은 반드시 ISR에서 처리해야 한다.
(원래의 수행시간보다 길어지는 경향)
 Task level response time: ISR이 BP에
정보를 전달하여 처리하는데 걸리는
시간
Foreground/Background System
단위프로그램
ISR
단위프로그램
단위프로그램
ISR
ISR
Background
process
Foreground
process
Time
Concept of Real-Time system(cont.)
RTOS는 아래와 같은 이유로 사용한다.
 Abstract out timing information
 Maintainability/Extensibility
 Modularity
 Cleaner interfaces
 Easier testing (in some cases)
 Code reuse
 Improved efficiency?
 Idle time
 Flexible interrupt handling
 Mixed processing requirements
 Easier control over peripherals
Why use an RTOS
Concept of Real-Time system(cont.)
Task
Task 1
Stack
Task 2
Stack
Task N
Stack
status
SP
Priority
TCB
status
SP
Priority
TCB
status
SP
Priority
TCB
Memory CPU
SP
Register
Concept of Real-Time system(cont.)
Task Status(µC-OS-II)
DORMANT
READY RUNNING
ISR
RUNNING
WATING
Concept of Real-Time system(cont.)
Task Status
Ready-State : Task는 실행 가능 상태이지
만 우선순위가 높거나 같은
다른 Task가 현재 실행상태에
있으므로 정지된 상태
Running-State : Task가 실행중인 상태
Blocked-State : vTaskDelay() 함수와 같은 타
이머등의 외부 이벤트를 기다리
며 정지된 상태, 이때는 우선순위
가 낮은 Task가 활동하거나 활동중
인 Task가 없는 경우에도
Scheduling 대상에서 제외
Suspended-State : vTaskSuspend()함수등 을
통해 중지상태에 머물게 되며
vTaskResume()의 API가 호출되기
전까지 스케줄링 대상에서 제외
Concept of Real-Time system(cont.)
 Critical Section
이 영역은 실행 중에 나뉘어져서는 안 된다는 의미이다. Critical Section은 실행
전에 Interrupt를 비활성화하고 실행 후에 활성화 한다.
 Resource
Task가 사용하는 모든 요소. I/O장치, 변수, 구조체 등...
 Shared Resource
여러 Task가 사용할 수 있는 Resource. Mutual exclusion 독점적 공유 자원 액
세스
 Multitasking
여러 Task가 번갈아서 CPU를 사용할 수 있도록 task의 순번을 정하고 task의 수
행을 전환하여 처리하는 것을 말한다. 여러 개의 background 프로세스를 가진
fore/back-ground system과 비슷하다. 장점으로 CPU를 최대한 활용할 수 있고
모듈화를 쉽게 해준다. Real-Time system을 복잡함을 쉽게 처리 할 수 있게 함
Terminology
Concept of Real-Time system(cont.)
 Context Switching
Multitasking kernel이 다른 task를 실행하고자 결정하면, Kernel은 단순히 현재
Task의 context(CPU register set)를 현재 Task stack에 저장하고 새로운 다른
Task의 stack에 저장되어졌던 context를 CPU register로 복귀시키는 과정을
Context switching이라고 한다.
 Kernel
Kernel은 multitasking system의 한 부분으로, Task 관리와 그 Task들 간의 통신
을 책임진다.
Context switching, Semaphore, Mailbox, Queue, Timedelay와 같은 서비스를
지원한다.
 Scheduler
Dispatcher라고도 한다. Kernel의 일부이며 다음에 실행할 task를 결정하는 일
을 수행한다. 대부분의 Real-time kernel은 Priority에 의해 실행할 Task를 결정
한다. (Preemptive-kernel or Non-Preemptive-kernel)
Terminology
Concept of Real-Time system(cont.)
 Reentrant Function
데이터의 손상 없이 여러 Task들이 공통으로 사용할 수 있는 함수. Reentrant
function은 항상 Interrupt를 허용한다. 가능한 local 변수를 사용하며 전역 변수
를 사용할 때는 데이터를 보호하는 방법을 사용해야 한다.
 Round-Robin Scheduling
2개 이상의 Task가 같은 Priority를 가지고 있을 때, Kernel은 quantum이라 불리
는 미리 정해진 시간간격동안 하나의 Task를 실행한 뒤, 다른 한 Task를 실행한
다. 이런 과정을 Time-slicing 또는 Round-Robin Scheduling이라고 한다.
 Static Scheduling / Dynamic Scheduling
– 정적 스케줄링(Static Scheduling) : 프로세스에 부여된 우선순위가 바뀌지 않는다. 고정
우선순위 스케줄링이라고도 한다. 컴파일시 우선순위가 배정되고 프로그램 수행 중에 우
선순위가 변경되지 않는다.
– 동적 스케줄링(Dynamic Scheduling) : 스케줄링 과정에서 프로세스의 우선순위를 변동
시킨다. 유동우선순위 스케줄링이라고도 한다. 우선순위는 프로그램 수행 중에 바꿀 수
있어 Priority Inversion 문제를 해결할 수 있다.
Terminology
Concept of Real-Time system(cont.)
Non-preemptive Kernel
 Non-preemptive kernel에서는 각 Task가 CPU의 제어권을 넘겨주기 위해 명시적으로 어
떤 동작을 해야 한다. 그리고 동시에 여러 task가 동작하는 것처럼 보이려면 이런 동작을
자주 실행해야 한다.
 Cooperative Multitasking 각 Task는 CPU를 공유하기 위해 서로 협력한다.
 ISR로 비동기적 이벤트를 처리하고 가장 Priority가 높은 task를 ready상태로 한 후 항상
수행하던 task로 되돌아 온다.
 Interrupt Latency가 짧다.
 Task level에서 Non-reentrant function을 사용할 수 있다. 공유 데이터를 보호할 필요성
이 줄어든다.
 Preemptive보다 scheduler 호출 빈도가 낮고 context switching에 의한 오버헤드가 적다
 Task level response time은 길어질 수 있다.
Concept of Real-Time system(cont.)
Preemptive Kernel
 Preemptive kernel에서는 Task level response time을 최소화 할 수 있다.
 ISR로 비동기적 이벤트를 처리하고 가장 Priority가 높은 task로 CPU 제어권이 넘어간다.
 Mutual Exclusion Semaphore를 이용하여 함수의 독점적인 Access를 보장하지 않은 상태
에서 Task level의 Non-reentrant function을 사용할 수 없다.
Low
Priority
Task
High
Priority Task
ISR
Time
Mid
Priority
Task
Concept of Real-Time system(cont.)
Priority Inversion
Task 1(H)
Task 2(M)
Task 3(L)
Task 3 세마포어 획득
Task 1 실행
Task 1 세마포어 요청
Task 2 실행 Task 2 종료
Task 3 실행
Task 3 세마포어 양도 Task 1 실행
Priority Inversion
Concept of Real-Time system(cont.)
Priority Inheritance
Task 1(H)
Task 2(M)
Task 3(L)
Task 3 세마포어 획득
Task 1 실행
Task 1 세마포어 요청
Task 3의 우선순위는
Task 1의 우선순위로
변경
Task 2 종료
Task 3 실행Task 3 세마포어 양도
Task 3 우선순위 원래대로
Task 1 실행
Task 1 완료
Priority Inversion
Concept of Real-Time system(cont.)
Scheduling 알고리즘 평가 기준
 CPU 사용률(CPU Utilization) : 전체 시스템 시간 중 CPU가 작업을 처리하는 시간의 비
율.
 처리량(Throughput) : CPU가 단위 시간당 처리하는 프로세스의 개수.
 응답 시간(Response Time) : 대화식 시스템에서 요청 후 응답이 오기 시작할 때까지의
시간.
 턴어라운드 시간(Turnaround Time) : 프로세스가 시작해서 끝날 때까지 걸리는 시간.
 대기 시간(Waiting Time) : 프로세스가 준비 큐 내에서 대기하는 시간의 총합.
 신뢰도(Reliability): 작업의 결과를 얼마나 정확하고 믿을 수 있는가의 요인.
Concept of Real-Time system(cont.)
Mutual Exclusion
 Task간 가장 쉬운 정보 교환은 공유 데이터를 통해서 구현한다.
 데이터의 손상을 막기 위해 데이터의 독점적이 액세스를 보장해야 한다.
 Mutual Exclusion 구현 방법
– Interrupt 비활성화: Interrupt 비활성화 시간이 길면 System Response Time이 길어진다.
– Test-And-Sets: Resource를 액세스하기 전에 Global access 변수를 Set한다. Resource를 사용하는 동
안 Interrupt는 활성화된다. 단 access 변수에 접근할 때 interrupt는 비활성화된다.
– Scheduler 비활성화: Task가 Resource를 ISR과 공유하지 않을 때 Task간 Resource 공유를 막기 위해
사용된다.
– Semaphore 사용
Concept of Real-Time system(cont.)
Semaphore
 세마포어(Semaphore)는 에츠허르 데이크스트라가 고안한, 두 개의 원자적 함수로 조작되는 정수 변수
로서, 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법으로 사용된다. 이는 철학자들
의 만찬 문제의 고전적인 해법이지만 모든 교착 상태를 해결하지는 못한다
 공유자원간의 액세스 제어(mutual exclusion)
 이벤트 발생을 알려줌(signaling)
 두 Task간의 동작 동기화(synchronization)
 Binary Semaphore, Counting Semaphore
 Operation: Initialize(Create), Wait(Pend), Signal(Post)
– Semaphore 초기화 시에 Ready 상태의 Task는 없다고 가정한다.
– Semaphore를 획득하고자 하면 Wait Operation을 수행
– Semaphore가 유효하면(0보다 큰 경우) Semaphore 값은 감소되고 Task 복귀 실행
– Semaphore가 0이면 Task는 Wait state로 감. (Timeout을 설정할 수 있음)
– Signal Operation을 통해 Semaphore를 반환한다.
– 어떤 Task도 Wait 상태가 아니면 Semaphore 값은 증가되고 Task 복귀 실행
– Wait 상태의 Task가 있다면 Semaphore 값은 그대로 그 Task는 Ready 상태로 간다.
 가장 우선순위가 높은 Task
 가장 먼저 Semaphore를 기다리기 시작한 Task
Concept of Real-Time system(cont.)
• Deadlock
교착상태는 동일한 자원을 공유하고 있는 두 개의 컴퓨터 프로그램들이, 상대방
이 자원에 접근하는 것을 사실상 서로 방해함으로써, 두 프로그램 모두 기능이
중지되는 결과를 낳는 상황을 말한다.
• Synchronization
• Semaphore를 사용하여 ISR 또는 다른 Task와 함께 동기화할 수 있다.
• Semaphore를 동기화 도구로 사용할 때 0으로 초기화한다.
ISR Task
POST PEND
Task Task
POST PEND
Task Task
POST PEND
POSTPEND
일방집결 양방집결
Concept of Real-Time system(cont.)
Event Flag
 Task를 여러 개의 Event 발생에 대해 동기화 할 필요가 있을 때 사용
ISR
Task
POST PEND
Task
OR
Semaphore이벤트
분리동기화
ISR
Task
POST PEND
Task
AND
Semaphore이벤트
결합동기화
Concept of Real-Time system(cont.)
• Intertask Communication
Task나 ISR이 다른 Task로 정보를 전달하는 것을 말한다.
전역변수나 메시지를 이용하여 전달할 수 있다. (ISR로는 전역변수로만)
전역변수를 사용할 경우 독점적 액세스를 보장
• Message Mailbox
Task Task
POST PEND
Message Queue
10
MailBox
Task 10 Task
POST PEND
5
Queue
Concept of Real-Time system(cont.)
Interrupt
 비동기적인 event가 발생한 것을 CPU에게 알
려주는 하드웨어 메커니즘
 Interrupt가 감지되면 CPU register를 저장하고
ISR을 수행한다.
 Interrupt 비활성화 시간은 가능한 짧게 ISR 수
행시간도 짧게 (시그날링과 비교 필요)
 Interrupt Latency
– 인터럽트가 비활성화된 최대시간 + ISR에서 최초 명
령을 실행하려는 시간
 Interrupt Response
– 인터럽트를 받는 순간부터 인터럽트 사용자 코드가 시작되는 순간까지의 시간
– 인터럽트를 처리하기 위한 모든 Overhead를 포함
– Interrupt Latency + Context switching Time + 커널의 ISR 진입함수 실행시간(선점형)
 Interrupt Recovery
– ISR을 수행한 후 커널 코드를 다시 수행하는 데 걸리는 시간
– Interrupt로부터 복귀명령 실행 시간 + Context switching Time + High Priority 결정 시간(선점형)
Concept of Real-Time system(cont.)
Clock Tick
 정기적으로 발생되는 Timer Interrupt이다
 커널로 하여금 Clock Tick 주기의 정수 배 만큼 Task를 지연시키고, 이벤트 Timeout을 제
공한다.
 Tick 발생속도가 빠르면 시스템에 오버헤드가 부과된다.
 Clock Delay는 Task Priority에 따라 다소 차이가 있고 정확한 Delay 시간을 제공하지는
않는다
Concept of Real-Time system(cont.)
 Richard Barry에 의해 작성된 Open Source의 RTOS( http://www.freertos.org/ )
 Free RTOS kernel - preemptive, cooperative and hybrid configuration options
 The SafeRTOS derivative product provides a high level of confidence in the code
integrity
 Includes a tickless mode for low power applications
 Tiny footprint
 Official support for >30 embedded system architectures
 FreeRTOS-MPU supports the ARM Cortex-M3 Memory Protection Unit (MPU)
 Designed to be small, simple and easy to use. Typically a RTOS kernel binary image
will be in the region of 4K to 9K bytes
 Very portable source code structure, predominantly written in C
 Supports both real time tasks and co-routines
 Innovative event group (or event flag) implementation
Features
FreeRTOS™ Overview
 Queues, binary semaphores, counting semaphores, recursive semaphores and mutexes
for communication and synchronisation between tasks, or between real time tasks and
interrupts
 Mutexes with priority inheritance
 Efficient software timers
 Powerful execution trace functionality
 Stack overflow detection options
 Pre-configured RTOS demo applications for selected single board computers allowing
'out of the box' operation and fast learning curve
 Free monitored forum support, or optional commercial support and licensing
 No software restriction on the number of real time tasks that can be created
 No software restriction on the number of task priorities that can be used
Features
FreeRTOS™ Overview(cont.)
 No restrictions imposed on task priority assignment - more than one real time task
can be assigned the same priority
 Free development tools for many supported architectures
 Free embedded software source code
 Royalty free
 Cross development from a standard Windows host
Features
FreeRTOS™ Overview(cont.)
Licensing
FreeRTOS™ Overview(cont.)
 FreeRTOS™는 변경된 GNU General Public
License를 따른다
 FreeRTOS™ demo application source에는
3rd party가 제공하는 별도의 source를 포
함한다. 이것은 FreeRTOS™ 라이선스를 따
르지 않고 별도의 라이선스가 부여된다
– silicon manufacturers and tool vendor가
제공하는 소스의 라이선스
– uIP TCP/IP stack 라이선스
– lwIP TCP/IP stack 라이선스
Folder Organization
FreeRTOS™ Demo S/W 구조
Libraries
이 directory에는 STM32 graphical library, hardware abstraction layer, the standard peripheral
libraries, the host and device libraries, the STM32 USB OTG driver, the CMSIS files 과 the
STM32 standard peripheral driver 들을 포함한다.
이 directory에는 STMicro에서 Release된 라이브러리들을 이 경로 아래에 둔다.
라이브러리는 가능한 수정하지 않고 사용하는 것을 지향한다.
만일 수정이 필요하면 define을 통해 정의 한 후 사용할 수 있다. 명확히 알 수 있는 버그에 대해
선 공지 후 define 없이 수정할 수 있다.
Project
STM32F2 시리즈를 사용하는 프로젝트는 여기에 정의하고 사용할 수 있다. 각 Project 아래 각 디
렉토리는 Project이다. 프로젝트 아래 세부 프로젝트로 나눌 수 있다. 프로젝트 디렉토리는 프로
젝트에 맞게 디렉토리를 분리하여 개발해도 된다. 개발에 맞게 적용한다.
프로젝트 파일이 많은 경우 Library와 Utility를 포함하여 전체를 새롭게 만들 수도 있다.
Utilities
공통 Utilities를 적용한다. 특히 3rd party solution들을 위치 시킨다. Library와 마찬가지로 공통
디렉토리이므로 수정을 지양한다. 수정할 경우 define을 통한 정의 통해 사용하여 다른 프로젝트
에 영향을 미치지 않도록 한다. 명확히 알 수 있는 버그에 대해선 공지 후 define 없이 수정할 수
있다.
Project 구조
FreeRTOS™ Demo S/W 구조(cont.)
Project 디렉토리 아래에는 진행할 Project를 정의한다. Project 그룹도 정의할 수 있다. FreeRTOS
는 프로젝트 그룹이고 그 아래에 각 Project를 정의하였고, MultiHop_2013은 프로젝트 디렉토리
이다.
이 프로젝트에서 개발되는 소스는 이 프로젝트에만 영향을 미치도록 하고 Library 또는 Utility에
영향을 미치지 않도록 한다. Dependency도 주어선 안된다.
EWARM 툴체인 정보를 SVN에 공유할 때 Object나 Setting 디렉토리는 제외한다. Dep 파일도 제
외한다.
STM322xG-EVAL
FreeRTOS™ Demo S/W 구조 (cont.)
STM322xG-EVAL 보드를 이용하여 각 테스트 버전을 만들 수 있는 프로젝트
STM322xG-EVAL을 위한 Demo 버전 소스로 구성되어 있음
STM322xG-EVAL 디렉토리 개발자 소스 디렉토리 구조는 다음과 같습니다.
 Config: Target configuration header 파일들을 여기에 둔다.
 Core: 개발 소스 디렉토리. 각 소스의 특징에 맞게 분리한 디렉토리 아래 둔다. 소스와 헤더 파
일도 같이 둔다.
 Doc: 소스와 관련된 문서 보관 장소
 EWARM: IAR 툴체인 디렉토리 오브젝트 파일들도 이 경로 아래 둔다.
MultiHop_2013
FreeRTOS™ Demo S/W 구조 (cont.)
병사용 무전기를 개발하기 위한 지경부 EVM으로 개발하는 프로젝트
MultiHop_2013 디렉토리 안에 EWARM이라는 IAR사에서 제공하는 Toolchain을 사용할 때 적용
되어진다. EWARM Toolchain에서 사용하는 프로젝트 경로는 이 디렉토리를 가르키게 한다.
MultiHop_2013 디렉토리 개발자 소스 디렉토리 구조는 다음과 같습니다.
 Config: Target configuration header 파일들을 여기에 둔다.
 Core: 개발 소스 디렉토리. 각 소스의 특징에 맞게 분리한 디렉토리 아래 둔다. 소스와 헤더 파
일도 같이 둔다.
 Doc: 소스와 관련된 문서 보관 장소
 EWARM: IAR 툴체인 디렉토리 오브젝트 파일들도 이 경로 아래 둔다.
이 프로젝트에서 개발되는 소스는 이 프로젝트에만 영향을 미치도록 하고 ST Micro chip을 사용
하면서 공통으로 이용 가능한 것들은 Library 또는 Utility에 포함하여 정의한다.
 TCB에 관한 구조체와 Stack을 지니며 동작하는 실행 개체
 독립적인 Task를 이용하여 Real time application을 구현
 Task는 Swap in/out시 사용되는 각자의 Stack을 지니고 있다
 우선 순위에 따라 Task Scheduler에 의해 Multi-Tasking을 구현
 4가지 state를 가짐
– Ready, Running, Suspended, Blocked state
 Supports full preemption
 Re-entrancy must be carefully considered if using preemption
Task Characteristics
FreeRTOS™ Task
 RTOS가 사용되는 용도에 따라 제한된 Memory용량 문제가 생기게 되는데 이를 해결하기
위해 Single Stack을 공유하는 Light Task개념으로써 사용되며 실행에 있어서 Main
Routine 과 Sub Routine처럼 주종관계가 있으며 실행될 때마다 재실행되는 Sub Routine
과 달리 서로 동등한 관계를 지니며 서로 호출이 가능하고 호출되어 다시 실행할 경우 마
지막에 실행된 곳에서부터 실행을 재개한다.
 Task와는 달리 하나의 Stack을 모든 CoRoutine들이 공유하게 되어 RAM상의 소모를 크게
줄일 수 있으나 그에 따른 실행과 관리에 제약이 존재한다.
 우선순위를 제공하고 비선점형 방식에 협력적(Cooperative) 스케줄링을 통해 실행되며
매크로방식을 사용하여 실행된다.
 Task와 함께 사용시에는 Task에 의해 선점이 되므로 보통 IdleTaskHook함수를 이용하여 실행
한다.
Co-Routine Characteristics
FreeRTOS™ Task (cont.)
 Ready State : Task와 마찬가지로 실행이
가능하지만 정지된 상태로 우선순위가 높
거나 같은 Co-Routine이 이미 실행 중이
거나 Task가 실행 중일 경우 Ready State
가 된다.
 Running : 현재 프로세스를 사용하여 실
행중인 상태
 Block : crDelay()등의 함수를 통해 외부적
인 이벤트(타이머)를 기다리는 상태로
Task와 마찬가지로 스케줄링이 불가능
 Co-Routine 함수는 다음과 같은 구조를
같는다
Co-Routine State
FreeRTOS™ Task (cont.)
 portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
const portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pvCreatedTask );
– pvTaskCode: Task entry function을 가리키는 pointer 값. 무한루프 함수로 작성
– pcName: 생성할 Task 이름 혹은 Tag char배열로 configMAX_TASK_NAME_LEN = 16
– usStackDepth: Task에서 사용될 Stack Size를 지정. 이 값은 byte size가 아님. Stack으로 사용하는 메
모리의 기본크기 portSTACK_TYPE x usStackDepth 이다. portSTACK_TYPE은 unsigned long이므로 4
이다. Stack size는 4 x usStackDepth bytes 이다.
– pvParameters: Task Entry Function을 호출할 때 넘겨줄 Parameter를 가르키는 pointer이다.
– uxPriority: Task Priority로 configMAX_PRIORITIES 값보다 작아야 한다.
– pvCreatedTask: 해당하는 Task의 TCB를 만들고 그것을 handle로 돌려 준다.
xTaskCreate
Task Creation API
 xTaskCreate() 함수를 호출하면 해당
Task의 TCB가 옆의 그림과 같이 생성됨
 TCB 아래에 xTaskCreate() 함수 호출 시
정의한 stack size x 4 bytes 만큼 생성됨
 맨 아래 stack에 초기화 값들을 채운다.
 xGenericListItem, xEventListItem
TCB 구조
Task Creation API(cont.)
 첫 번째 Task를 생성하면서
한 번 호출되는 함수
prvInitialiseTaskLists( )
 pxReadyTasksLists[13],
xDelayedTaskList1,
xDelayedTaskList2,
xPendingReadyList 이름의
List를 생성하고 초기화 한다.
List 관리
Task Creation API(cont.)
ReadyTaskList
Task Creation API(cont.)
 pxReadyTasksLists와 생성한 TCB와
Linked List로 연결한다.
 TCB Priority 별로 각각 연결한다.
 TCB Priority가 같으면 추가되는 TCB
는 아래와 같이 연결되고 관리 되어
진다.
 TCB의 *pvContainer는 연결된
pxReadyTasksLists[ ]을 가리킨다.
 void vTaskDelete( xTaskHandle pxTaskToDelete )
– Remove task from the ready list and place in the termination list. This will stop the task from be
scheduled.
– The idle task will check the termination list and free up any memory allocated by the scheduler
for the TCB and stack
vTaskDelete
Task Creation API(cont.)
 void vTaskDelay( portTickType
xTicksToDelay )
 해당 Tick 수만큼 호출한 Task를 대기
상태로 한다.
– xTicksToDelay : Tick 주기 단위의 시간량 ,
FreeRTOSconfig.h 의
configTICK_RATE_HZ 에 설정되어 있다.
– 설정 상수 ( FreeRTOSconfig.h ) :
INCLUDE_vTaskDelay= 1
 pxCurrentTCB 즉 현재 Task를
pxReadyTasksLists에서 삭제
 pxCurrentTCB를 pxDelayedTaskList,
pxOverflowDelayedTaskList에 등록
 xTaskResumeAll( )을 통해 Task
switching
vTaskDelay
Task Control API
 void vTaskDelayUntil( portTickType * const pxPreviousWakeTime,
portTickType xTimeIncrement )
– vTaskDelay의 경우 다른 Task에 의해 Tick수에 의한 정확한 실행 주기를 만들기 어려운 반면
vTaskDelayUntil()의 경우 Task가 마지막으로 깨어난 시점과 반복주기를 매개변수로 받아 대기시간을 명
시하여 정확한 실행 주기를 만들 수 있다
– pxPreviousWakeTime : Task가 마지막으로 깨어난 시점을 기록하는 포인터, 함수가 실행될 때마다 자동적
으로 갱신된다.
vTaskDelayUntil
Task Control API(cont.)
– xTimeIncrement : 반복주기,
Task는 (
*pxPreviousWakeTime
+xTimeIncrement )로 계산된
시간에 깨어나게 된다.
– 설정 상수 (
FreeRTOSconfig.h ) :
INCLUDE_vTaskDelayUntil= 1
 unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )
– 해당 Task의 우선순위를 반환
– pxTask : 해당 Task의 Handle값, NULL일 경우엔 호출한 Task의 값이 된다.
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskPriorityGET = 1
 void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )
– 해당 Task의 우선순위를 재설정하며, 함수가 반환 하기 전에 우선순위가 현재 실행되고 있는 Task
보다 높게되면 Context switch를 행한다.
– pxTask : 해당 Task의 Handle
– uxNewPriority : 설정할 Task의 우선순위
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskPrioritySet=1
– xEventListItem의 xItemValue = configMAX_PRIORITIES - ( portTickType ) uxNewPriority
TaskPriority 관련 함수
Task Control API(cont.)
 pxReadyTasksLists에 Task 재 작성
 void vTaskSuspend( xTaskHandle pxTaskToSuspend )
– 해당 Task를 중지상태 (Suspend State)로 전환
– pxTaskToSuspend : 해당 Task의 Handle
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskSuspend=1
– Remove task from the ready/delayed list and place in the suspended list.
– Waiting 하고 있는 xEventListItem 삭제에 의해 event도 삭제
– Current Task가 suspend 되면 Context Switching을 통해 Task switching
 void vTaskResume( xTaskHandle pxTaskToResume )
– 중지상태에 있는 해당 Task를 재개
– pxTaskToResume : Resume할 Task의 Handle
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskSuspend=1
– pxReadyTasksLists에 Resume Task TCB 등록함으로서 수행
 portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )
– vTaskResume()함수와 기능이 같으며 ISR 내부에서 실행
– pxTaskToResume : Resume할 Task의 Handle
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskSuspend = 1
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskResumeFromISR = 1
vTaskSuspend, vTaskResume
Task Control API(cont.)
vTaskStartScheduler()
Public Scheduler Control API
 vPortStartFirstTask()에서 non-Return
 PendSV Interrupt를 통해 Context
switching을 수행한다.
 vTaskSwitchContext( )를 호출하여
pxCurrentTCB를 가장 best Task로 설정한
후 인터럽트가 호출되면 수행하게 된다
Public Scheduler Control API (cont.)
 void vTaskEndScheduler( void ): xSchedulerRunning = pdFALSE
 void vTaskSuspendAll( void ): ++uxSchedulerSuspended
 signed portBASE_TYPE xTaskResumeAll( void )
– Move any readied tasks from the pending list into the appropriate ready list
– xTaskResumeFromISR, xTaskRemoveFromEventList 와 같은 함수 호출은 Task suspend동안
pxReadyTasksLists에 Task가 등록되지 않고 xPendingReadyList에 등록 된다.
– Resume 시 Priority가 현재 Task 보다 높은 Task가 Ready 상태에 있다면 Task switching
– vTaskIncrementTick함수가 호출된 횟수 만큼 xTaskResumeAll()함수에서 vTaskIncrementTick함수를
호출
 #define taskYIELD() portYIELD() : 강제적으로 Context Switch를 한다.
 #define taskENTER_CRITICAL() portENTER_CRITICAL() : 크리티컬 코드 영역의 시작 이후로
는 다른 Task에 의한 Context Switch가 일어나지 않는다.
 #define taskEXIT_CRITICAL() portEXIT_CRITICAL() : 크리티컬 코드 영역의 끝을 표시
 #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() : 모든 인터럽트를 비 활
성화 – basePRI register를 활용
 #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() : 비 활성화한 인터럽트들
을 다시 활성화 – basePRI register를 활용
vTaskEndScheduler, vTaskSuspendAll
 vTaskSuspendAll()과 match되어야 한다. (uxSchedulerSuspended)
xTaskResumeAll
Public Scheduler Control API (cont.)
Public Task Utilities
 portTickType xTaskGetTickCount( void ), portTickType xTaskGetTickCountFromISR( void )
vTaskStartScheduler가 호출되어 스케줄링을 시작한 이후부터의 Tick 카운트 수를 반환
 unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
현재 Kernel에서 관리하는 Task의 수를 반환. 삭제 대기 상태이나 idle Task에 의해 삭제
되지 않은 Task도 포함된다.
 void vTaskList( signed char *pcWriteBuffer )
현재 실행중인 모든 Task들의 정보를 표시하며, 대기(‘B’), 준비(‘R’), 삭제(‘D’), 중지(‘S’)로
표현된다.
– pcWriteBuffer : 위에서 나타난 State를 아스키 문자 형식으로 저장하는 버퍼
– 설정 상수 ( FreeRTOSconfig.h ) : configUSE_TRACE_FACILITY = 1
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_TaskDelete= 1
– 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_TaskSuspend = 1
 void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize )– 구현부 없음
실시간 Kernel 동작을 추적하여 어떤 Task가 언제 실행되는지에 대한 것을 추적하여 기록
– pcBuffer : 추적결과를 기록할 버퍼
– ulBufferSIZE : pcBuffer의 바이트 단위 크기, 설정된 크기이상 Trace정보가 기록될 경우나
ulTaskEndTrace()가 호출될 때까지 Trace한 내용을 기록
 unsigned long ulTaskEndTrace( void ) – 구현부 없음
Trace를 중지한다. pcBuffer에 기록된 바이트 수를 반환한다
Public Task Utilities(cont.)
 xTaskHandle xTaskGetCurrentTaskHandle( void )
호출된 Task의 Handle값을 반환
– 설정 상수 : INCLUDE_xTaskGetCurrentTaskHandle = 1 or configUSE_MUTEXES == 1
 portBASE_TYPE xTaskGetSchedulerState( void )
현재 스케줄러의 상태를 “taskSCHEDULER_NOT_STARTED, taskSCHEDULER_RUNNING,
taskSCHEDULER_SUSPENDED”중 하나로 반환
– 설정 상수 : INCLUDE_ xTaskGetSchedulerState = 1 or configUSE_TIMERS == 1
 void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE
pxHookFunction ) : 해당 Task의 Tag값을 설정
– xTask : 해당 Task의 Handle
– pxTagValue : Tag값으로 사용할 함수의 포인터, xTaskCallApplicationTaskHook()에서 사용될 함수를
정의하는 값이다.
– 설정 상수 ( FreeRTOSconfig.h ) : configUSE_APPLICATION_TASK_TAG = 1
 pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask )
 portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )
: 실행될 때마다 Task의 Tag값으로 명시된 Hook Function을 실행한다. 매개변수로 주어
진 pvParameter값을 Hook Function에 전달하여 사용할 수 있다.
– xTask : 해당 Task의 Handle
– pvParameter : Hook Function에서 사용될 값의 포인터
– 설정 상수 ( FreeRTOSconfig.h ) : configUSE_APPLICATION_TASK_TAG = 1
예제1 : Task를 생성하여 LCD화면 출력
TASK API 예제
TASK API 예제(cont.)
TASK API 예제(cont.)
예제 2 : vTaskDelay()와 vTaskDelayUntil()
TASK API 예제(cont.)
TASK API 예제(cont.)
예제3 : uxTaskPriorityGet(), vTaskPrioritySet()
TASK API 예제(cont.)
예제 4 : vTaskSuspend(), vTaskResume()
TASK API 예제(cont.)
TASK API 예제(cont.)
예제5 : vTaskSuspendAll(), vTaskResumeAll()
TASK API 예제(cont.)
TASK API 예제(cont.)
예제 6 : vTaskSetApplicationTaskTag(), vTaskApplicationTaskHook();
TASK API 예제(cont.)
TASK API 예제(cont.)
uxTaskPriorityGet(), xTaskGetTickCount(), xTaskGetSchedulerState(), uxTaskGetNumberOfTask()
TASK API 예제(cont.)
TASK API 예제(cont.)
CoRoutine생성과 실행
CoRoutine API 예제
CoRoutine API 예제(cont.)
CoRoutine API 예제(cont.)
 MutiTasking에서는 각 Task간에 공유하거나 겹치게 되는 자원영역 즉 Critical Section이 존재
하므로 이에 의해 생기는 문제를 해결하기 위하여 자원의 선점을 관리하거나 각 Task 간 통
신(ITC : Inter Task Communication)이 필요하게 된다.
 FreeRTOS에서 지원하는 ITC로는 Message Queue와 Semaphore(Mutexes)를 지원하고 있다.
 Message Queue는 FIFO(First in First out)방식을 사용하며 데이터를 Queue에 보낼때는 자료의
포인터를 보내게 되며 ISR에서도 사용하여 ISR과 Task내에 통신이 가능하다.
ITC – Message Queue
Public Queue Management
• *pcHead: Points to the beginning of the queue storage area.
• *pcTail: Points to the byte at the end of the queue storage area. Once
more byte is allocated than necessary to store the queue items, this is used
as a marker.
• *pcWriteTo: Points to the free next place in the storage area.
• *pcReadFrom: Points to the last place that a queued item was read from.
• xTasksWaitingToSend: List of tasks that are blocked waiting to post onto
this queue. Stored in priority order.
• xTasksWaitingToReceive: List of tasks that are blocked waiting to read from
this queue. Stored in priority order.
• uxMessagesWaiting: The number of items currently in the queue.
• uxLength: The length of the queue defined as the number of items it will
hold, not the number of bytes.
• uxItemSize: The size of each items that the queue will hold.
• xRxLock: Stores the number of items received from the queue (removed
from the queue) while the queue was locked. Set to queueUNLOCKED
when the queue is not locked
• xTxLock: Stores the number of items transmitted to the queue (added to
the queue) while the queue was locked. Set to queueUNLOCKED when the
queue is not locked.
• ucQueueNumber: configUSE_TRACE_FACILITY = 1 일때
• ucQueueType: configUSE_TRACE_FACILITY = 1 일때
Queue의 구조
Public Queue Management(cont.)
 xQueueCreate( uxQueueLength, uxItemSize )
 xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength,
unsigned portBASE_TYPE uxItemSize,
unsigned char ucQueueType )
새로운 Queue를 생성한다. Queue가 가질 자료의 최대 항목 수 uxQueueLength와 각 항목 당 필요한
자료의 크기인(바이트수) uxItemSize를 매개변수로 받아 Heap memory로부터 Queue 헤더와 Queue
데이터 영역을 생성 후에 그 Handle값인 xQueue를 반환해 준다
– uxQueueLength : Queue가 가질 최대 항목 개수
– uxItemSize : Queue에 있는 하나의 항목이 필요로 하는 바이트 수
 xQueueHandle xQueueCreateMutex( unsigned char ucQueueType )
Queue를 Mutex로 사용하기 위해 실제 Queue와 좀 다르게 생성한다. Queue Header만 생성한다.
 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE
uxCountValue, unsigned portBASE_TYPE uxInitialCount )
 unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )
해당 Queue의 Handle 값인 xQueue를 매개변수로 받아 Queue내의 매세지 개수를 반환한다.
 void vQueueDelete( xQueueHandle pxQueue )
해당 Handle값을 입력 받아 해당 Queue를 삭제하고 Queue내의 모든 항목의 Memory를 해제시킨다.
xQueueCreate
Public Queue Management API
 xQueueSend( xQueue, pvItemToQueue, xTicksToWait )
 xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait )
 xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait )
xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK(0) )
– xQueue: 해당 queue에 데이터를 저장하는 함수
– pvItemToQueue : Queue에 저장할 항목에 대한 포인터, 생성시 사용된 uxItemSize인자 즉 각 항목당
바이트 수에 의해 해당 포인터부터 정해진 바이트 수만큼 Queue영역으로 복사한다.
– pxQueue->xTasksWaitingToReceive에 등록한 Task가 있으면 xTaskRemoveFromEventList( )를 호출
pdTRUE를 return 하면 portYIELD_WITHIN_API()를 수행 task switching을 진행한다.
– xTicksToWait : Queue에 공간이 빌 때까지 Task가 기다리는 최대 시간
 signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )
이 함수는 인터럽트가 disable 상태거나 scheduler가 suspend 상태일 때 호출되어져야 한다. ISR에서
호출될 수도 있다. The event list is sorted in priority order, so we can remove the first in the list,
remove the TCB from the delayed list, and add it to the ready list
– *pxEventList = &pxQueue->xTasksWaitingToReceive (예)
– pxUnblockedTCB = pxQueue->xTasksWaitingToReceive 의 pvOwner가 가리키는 TCB가 된다.
– TCB내의 xEventListItem과 xGenericListItem와 연결된 List에서 삭제하고 pxReadyTasksLists에 연결
 portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut,
portTickType * const pxTicksToWait )
이 함수는 빈 Queue가 없을 때 Queue 생성될 때까지 대기하는 시간을 check한다
xQueueSend
Public Queue Management API(cont.)
Public Queue Management API(cont.)
 xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
 xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
 xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
xQueueGenericSendFromISR( xQueueHandle pxQueue,
const void * const pvItemToQueue,
signed portBASE_TYPE *pxHigherPriorityTaskWoken,
portBASE_TYPE xCopyPosition )
: ISR(Interrupt Service Routine)내에서 해당 Queue에 자료를 전달하는 함수.
– pxQueue: Queue handle
– pvItemToQueue : Queue에 저장할 항목에 대한 포인터, 생성시 사용된 uxItemSize인자 즉 각 항목당
바이트 수에 의해 해당 포인터부터 정해진 바이트 수만큼 Queue영역으로 복사한다.
– *pxHigherPriorityTaskWoken : ISR내에서 xQueueSendFromISR()에 의해 unblock된 Task의 Priority가
현재 실행중인 Task보다 높을 경우 xQueueSendFromISR()은 pxHigherPriority값을 pdTRUE로 만든다.
그럴 경우 ISR수행이 끝나지 않았음에도 unblock된 Task에 의해 Context Switch가 요청되어야 하므
로 ISR수행 후 pxHigherPriorityTaskWoken값을 이용하여 Context Switch 처리 여부를 결정할 수 있
다.
– xCopyPosition : xQueueGenericSendFromISR( )를 호출하면서 Queue의 front or back에 저장 위치에
대한 정보를 전달한다.
 xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xJustPeeking=pdFALSE 호출
 xQueuePeek( xQueue, pvBuffer, xTicksToWait ): xJustPeeking=pdTRUE 호출
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue,
void * const pvBuffer,
portTickType xTicksToWait,
portBASE_TYPE xJustPeeking )
해당 Queue에서 자료를 받는다. 항목을 성공적으로 받을 경우에 pdTRUE 1, 그렇지 않으면 pdFALSE
0 값을 반환한다.
– xQueue: 해당 Queue의 Handle 값
– pvBuffer : 받은 자료를 저장할 Buffer의 포인터
– xTicksToWait : Queue에 공간이 빌 때까지 Task가 기다리는 최대 시간
– xJustPeeking: xQueueReceive에서는 xJustPeeking=pdFALSE, xQueuePeek에서는
xJustPeeking=pdTRUE
 signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )
 xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait )
xQueueReceive
Public Queue Management API(cont.)
Public Queue Management API(cont.)
 xQueueReceiveFromISR( xQueueHandle pxQueue,
void * const pvBuffer,
signed portBASE_TYPE *pxTaskWoken )
: ISR내에서 해당 Queue내의 자료를 지정된 Buffer복사한 후 제거한다.
– pxQueue: Queue handle
– pvBuffer : Queue에서 받은 자료를 저장할 Buffer의 포인터
– *pxTaskWoken : 해당 Queue가 full일 경우 빈공간이 생기길 기다리는 Task가 존재할 수 있다. 이 경
우 함수 실행 후 빈 공간이 생겨서 해당 Task의 Waiting상태가 풀릴 경우 pxTaskWoken은 pdTRUE
로 Set되며 아닐 경우 pdFALSE로 남아있게 된다.
 crQUEUE_SEND( xCoRotineHandle xHandle, xQueueHandle pxQueue,
void *pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE *pxResult )
: CoRoutine내에서만 사용되며 xQueueSend()와 기능이 동일하며, CoRoutine은 Stack을 유지하지 않
으므로 호출된 함수 내에서는 사용할 수 없다.
– xHandle : CoRoutine handle
– pxQueue: Queue handle
– *pvItemToQueue : Queue에 넣을 자료의 포인터
– xTicksToWait : Queue가 사용 가능해질 때까지 CoRoutine이 대기하는 Tick의 수
– pxResult : Queue에 자료를 넣는데 성공시 pdPASS, 실패 시 projDefs.h에 정의된 값을 Set
 crQUEUE_RECEIVE( xCoRotineHandle xHandle, xQueueHandle pxQueue,
void *pvBuffer, portTickType xTicksToWait, portBASE_TYPE *pxResult )
: crQUEUE_SEND와 마찬가지로 CoRoutine내에서만 사용되며 xQueueReceive()와 동일, 마찬가지로
호출
– xHandle : CoRoutine handle
– pxQueue: Queue handle
– pvBuffer: 받을 자료를 저장할 포인터 값
– xTicksToWait : Queue가 사용가능해질 때까지 CoRoutine이 대기하는 Tick의 수
– pxResult : Queue에 자료를 넣는데 성공시 pdPASS, 실패 시 projDefs.h에 정의된 값을 Set된 함수 내
에서 사용할 수 없다.
CoRoutine Queue Management
Public Queue Management API(cont.)
Public Queue Management API(cont.)
 crQUEUE_SEND_FROM_ISR( xQueueHandle pxQueue, void *pvItemToQueue,
portBASE_TYPE xCoRotinePreviouslyWoken )
: xQueueSendFromISR()과 동일한 기능을 가지며 차이점은 ISR과 Task간의 자료전달이 아니라 ISR과
CoRoutine간의 자료 전달이라는 점이다.
– pxQueue: Queue handle
– *pvItemToQueue : Queue에 넣을 자료의 포인터
– xCoRotinePreviouslyWoken : xQueueSendFromISR()과 동일하게 Queue에 자료를 보낸 후 Context
Switch가 필요한 시점이 되면 pdTRUE값으로 Set된다.
 crQUEUE_RECEIVE_FROM_ISR( xQueueHandle pxQueue, void *pvBuffer,
portBASE_TYPE *pxCoRotineWoken )
: xQueueReceiveFromISR()과 같이 Queue로부터 자료를 받아 pvBuffer에 지정된 포인터 값으로 자료
를 전송한다. (복사 후 삭제)
– pxQueue: Queue handle
– pvBuffer: 받을 자료를 저장할 포인터 값
– pxCoRotineWoken : 해당 Queue가 Full 상태일 때 Queue가 비는 것을 기다리는 CoRoutine이 존재
시 Queue의 자료를 받은 후 pxCoRotineWoken값을 pdTRUE 값으로 Set한다.
예제 1 : Queue생성과 Data전송
Message Queue API 예제
Message Queue API 예제(cont.)
Message Queue API 예제(cont.)
 예제 2 : CoRoutine 내에서 Queue 사용(crQUEUE_SEND(), crQUEUE_RECEIVE())
CoRoutine 내에서 Queue
Message Queue API 예제(cont.)
Message Queue API 예제(cont.)
Message Queue API 예제(cont.)
 공유 자원에 대하여 둘 이상의 프로세스가 접근할 경우 자원의 값이 변함에 의한 오류나
교착상태(Deadlock)가 생길 수 있는 Critical Section의 동기화 문제를 해결하기 위한 방법
 하나의 프로세스가 공유 자원을 선점하였을 경우에 다른 프로세스들이 접근하지 못하도
록 막고, 사용 후 공유자원에 대한 사용권을 풀어줌으로써 자원 점유에 대한 중복을 막을
수 있게 한다.
 공유 자원의 사용권 수에 따라 하나일 경우 Binary Semaphore, 둘 이상일 경우 Counting
Semaphore, Binary Semaphore와 비슷하지만 소유권개념을 가지는 Mutex (Recursive
Mutex)를 지원한다.
 각 Semaphore들은 Queue를 이용한 매크로함수를 사용하여 구현된다.
Semaphore (FreeRTOS)
Semaphore
 vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
: Queue의 길이가 1인 Binary Semaphore를 생성한다.
– xSemaphore : 생성된 Semaphore의 Handle값
 xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned
portBASE_TYPE uxInitialCount )
: Counting Semaphore를 생성하기 위한 함수, 생성 시에 남아 있는 자료량과 최대 자료량을 결정할
수 있다. 생성 후 Semaphore의 Handle값을 반환한다.
– uxMaxCount : 사용할 수 있는 최대 자료량
– uxInitialCount : Semaphore가 생성될때 남아있는 자료량
– 설정 상수 ( FreeRTOSconfig.h ) : configUSE_COUNTING_SEMAPHORES = 1
 xSemaphoreCreateMutex( void )
: Mutex를 생성하는 함수, 생성 후 Semaphore의 Handle값을 반환한다.
 xSemaphoreCreateRecursiveMutex( void )
: 한 Mutex를 받은 함수가 여러번 Take를 할 수 있는 Mutex를 생성 예를 들어 Task가 5번 Take를 할
경우에 다른 Task에서 Mutex를 얻기 위해서는 해당 Task가 5번 Give를 해야 한다.
Semaphore API
Semaphore(cont.)
 xSemaphoreGive( xSemaphoreHandle xSemaphore )
: Task가 가지고 있는 Semaphore를 release한다. 그러기 위해서는 xSemaphoreCreateBinary(),
xSemaphoreCreateCouting(), xSemaphoreMutex()가 선언되고 xSemaphoreTake()를 통해
Semaphore를 획득한 상태여야 한다.
– xSemaphore : 해당 Semaphore의 Handle값
 xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
: xSemaphoreCreateRecursiveMutex()를 통해 생성된 Mutex를 release한다. Mutex를 가지고 있는
Task의 경우 xSemaphoreTakeRecursive()를 통해 Take한 횟수만큼 Give를 해 주어야 다른 Task에서
Mutex에 접근할 수 있다.
– xMutex : 해당 Mutex의 Handle값
 xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore,
portBASE_TYPE *pxHigherPriorityTaskWoken )
: xSemaphoreCreateBinary(), xSemaphoreCreateCounting()을 통하여 생성된 Semaphore를 ISR내에
서 release하는 함수. Mutex Type의 경우 사용할 수 없다.
– xSemaphore : 해당 Semaphore의 Handle값
– pxHigherPriorityTaskWoken : Semaphore를 놓아 줌으로써 현재 실행되고 있는 Task보다 높은
Priority를 가진 Task가 unblock되었을 시 해당 변수를 pdTRUE로 Set해 준다.
Semaphore API
Semaphore(cont.)
예제 1 : BinarySemaphore
Semaphore API 예제
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
예제 2 : Recursive Mutex와 소유권 문제
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
예제 3 : Recursive Mutex
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
예제 4 : Counting Semaphore
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
Semaphore API 예제(cont.)
Memory Management
RTOS에서는 Task Stack, Queue, Semaphore등을 생성할 때 Memory를 할당받는다. 하지만 이때 사
용되는 malloc(), Free() 는 Fragmentation에 의한 Memory 낭비가 있거나 Thread Safe(동시에 여러
개의 Thread 실행 시 결과의 Correct를 보장)에 문제, 연속적인 메모리 할당이 아닐 수 있으므로 생
기는 비결정적(Non – Determination) 수행속도에 의해 RTOS에서는 부적합 할 수 있다. FreeRTOS에
서는 이를 보장하기 위해서 malloc(), Free()대신에 pvPortMalloc(), vPortFree()를 Portable 계층에서
정의하여 Thread safe와 Memory낭비를 줄여주는 Scheme인 Heap_1, Heap_2, Heap_3를 지원하고
있다. Heap방식의 선택은 Compile시 Make file 설정을 통해 선택이 가능하다.
 프로그램 상에서 Task나 Queue가 Delete되지 않을 경우 사용되며, Memory 할당 시에는
pvPortMalloc()을 통해 Stack Size에 맞춰 할당하게 되며 한번 할당되면 제거를 하지 않는 프로
그램에 맞는 Scheme이다.
 A → B → C순으로 시간이 경과 할 때마다 Task가 들어오면 차례로 Task의 Size별로 Heap영역
을 할당하게 된다.
Heap_1.c
Memory Management(cont.)
 Memory를 5 bytes, 25 bytes, 100 bytes단위로 Block을 구축하여 Memory 영역 할당 시
pvPortMalloc()을 통하여 요구된 Memory 영역의 크기와 비교 가장 요구조건을 만족시키면서
낭비가 없는 Block을 선택하여 설정하게 된다. 해당 Memory영역과 남은 Memory Block들은
list를 통하여 관리되고 사용되고 있는 Memory 영역을 제거할 경우에는 vPortFree()를 통하여
제거한 후 해당 블록을 빈상태로 list에서 관리하게 된다. 또한 할당 후 Block내에 남은
Memory들은 다시 단위로 쪼개어 Block화 함으로써 Fragmentation을 줄이게 한다.
Heap_2.c
Memory Management(cont.)

Contenu connexe

Tendances

Real Time Kernels
Real Time KernelsReal Time Kernels
Real Time Kernels
Arnav Soni
 

Tendances (20)

Real Time Kernels
Real Time KernelsReal Time Kernels
Real Time Kernels
 
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
 
Prerequisite knowledge for shared memory concurrency
Prerequisite knowledge for shared memory concurrencyPrerequisite knowledge for shared memory concurrency
Prerequisite knowledge for shared memory concurrency
 
Device Tree for Dummies (ELC 2014)
Device Tree for Dummies (ELC 2014)Device Tree for Dummies (ELC 2014)
Device Tree for Dummies (ELC 2014)
 
Embedded Linux on ARM
Embedded Linux on ARMEmbedded Linux on ARM
Embedded Linux on ARM
 
FreeRTOS
FreeRTOSFreeRTOS
FreeRTOS
 
Crash Analysis with Reverse Taint
Crash Analysis with Reverse TaintCrash Analysis with Reverse Taint
Crash Analysis with Reverse Taint
 
FreeRTOS introduction
FreeRTOS introductionFreeRTOS introduction
FreeRTOS introduction
 
Rust Primer
Rust PrimerRust Primer
Rust Primer
 
Part 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module ProgrammingPart 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module Programming
 
Introduction to gdb
Introduction to gdbIntroduction to gdb
Introduction to gdb
 
Real Time Operating Systems for Embedded Systems
Real Time Operating Systems for Embedded SystemsReal Time Operating Systems for Embedded Systems
Real Time Operating Systems for Embedded Systems
 
Linux Crash Dump Capture and Analysis
Linux Crash Dump Capture and AnalysisLinux Crash Dump Capture and Analysis
Linux Crash Dump Capture and Analysis
 
Basics of boot-loader
Basics of boot-loaderBasics of boot-loader
Basics of boot-loader
 
淺談 Live patching technology
淺談 Live patching technology淺談 Live patching technology
淺談 Live patching technology
 
Embedded C - Day 2
Embedded C - Day 2Embedded C - Day 2
Embedded C - Day 2
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programming
 
Zephyr-Overview-20230124.pdf
Zephyr-Overview-20230124.pdfZephyr-Overview-20230124.pdf
Zephyr-Overview-20230124.pdf
 
[DockerCon 2020] Hardening Docker daemon with Rootless Mode
[DockerCon 2020] Hardening Docker daemon with Rootless Mode[DockerCon 2020] Hardening Docker daemon with Rootless Mode
[DockerCon 2020] Hardening Docker daemon with Rootless Mode
 
Introduction to Rust
Introduction to RustIntroduction to Rust
Introduction to Rust
 

En vedette

FreeRTOS
FreeRTOSFreeRTOS
FreeRTOS
quakke
 
GLONASS conference on ChipExpo 2011
GLONASS conference on ChipExpo 2011GLONASS conference on ChipExpo 2011
GLONASS conference on ChipExpo 2011
Nikolay Mikhaylov
 
[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)
[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)
[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)
Sang Don Kim
 

En vedette (20)

FreeRTOS
FreeRTOSFreeRTOS
FreeRTOS
 
Qt on Real Time Operating Systems
Qt on Real Time Operating SystemsQt on Real Time Operating Systems
Qt on Real Time Operating Systems
 
Use Analytics to Prevent Costly Product Returns
Use Analytics to Prevent Costly Product ReturnsUse Analytics to Prevent Costly Product Returns
Use Analytics to Prevent Costly Product Returns
 
GLONASS conference on ChipExpo 2011
GLONASS conference on ChipExpo 2011GLONASS conference on ChipExpo 2011
GLONASS conference on ChipExpo 2011
 
FreeRTOS API
FreeRTOS APIFreeRTOS API
FreeRTOS API
 
A low cost, real-time algorithm for embedded devices based on freertos kernel
A low cost, real-time algorithm for embedded devices based on freertos kernelA low cost, real-time algorithm for embedded devices based on freertos kernel
A low cost, real-time algorithm for embedded devices based on freertos kernel
 
Satellite Navigation. Present and Future
Satellite Navigation. Present and FutureSatellite Navigation. Present and Future
Satellite Navigation. Present and Future
 
Free rtos简介
Free rtos简介Free rtos简介
Free rtos简介
 
How to Measure RTOS Performance
How to Measure RTOS Performance How to Measure RTOS Performance
How to Measure RTOS Performance
 
NoSQL Database
NoSQL DatabaseNoSQL Database
NoSQL Database
 
SkyRover Firmware
SkyRover FirmwareSkyRover Firmware
SkyRover Firmware
 
FreeRTOS Course - Queue Management
FreeRTOS Course - Queue ManagementFreeRTOS Course - Queue Management
FreeRTOS Course - Queue Management
 
2016 年春季嵌入式作業系統課程說明
2016 年春季嵌入式作業系統課程說明2016 年春季嵌入式作業系統課程說明
2016 年春季嵌入式作業系統課程說明
 
[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)
[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)
[Td 2015]개발하기 바쁜데 푸시서버와 메시지큐는 있는거 쓸래요(김영재)
 
NoSQL 간단한 소개
NoSQL 간단한 소개NoSQL 간단한 소개
NoSQL 간단한 소개
 
Mqtt 소개
Mqtt 소개Mqtt 소개
Mqtt 소개
 
Introduction to Embedded Systems a Practical Approach
Introduction to Embedded Systems a Practical ApproachIntroduction to Embedded Systems a Practical Approach
Introduction to Embedded Systems a Practical Approach
 
Android Push Server & MQTT
Android Push Server & MQTTAndroid Push Server & MQTT
Android Push Server & MQTT
 
Introduction to C Programming
Introduction to C ProgrammingIntroduction to C Programming
Introduction to C Programming
 
FreeRTOS Course - Semaphore/Mutex Management
FreeRTOS Course - Semaphore/Mutex ManagementFreeRTOS Course - Semaphore/Mutex Management
FreeRTOS Course - Semaphore/Mutex Management
 

Similaire à Free rtos seminar

프로세스 관리
프로세스 관리프로세스 관리
프로세스 관리
jeiger
 
Linux Performan tuning Part I
Linux Performan tuning Part ILinux Performan tuning Part I
Linux Performan tuning Part I
sprdd
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍
흥배 최
 

Similaire à Free rtos seminar (20)

운영체제 Chapter1
운영체제 Chapter1운영체제 Chapter1
운영체제 Chapter1
 
프로세스 관리
프로세스 관리프로세스 관리
프로세스 관리
 
김성윤 - 우분투로 슈퍼컴 만들기 (2011Y03M26D)
김성윤 - 우분투로 슈퍼컴 만들기 (2011Y03M26D)김성윤 - 우분투로 슈퍼컴 만들기 (2011Y03M26D)
김성윤 - 우분투로 슈퍼컴 만들기 (2011Y03M26D)
 
Linux Performan tuning Part I
Linux Performan tuning Part ILinux Performan tuning Part I
Linux Performan tuning Part I
 
System Infra와 Recovery 그리고 DevOps
System Infra와 Recovery 그리고 DevOpsSystem Infra와 Recovery 그리고 DevOps
System Infra와 Recovery 그리고 DevOps
 
Reactive programming vs reactive systems
Reactive programming vs reactive systemsReactive programming vs reactive systems
Reactive programming vs reactive systems
 
Rankwave MOMENT™ (Korean)
Rankwave MOMENT™ (Korean)Rankwave MOMENT™ (Korean)
Rankwave MOMENT™ (Korean)
 
Rankwave moment™ desc3
Rankwave moment™ desc3Rankwave moment™ desc3
Rankwave moment™ desc3
 
Kubernetes
Kubernetes Kubernetes
Kubernetes
 
Zoo keeper 소개
Zoo keeper 소개Zoo keeper 소개
Zoo keeper 소개
 
os question
os questionos question
os question
 
Custom DevOps Monitoring System in MelOn (with InfluxDB + Telegraf + Grafana)
Custom DevOps Monitoring System in MelOn (with InfluxDB + Telegraf + Grafana)Custom DevOps Monitoring System in MelOn (with InfluxDB + Telegraf + Grafana)
Custom DevOps Monitoring System in MelOn (with InfluxDB + Telegraf + Grafana)
 
Monitoring System for DevOps - Case of MelOn
Monitoring System for DevOps - Case of MelOnMonitoring System for DevOps - Case of MelOn
Monitoring System for DevOps - Case of MelOn
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드
 
Fault Tolerance 소프트웨어 패턴
Fault Tolerance 소프트웨어 패턴Fault Tolerance 소프트웨어 패턴
Fault Tolerance 소프트웨어 패턴
 
[오픈소스컨설팅]systemd on RHEL7
[오픈소스컨설팅]systemd on RHEL7[오픈소스컨설팅]systemd on RHEL7
[오픈소스컨설팅]systemd on RHEL7
 
Fault Tolerance 패턴
Fault Tolerance 패턴 Fault Tolerance 패턴
Fault Tolerance 패턴
 
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
 
클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기클라우드 환경에서 알아야할 성능 이야기
클라우드 환경에서 알아야할 성능 이야기
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍
 

Free rtos seminar

  • 2. Contents  Concept of Real-Time system  FreeRTOS™ Overview  FreeRTOS™ Demo S/W 구조  FreeRTOS™ Task  Task Creation API  Task Control API  Public Scheduler Control API  Public Task Utilities  TASK API 예제  CoRoutine API 예제  Public Queue Management  Message Queue API 예제  Semaphore  Semaphore API 예제  Memory Management
  • 3. 시스템 하드웨어를 관리할 뿐 아니라 응용 소프트웨어를 실행하기 위하여 하드웨어 추상화 플랫폼과 공통 시스템 서비스를 제공하는 시스템 소프트웨어이다. 운영 체제는 실행되는 응용 프로그램들이 메모리와 CPU, 입출력 장치 등의 자원들을 사용할 수 있도록 만들어 주고, 이들을 추상화하여 파일시스템 등의 서비 스를 제공한다. 또한 멀티태스킹을 지원하는 경우, 여러 개의 응용 프로그램을 실행하고 있는 동안, 운영 체 제는 이러한 모든 프로세스들을 스케줄링하여 마치 그들이 동시에 수행되는 것처럼 보이는 효과를 낸다  Kernel: Kernel은 일반인이 일반적으로 보지 못하는 낮은 수준의 프로세스를 제어한다. 얼마나 메모리를 읽고 쓸 것인지 , 어느 프로세스를 실행할 것인지, 모니터, 키보드, 마우스와 같은 장치를 통해 어떠한 정보를 주고받을 것인지, 네트워 크를 통해 받은 정보를 어떻게 해석할 것인지를 제어한다  UI: 컴퓨터 사용자가 직접 프로그램을 제어하고 사용할 수 있게 하는 운영 체제의 기능이다  목적 – 사용자에게 컴퓨터의 프로그램을 쉽고 효율적으로 실행할 수 있는 환경을 제공한다 – 컴퓨터 시스템 하드웨어 및 소프트웨어 자원을 여러 사용자 간에 효율적 할당, 관리, 보호하는 것 – 운영 체제는 제어 프로그램으로서 사용자 프로그램의 오류나 잘못된 자원 사용을 감시하는 것과 입출력 장치 등의 자원에 대한 연산과 제어 를 관리  구성요소 Operating System (OS) Concept of Real-Time system – Kernel – Mode – Multitasking – 네트워킹 – Interrupt – 가상메모리 – 장치 드라이버 – UI, GUI – 프로그램 실행 – 메모리 관리 – 디스크 접근 및 파일시스템 – 보안
  • 4.  Real-Time System이란 사용할 수 있는 자원이 한정되어 있는 상황에서 작업 수행이 요청 되었을 때, 이를 제한된 시간안에 처리해 결과를 내주는 것을 말한다. 즉, 작업의 요청에 서 수행결과를 얻기까지의 시간적인 제약이 존재하는 시스템으로 그 제약의 엄격함에 따 라서 hard real-time system과 soft real-time system으로 나뉜다.  hard real-time system 작업의 실행 시작이나 완료에 대한 시간 제약조건을 지키지 못하는 경우 시스템 치명적 인 영향을 주는 경우를 가리킨다. 예로 무기제어, 발전소제어, 철도자동제어, 미사일 자동 조준 등을 들수 있다. 보장되는 컴퓨팅과 시간의 정확성과 컴퓨팅에 대한 예측성을 가지 게 해주어야 한다.  soft real-time system 작업실행에 대한 시간 제약이 있지만, 이를 지키지 못하더라도 전체 시스템에 큰 영향을 끼치지 않는 시스템을 말한다. 그 예로 동영상을 들 수 있다. 초당 일정한 프레임(Frame) 이상의 영상을 재생해야 한다는 제약이 있으나, 통신부하나 시스템의 다른 작업으로 인하 여 프레임(Frame)이 건너뛰어져도 동영상을 재생하고 있던 시스템에는 큰 영향을 끼치지 않는다. Real-Time System 이란? Concept of Real-Time system(cont.)
  • 5. 단위프로그램 단위프로그램  Foreground/background system 소형이면서 복잡하지 않은 시스템은 옆의 그림과 같이 설계한다. 이런 시스 템을 foreground/background system 또는 super-loop라고 한다.  Foreground process는 interrupt level background process는 task level이라 고 부른다.  일정한 시간 내에 수행해야 할 중요한 동작은 반드시 ISR에서 처리해야 한다. (원래의 수행시간보다 길어지는 경향)  Task level response time: ISR이 BP에 정보를 전달하여 처리하는데 걸리는 시간 Foreground/Background System 단위프로그램 ISR 단위프로그램 단위프로그램 ISR ISR Background process Foreground process Time Concept of Real-Time system(cont.)
  • 6. RTOS는 아래와 같은 이유로 사용한다.  Abstract out timing information  Maintainability/Extensibility  Modularity  Cleaner interfaces  Easier testing (in some cases)  Code reuse  Improved efficiency?  Idle time  Flexible interrupt handling  Mixed processing requirements  Easier control over peripherals Why use an RTOS Concept of Real-Time system(cont.)
  • 7. Task Task 1 Stack Task 2 Stack Task N Stack status SP Priority TCB status SP Priority TCB status SP Priority TCB Memory CPU SP Register Concept of Real-Time system(cont.)
  • 9. Task Status Ready-State : Task는 실행 가능 상태이지 만 우선순위가 높거나 같은 다른 Task가 현재 실행상태에 있으므로 정지된 상태 Running-State : Task가 실행중인 상태 Blocked-State : vTaskDelay() 함수와 같은 타 이머등의 외부 이벤트를 기다리 며 정지된 상태, 이때는 우선순위 가 낮은 Task가 활동하거나 활동중 인 Task가 없는 경우에도 Scheduling 대상에서 제외 Suspended-State : vTaskSuspend()함수등 을 통해 중지상태에 머물게 되며 vTaskResume()의 API가 호출되기 전까지 스케줄링 대상에서 제외 Concept of Real-Time system(cont.)
  • 10.  Critical Section 이 영역은 실행 중에 나뉘어져서는 안 된다는 의미이다. Critical Section은 실행 전에 Interrupt를 비활성화하고 실행 후에 활성화 한다.  Resource Task가 사용하는 모든 요소. I/O장치, 변수, 구조체 등...  Shared Resource 여러 Task가 사용할 수 있는 Resource. Mutual exclusion 독점적 공유 자원 액 세스  Multitasking 여러 Task가 번갈아서 CPU를 사용할 수 있도록 task의 순번을 정하고 task의 수 행을 전환하여 처리하는 것을 말한다. 여러 개의 background 프로세스를 가진 fore/back-ground system과 비슷하다. 장점으로 CPU를 최대한 활용할 수 있고 모듈화를 쉽게 해준다. Real-Time system을 복잡함을 쉽게 처리 할 수 있게 함 Terminology Concept of Real-Time system(cont.)
  • 11.  Context Switching Multitasking kernel이 다른 task를 실행하고자 결정하면, Kernel은 단순히 현재 Task의 context(CPU register set)를 현재 Task stack에 저장하고 새로운 다른 Task의 stack에 저장되어졌던 context를 CPU register로 복귀시키는 과정을 Context switching이라고 한다.  Kernel Kernel은 multitasking system의 한 부분으로, Task 관리와 그 Task들 간의 통신 을 책임진다. Context switching, Semaphore, Mailbox, Queue, Timedelay와 같은 서비스를 지원한다.  Scheduler Dispatcher라고도 한다. Kernel의 일부이며 다음에 실행할 task를 결정하는 일 을 수행한다. 대부분의 Real-time kernel은 Priority에 의해 실행할 Task를 결정 한다. (Preemptive-kernel or Non-Preemptive-kernel) Terminology Concept of Real-Time system(cont.)
  • 12.  Reentrant Function 데이터의 손상 없이 여러 Task들이 공통으로 사용할 수 있는 함수. Reentrant function은 항상 Interrupt를 허용한다. 가능한 local 변수를 사용하며 전역 변수 를 사용할 때는 데이터를 보호하는 방법을 사용해야 한다.  Round-Robin Scheduling 2개 이상의 Task가 같은 Priority를 가지고 있을 때, Kernel은 quantum이라 불리 는 미리 정해진 시간간격동안 하나의 Task를 실행한 뒤, 다른 한 Task를 실행한 다. 이런 과정을 Time-slicing 또는 Round-Robin Scheduling이라고 한다.  Static Scheduling / Dynamic Scheduling – 정적 스케줄링(Static Scheduling) : 프로세스에 부여된 우선순위가 바뀌지 않는다. 고정 우선순위 스케줄링이라고도 한다. 컴파일시 우선순위가 배정되고 프로그램 수행 중에 우 선순위가 변경되지 않는다. – 동적 스케줄링(Dynamic Scheduling) : 스케줄링 과정에서 프로세스의 우선순위를 변동 시킨다. 유동우선순위 스케줄링이라고도 한다. 우선순위는 프로그램 수행 중에 바꿀 수 있어 Priority Inversion 문제를 해결할 수 있다. Terminology Concept of Real-Time system(cont.)
  • 13. Non-preemptive Kernel  Non-preemptive kernel에서는 각 Task가 CPU의 제어권을 넘겨주기 위해 명시적으로 어 떤 동작을 해야 한다. 그리고 동시에 여러 task가 동작하는 것처럼 보이려면 이런 동작을 자주 실행해야 한다.  Cooperative Multitasking 각 Task는 CPU를 공유하기 위해 서로 협력한다.  ISR로 비동기적 이벤트를 처리하고 가장 Priority가 높은 task를 ready상태로 한 후 항상 수행하던 task로 되돌아 온다.  Interrupt Latency가 짧다.  Task level에서 Non-reentrant function을 사용할 수 있다. 공유 데이터를 보호할 필요성 이 줄어든다.  Preemptive보다 scheduler 호출 빈도가 낮고 context switching에 의한 오버헤드가 적다  Task level response time은 길어질 수 있다. Concept of Real-Time system(cont.)
  • 14. Preemptive Kernel  Preemptive kernel에서는 Task level response time을 최소화 할 수 있다.  ISR로 비동기적 이벤트를 처리하고 가장 Priority가 높은 task로 CPU 제어권이 넘어간다.  Mutual Exclusion Semaphore를 이용하여 함수의 독점적인 Access를 보장하지 않은 상태 에서 Task level의 Non-reentrant function을 사용할 수 없다. Low Priority Task High Priority Task ISR Time Mid Priority Task Concept of Real-Time system(cont.)
  • 15. Priority Inversion Task 1(H) Task 2(M) Task 3(L) Task 3 세마포어 획득 Task 1 실행 Task 1 세마포어 요청 Task 2 실행 Task 2 종료 Task 3 실행 Task 3 세마포어 양도 Task 1 실행 Priority Inversion Concept of Real-Time system(cont.)
  • 16. Priority Inheritance Task 1(H) Task 2(M) Task 3(L) Task 3 세마포어 획득 Task 1 실행 Task 1 세마포어 요청 Task 3의 우선순위는 Task 1의 우선순위로 변경 Task 2 종료 Task 3 실행Task 3 세마포어 양도 Task 3 우선순위 원래대로 Task 1 실행 Task 1 완료 Priority Inversion Concept of Real-Time system(cont.)
  • 17. Scheduling 알고리즘 평가 기준  CPU 사용률(CPU Utilization) : 전체 시스템 시간 중 CPU가 작업을 처리하는 시간의 비 율.  처리량(Throughput) : CPU가 단위 시간당 처리하는 프로세스의 개수.  응답 시간(Response Time) : 대화식 시스템에서 요청 후 응답이 오기 시작할 때까지의 시간.  턴어라운드 시간(Turnaround Time) : 프로세스가 시작해서 끝날 때까지 걸리는 시간.  대기 시간(Waiting Time) : 프로세스가 준비 큐 내에서 대기하는 시간의 총합.  신뢰도(Reliability): 작업의 결과를 얼마나 정확하고 믿을 수 있는가의 요인. Concept of Real-Time system(cont.)
  • 18. Mutual Exclusion  Task간 가장 쉬운 정보 교환은 공유 데이터를 통해서 구현한다.  데이터의 손상을 막기 위해 데이터의 독점적이 액세스를 보장해야 한다.  Mutual Exclusion 구현 방법 – Interrupt 비활성화: Interrupt 비활성화 시간이 길면 System Response Time이 길어진다. – Test-And-Sets: Resource를 액세스하기 전에 Global access 변수를 Set한다. Resource를 사용하는 동 안 Interrupt는 활성화된다. 단 access 변수에 접근할 때 interrupt는 비활성화된다. – Scheduler 비활성화: Task가 Resource를 ISR과 공유하지 않을 때 Task간 Resource 공유를 막기 위해 사용된다. – Semaphore 사용 Concept of Real-Time system(cont.)
  • 19. Semaphore  세마포어(Semaphore)는 에츠허르 데이크스트라가 고안한, 두 개의 원자적 함수로 조작되는 정수 변수 로서, 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법으로 사용된다. 이는 철학자들 의 만찬 문제의 고전적인 해법이지만 모든 교착 상태를 해결하지는 못한다  공유자원간의 액세스 제어(mutual exclusion)  이벤트 발생을 알려줌(signaling)  두 Task간의 동작 동기화(synchronization)  Binary Semaphore, Counting Semaphore  Operation: Initialize(Create), Wait(Pend), Signal(Post) – Semaphore 초기화 시에 Ready 상태의 Task는 없다고 가정한다. – Semaphore를 획득하고자 하면 Wait Operation을 수행 – Semaphore가 유효하면(0보다 큰 경우) Semaphore 값은 감소되고 Task 복귀 실행 – Semaphore가 0이면 Task는 Wait state로 감. (Timeout을 설정할 수 있음) – Signal Operation을 통해 Semaphore를 반환한다. – 어떤 Task도 Wait 상태가 아니면 Semaphore 값은 증가되고 Task 복귀 실행 – Wait 상태의 Task가 있다면 Semaphore 값은 그대로 그 Task는 Ready 상태로 간다.  가장 우선순위가 높은 Task  가장 먼저 Semaphore를 기다리기 시작한 Task Concept of Real-Time system(cont.)
  • 20. • Deadlock 교착상태는 동일한 자원을 공유하고 있는 두 개의 컴퓨터 프로그램들이, 상대방 이 자원에 접근하는 것을 사실상 서로 방해함으로써, 두 프로그램 모두 기능이 중지되는 결과를 낳는 상황을 말한다. • Synchronization • Semaphore를 사용하여 ISR 또는 다른 Task와 함께 동기화할 수 있다. • Semaphore를 동기화 도구로 사용할 때 0으로 초기화한다. ISR Task POST PEND Task Task POST PEND Task Task POST PEND POSTPEND 일방집결 양방집결 Concept of Real-Time system(cont.)
  • 21. Event Flag  Task를 여러 개의 Event 발생에 대해 동기화 할 필요가 있을 때 사용 ISR Task POST PEND Task OR Semaphore이벤트 분리동기화 ISR Task POST PEND Task AND Semaphore이벤트 결합동기화 Concept of Real-Time system(cont.)
  • 22. • Intertask Communication Task나 ISR이 다른 Task로 정보를 전달하는 것을 말한다. 전역변수나 메시지를 이용하여 전달할 수 있다. (ISR로는 전역변수로만) 전역변수를 사용할 경우 독점적 액세스를 보장 • Message Mailbox Task Task POST PEND Message Queue 10 MailBox Task 10 Task POST PEND 5 Queue Concept of Real-Time system(cont.)
  • 23. Interrupt  비동기적인 event가 발생한 것을 CPU에게 알 려주는 하드웨어 메커니즘  Interrupt가 감지되면 CPU register를 저장하고 ISR을 수행한다.  Interrupt 비활성화 시간은 가능한 짧게 ISR 수 행시간도 짧게 (시그날링과 비교 필요)  Interrupt Latency – 인터럽트가 비활성화된 최대시간 + ISR에서 최초 명 령을 실행하려는 시간  Interrupt Response – 인터럽트를 받는 순간부터 인터럽트 사용자 코드가 시작되는 순간까지의 시간 – 인터럽트를 처리하기 위한 모든 Overhead를 포함 – Interrupt Latency + Context switching Time + 커널의 ISR 진입함수 실행시간(선점형)  Interrupt Recovery – ISR을 수행한 후 커널 코드를 다시 수행하는 데 걸리는 시간 – Interrupt로부터 복귀명령 실행 시간 + Context switching Time + High Priority 결정 시간(선점형) Concept of Real-Time system(cont.)
  • 24. Clock Tick  정기적으로 발생되는 Timer Interrupt이다  커널로 하여금 Clock Tick 주기의 정수 배 만큼 Task를 지연시키고, 이벤트 Timeout을 제 공한다.  Tick 발생속도가 빠르면 시스템에 오버헤드가 부과된다.  Clock Delay는 Task Priority에 따라 다소 차이가 있고 정확한 Delay 시간을 제공하지는 않는다 Concept of Real-Time system(cont.)
  • 25.  Richard Barry에 의해 작성된 Open Source의 RTOS( http://www.freertos.org/ )  Free RTOS kernel - preemptive, cooperative and hybrid configuration options  The SafeRTOS derivative product provides a high level of confidence in the code integrity  Includes a tickless mode for low power applications  Tiny footprint  Official support for >30 embedded system architectures  FreeRTOS-MPU supports the ARM Cortex-M3 Memory Protection Unit (MPU)  Designed to be small, simple and easy to use. Typically a RTOS kernel binary image will be in the region of 4K to 9K bytes  Very portable source code structure, predominantly written in C  Supports both real time tasks and co-routines  Innovative event group (or event flag) implementation Features FreeRTOS™ Overview
  • 26.  Queues, binary semaphores, counting semaphores, recursive semaphores and mutexes for communication and synchronisation between tasks, or between real time tasks and interrupts  Mutexes with priority inheritance  Efficient software timers  Powerful execution trace functionality  Stack overflow detection options  Pre-configured RTOS demo applications for selected single board computers allowing 'out of the box' operation and fast learning curve  Free monitored forum support, or optional commercial support and licensing  No software restriction on the number of real time tasks that can be created  No software restriction on the number of task priorities that can be used Features FreeRTOS™ Overview(cont.)
  • 27.  No restrictions imposed on task priority assignment - more than one real time task can be assigned the same priority  Free development tools for many supported architectures  Free embedded software source code  Royalty free  Cross development from a standard Windows host Features FreeRTOS™ Overview(cont.)
  • 28. Licensing FreeRTOS™ Overview(cont.)  FreeRTOS™는 변경된 GNU General Public License를 따른다  FreeRTOS™ demo application source에는 3rd party가 제공하는 별도의 source를 포 함한다. 이것은 FreeRTOS™ 라이선스를 따 르지 않고 별도의 라이선스가 부여된다 – silicon manufacturers and tool vendor가 제공하는 소스의 라이선스 – uIP TCP/IP stack 라이선스 – lwIP TCP/IP stack 라이선스
  • 29. Folder Organization FreeRTOS™ Demo S/W 구조 Libraries 이 directory에는 STM32 graphical library, hardware abstraction layer, the standard peripheral libraries, the host and device libraries, the STM32 USB OTG driver, the CMSIS files 과 the STM32 standard peripheral driver 들을 포함한다. 이 directory에는 STMicro에서 Release된 라이브러리들을 이 경로 아래에 둔다. 라이브러리는 가능한 수정하지 않고 사용하는 것을 지향한다. 만일 수정이 필요하면 define을 통해 정의 한 후 사용할 수 있다. 명확히 알 수 있는 버그에 대해 선 공지 후 define 없이 수정할 수 있다. Project STM32F2 시리즈를 사용하는 프로젝트는 여기에 정의하고 사용할 수 있다. 각 Project 아래 각 디 렉토리는 Project이다. 프로젝트 아래 세부 프로젝트로 나눌 수 있다. 프로젝트 디렉토리는 프로 젝트에 맞게 디렉토리를 분리하여 개발해도 된다. 개발에 맞게 적용한다. 프로젝트 파일이 많은 경우 Library와 Utility를 포함하여 전체를 새롭게 만들 수도 있다. Utilities 공통 Utilities를 적용한다. 특히 3rd party solution들을 위치 시킨다. Library와 마찬가지로 공통 디렉토리이므로 수정을 지양한다. 수정할 경우 define을 통한 정의 통해 사용하여 다른 프로젝트 에 영향을 미치지 않도록 한다. 명확히 알 수 있는 버그에 대해선 공지 후 define 없이 수정할 수 있다.
  • 30. Project 구조 FreeRTOS™ Demo S/W 구조(cont.) Project 디렉토리 아래에는 진행할 Project를 정의한다. Project 그룹도 정의할 수 있다. FreeRTOS 는 프로젝트 그룹이고 그 아래에 각 Project를 정의하였고, MultiHop_2013은 프로젝트 디렉토리 이다. 이 프로젝트에서 개발되는 소스는 이 프로젝트에만 영향을 미치도록 하고 Library 또는 Utility에 영향을 미치지 않도록 한다. Dependency도 주어선 안된다. EWARM 툴체인 정보를 SVN에 공유할 때 Object나 Setting 디렉토리는 제외한다. Dep 파일도 제 외한다.
  • 31. STM322xG-EVAL FreeRTOS™ Demo S/W 구조 (cont.) STM322xG-EVAL 보드를 이용하여 각 테스트 버전을 만들 수 있는 프로젝트 STM322xG-EVAL을 위한 Demo 버전 소스로 구성되어 있음 STM322xG-EVAL 디렉토리 개발자 소스 디렉토리 구조는 다음과 같습니다.  Config: Target configuration header 파일들을 여기에 둔다.  Core: 개발 소스 디렉토리. 각 소스의 특징에 맞게 분리한 디렉토리 아래 둔다. 소스와 헤더 파 일도 같이 둔다.  Doc: 소스와 관련된 문서 보관 장소  EWARM: IAR 툴체인 디렉토리 오브젝트 파일들도 이 경로 아래 둔다.
  • 32. MultiHop_2013 FreeRTOS™ Demo S/W 구조 (cont.) 병사용 무전기를 개발하기 위한 지경부 EVM으로 개발하는 프로젝트 MultiHop_2013 디렉토리 안에 EWARM이라는 IAR사에서 제공하는 Toolchain을 사용할 때 적용 되어진다. EWARM Toolchain에서 사용하는 프로젝트 경로는 이 디렉토리를 가르키게 한다. MultiHop_2013 디렉토리 개발자 소스 디렉토리 구조는 다음과 같습니다.  Config: Target configuration header 파일들을 여기에 둔다.  Core: 개발 소스 디렉토리. 각 소스의 특징에 맞게 분리한 디렉토리 아래 둔다. 소스와 헤더 파 일도 같이 둔다.  Doc: 소스와 관련된 문서 보관 장소  EWARM: IAR 툴체인 디렉토리 오브젝트 파일들도 이 경로 아래 둔다. 이 프로젝트에서 개발되는 소스는 이 프로젝트에만 영향을 미치도록 하고 ST Micro chip을 사용 하면서 공통으로 이용 가능한 것들은 Library 또는 Utility에 포함하여 정의한다.
  • 33.  TCB에 관한 구조체와 Stack을 지니며 동작하는 실행 개체  독립적인 Task를 이용하여 Real time application을 구현  Task는 Swap in/out시 사용되는 각자의 Stack을 지니고 있다  우선 순위에 따라 Task Scheduler에 의해 Multi-Tasking을 구현  4가지 state를 가짐 – Ready, Running, Suspended, Blocked state  Supports full preemption  Re-entrancy must be carefully considered if using preemption Task Characteristics FreeRTOS™ Task
  • 34.  RTOS가 사용되는 용도에 따라 제한된 Memory용량 문제가 생기게 되는데 이를 해결하기 위해 Single Stack을 공유하는 Light Task개념으로써 사용되며 실행에 있어서 Main Routine 과 Sub Routine처럼 주종관계가 있으며 실행될 때마다 재실행되는 Sub Routine 과 달리 서로 동등한 관계를 지니며 서로 호출이 가능하고 호출되어 다시 실행할 경우 마 지막에 실행된 곳에서부터 실행을 재개한다.  Task와는 달리 하나의 Stack을 모든 CoRoutine들이 공유하게 되어 RAM상의 소모를 크게 줄일 수 있으나 그에 따른 실행과 관리에 제약이 존재한다.  우선순위를 제공하고 비선점형 방식에 협력적(Cooperative) 스케줄링을 통해 실행되며 매크로방식을 사용하여 실행된다.  Task와 함께 사용시에는 Task에 의해 선점이 되므로 보통 IdleTaskHook함수를 이용하여 실행 한다. Co-Routine Characteristics FreeRTOS™ Task (cont.)
  • 35.  Ready State : Task와 마찬가지로 실행이 가능하지만 정지된 상태로 우선순위가 높 거나 같은 Co-Routine이 이미 실행 중이 거나 Task가 실행 중일 경우 Ready State 가 된다.  Running : 현재 프로세스를 사용하여 실 행중인 상태  Block : crDelay()등의 함수를 통해 외부적 인 이벤트(타이머)를 기다리는 상태로 Task와 마찬가지로 스케줄링이 불가능  Co-Routine 함수는 다음과 같은 구조를 같는다 Co-Routine State FreeRTOS™ Task (cont.)
  • 36.  portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask ); – pvTaskCode: Task entry function을 가리키는 pointer 값. 무한루프 함수로 작성 – pcName: 생성할 Task 이름 혹은 Tag char배열로 configMAX_TASK_NAME_LEN = 16 – usStackDepth: Task에서 사용될 Stack Size를 지정. 이 값은 byte size가 아님. Stack으로 사용하는 메 모리의 기본크기 portSTACK_TYPE x usStackDepth 이다. portSTACK_TYPE은 unsigned long이므로 4 이다. Stack size는 4 x usStackDepth bytes 이다. – pvParameters: Task Entry Function을 호출할 때 넘겨줄 Parameter를 가르키는 pointer이다. – uxPriority: Task Priority로 configMAX_PRIORITIES 값보다 작아야 한다. – pvCreatedTask: 해당하는 Task의 TCB를 만들고 그것을 handle로 돌려 준다. xTaskCreate Task Creation API
  • 37.  xTaskCreate() 함수를 호출하면 해당 Task의 TCB가 옆의 그림과 같이 생성됨  TCB 아래에 xTaskCreate() 함수 호출 시 정의한 stack size x 4 bytes 만큼 생성됨  맨 아래 stack에 초기화 값들을 채운다.  xGenericListItem, xEventListItem TCB 구조 Task Creation API(cont.)
  • 38.  첫 번째 Task를 생성하면서 한 번 호출되는 함수 prvInitialiseTaskLists( )  pxReadyTasksLists[13], xDelayedTaskList1, xDelayedTaskList2, xPendingReadyList 이름의 List를 생성하고 초기화 한다. List 관리 Task Creation API(cont.)
  • 39. ReadyTaskList Task Creation API(cont.)  pxReadyTasksLists와 생성한 TCB와 Linked List로 연결한다.  TCB Priority 별로 각각 연결한다.  TCB Priority가 같으면 추가되는 TCB 는 아래와 같이 연결되고 관리 되어 진다.  TCB의 *pvContainer는 연결된 pxReadyTasksLists[ ]을 가리킨다.
  • 40.  void vTaskDelete( xTaskHandle pxTaskToDelete ) – Remove task from the ready list and place in the termination list. This will stop the task from be scheduled. – The idle task will check the termination list and free up any memory allocated by the scheduler for the TCB and stack vTaskDelete Task Creation API(cont.)
  • 41.  void vTaskDelay( portTickType xTicksToDelay )  해당 Tick 수만큼 호출한 Task를 대기 상태로 한다. – xTicksToDelay : Tick 주기 단위의 시간량 , FreeRTOSconfig.h 의 configTICK_RATE_HZ 에 설정되어 있다. – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskDelay= 1  pxCurrentTCB 즉 현재 Task를 pxReadyTasksLists에서 삭제  pxCurrentTCB를 pxDelayedTaskList, pxOverflowDelayedTaskList에 등록  xTaskResumeAll( )을 통해 Task switching vTaskDelay Task Control API
  • 42.  void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) – vTaskDelay의 경우 다른 Task에 의해 Tick수에 의한 정확한 실행 주기를 만들기 어려운 반면 vTaskDelayUntil()의 경우 Task가 마지막으로 깨어난 시점과 반복주기를 매개변수로 받아 대기시간을 명 시하여 정확한 실행 주기를 만들 수 있다 – pxPreviousWakeTime : Task가 마지막으로 깨어난 시점을 기록하는 포인터, 함수가 실행될 때마다 자동적 으로 갱신된다. vTaskDelayUntil Task Control API(cont.) – xTimeIncrement : 반복주기, Task는 ( *pxPreviousWakeTime +xTimeIncrement )로 계산된 시간에 깨어나게 된다. – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskDelayUntil= 1
  • 43.  unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) – 해당 Task의 우선순위를 반환 – pxTask : 해당 Task의 Handle값, NULL일 경우엔 호출한 Task의 값이 된다. – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskPriorityGET = 1  void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) – 해당 Task의 우선순위를 재설정하며, 함수가 반환 하기 전에 우선순위가 현재 실행되고 있는 Task 보다 높게되면 Context switch를 행한다. – pxTask : 해당 Task의 Handle – uxNewPriority : 설정할 Task의 우선순위 – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskPrioritySet=1 – xEventListItem의 xItemValue = configMAX_PRIORITIES - ( portTickType ) uxNewPriority TaskPriority 관련 함수 Task Control API(cont.)  pxReadyTasksLists에 Task 재 작성
  • 44.  void vTaskSuspend( xTaskHandle pxTaskToSuspend ) – 해당 Task를 중지상태 (Suspend State)로 전환 – pxTaskToSuspend : 해당 Task의 Handle – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskSuspend=1 – Remove task from the ready/delayed list and place in the suspended list. – Waiting 하고 있는 xEventListItem 삭제에 의해 event도 삭제 – Current Task가 suspend 되면 Context Switching을 통해 Task switching  void vTaskResume( xTaskHandle pxTaskToResume ) – 중지상태에 있는 해당 Task를 재개 – pxTaskToResume : Resume할 Task의 Handle – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskSuspend=1 – pxReadyTasksLists에 Resume Task TCB 등록함으로서 수행  portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) – vTaskResume()함수와 기능이 같으며 ISR 내부에서 실행 – pxTaskToResume : Resume할 Task의 Handle – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskSuspend = 1 – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_vTaskResumeFromISR = 1 vTaskSuspend, vTaskResume Task Control API(cont.)
  • 45. vTaskStartScheduler() Public Scheduler Control API  vPortStartFirstTask()에서 non-Return  PendSV Interrupt를 통해 Context switching을 수행한다.  vTaskSwitchContext( )를 호출하여 pxCurrentTCB를 가장 best Task로 설정한 후 인터럽트가 호출되면 수행하게 된다
  • 46. Public Scheduler Control API (cont.)  void vTaskEndScheduler( void ): xSchedulerRunning = pdFALSE  void vTaskSuspendAll( void ): ++uxSchedulerSuspended  signed portBASE_TYPE xTaskResumeAll( void ) – Move any readied tasks from the pending list into the appropriate ready list – xTaskResumeFromISR, xTaskRemoveFromEventList 와 같은 함수 호출은 Task suspend동안 pxReadyTasksLists에 Task가 등록되지 않고 xPendingReadyList에 등록 된다. – Resume 시 Priority가 현재 Task 보다 높은 Task가 Ready 상태에 있다면 Task switching – vTaskIncrementTick함수가 호출된 횟수 만큼 xTaskResumeAll()함수에서 vTaskIncrementTick함수를 호출  #define taskYIELD() portYIELD() : 강제적으로 Context Switch를 한다.  #define taskENTER_CRITICAL() portENTER_CRITICAL() : 크리티컬 코드 영역의 시작 이후로 는 다른 Task에 의한 Context Switch가 일어나지 않는다.  #define taskEXIT_CRITICAL() portEXIT_CRITICAL() : 크리티컬 코드 영역의 끝을 표시  #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() : 모든 인터럽트를 비 활 성화 – basePRI register를 활용  #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() : 비 활성화한 인터럽트들 을 다시 활성화 – basePRI register를 활용 vTaskEndScheduler, vTaskSuspendAll
  • 47.  vTaskSuspendAll()과 match되어야 한다. (uxSchedulerSuspended) xTaskResumeAll Public Scheduler Control API (cont.)
  • 48. Public Task Utilities  portTickType xTaskGetTickCount( void ), portTickType xTaskGetTickCountFromISR( void ) vTaskStartScheduler가 호출되어 스케줄링을 시작한 이후부터의 Tick 카운트 수를 반환  unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) 현재 Kernel에서 관리하는 Task의 수를 반환. 삭제 대기 상태이나 idle Task에 의해 삭제 되지 않은 Task도 포함된다.  void vTaskList( signed char *pcWriteBuffer ) 현재 실행중인 모든 Task들의 정보를 표시하며, 대기(‘B’), 준비(‘R’), 삭제(‘D’), 중지(‘S’)로 표현된다. – pcWriteBuffer : 위에서 나타난 State를 아스키 문자 형식으로 저장하는 버퍼 – 설정 상수 ( FreeRTOSconfig.h ) : configUSE_TRACE_FACILITY = 1 – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_TaskDelete= 1 – 설정 상수 ( FreeRTOSconfig.h ) : INCLUDE_TaskSuspend = 1  void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize )– 구현부 없음 실시간 Kernel 동작을 추적하여 어떤 Task가 언제 실행되는지에 대한 것을 추적하여 기록 – pcBuffer : 추적결과를 기록할 버퍼 – ulBufferSIZE : pcBuffer의 바이트 단위 크기, 설정된 크기이상 Trace정보가 기록될 경우나 ulTaskEndTrace()가 호출될 때까지 Trace한 내용을 기록  unsigned long ulTaskEndTrace( void ) – 구현부 없음 Trace를 중지한다. pcBuffer에 기록된 바이트 수를 반환한다
  • 49. Public Task Utilities(cont.)  xTaskHandle xTaskGetCurrentTaskHandle( void ) 호출된 Task의 Handle값을 반환 – 설정 상수 : INCLUDE_xTaskGetCurrentTaskHandle = 1 or configUSE_MUTEXES == 1  portBASE_TYPE xTaskGetSchedulerState( void ) 현재 스케줄러의 상태를 “taskSCHEDULER_NOT_STARTED, taskSCHEDULER_RUNNING, taskSCHEDULER_SUSPENDED”중 하나로 반환 – 설정 상수 : INCLUDE_ xTaskGetSchedulerState = 1 or configUSE_TIMERS == 1  void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) : 해당 Task의 Tag값을 설정 – xTask : 해당 Task의 Handle – pxTagValue : Tag값으로 사용할 함수의 포인터, xTaskCallApplicationTaskHook()에서 사용될 함수를 정의하는 값이다. – 설정 상수 ( FreeRTOSconfig.h ) : configUSE_APPLICATION_TASK_TAG = 1  pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask )  portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) : 실행될 때마다 Task의 Tag값으로 명시된 Hook Function을 실행한다. 매개변수로 주어 진 pvParameter값을 Hook Function에 전달하여 사용할 수 있다. – xTask : 해당 Task의 Handle – pvParameter : Hook Function에서 사용될 값의 포인터 – 설정 상수 ( FreeRTOSconfig.h ) : configUSE_APPLICATION_TASK_TAG = 1
  • 50. 예제1 : Task를 생성하여 LCD화면 출력 TASK API 예제
  • 53. 예제 2 : vTaskDelay()와 vTaskDelayUntil() TASK API 예제(cont.)
  • 55. 예제3 : uxTaskPriorityGet(), vTaskPrioritySet() TASK API 예제(cont.)
  • 56. 예제 4 : vTaskSuspend(), vTaskResume() TASK API 예제(cont.)
  • 58. 예제5 : vTaskSuspendAll(), vTaskResumeAll() TASK API 예제(cont.)
  • 60. 예제 6 : vTaskSetApplicationTaskTag(), vTaskApplicationTaskHook(); TASK API 예제(cont.)
  • 62. uxTaskPriorityGet(), xTaskGetTickCount(), xTaskGetSchedulerState(), uxTaskGetNumberOfTask() TASK API 예제(cont.)
  • 67.  MutiTasking에서는 각 Task간에 공유하거나 겹치게 되는 자원영역 즉 Critical Section이 존재 하므로 이에 의해 생기는 문제를 해결하기 위하여 자원의 선점을 관리하거나 각 Task 간 통 신(ITC : Inter Task Communication)이 필요하게 된다.  FreeRTOS에서 지원하는 ITC로는 Message Queue와 Semaphore(Mutexes)를 지원하고 있다.  Message Queue는 FIFO(First in First out)방식을 사용하며 데이터를 Queue에 보낼때는 자료의 포인터를 보내게 되며 ISR에서도 사용하여 ISR과 Task내에 통신이 가능하다. ITC – Message Queue Public Queue Management
  • 68. • *pcHead: Points to the beginning of the queue storage area. • *pcTail: Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. • *pcWriteTo: Points to the free next place in the storage area. • *pcReadFrom: Points to the last place that a queued item was read from. • xTasksWaitingToSend: List of tasks that are blocked waiting to post onto this queue. Stored in priority order. • xTasksWaitingToReceive: List of tasks that are blocked waiting to read from this queue. Stored in priority order. • uxMessagesWaiting: The number of items currently in the queue. • uxLength: The length of the queue defined as the number of items it will hold, not the number of bytes. • uxItemSize: The size of each items that the queue will hold. • xRxLock: Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked • xTxLock: Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. • ucQueueNumber: configUSE_TRACE_FACILITY = 1 일때 • ucQueueType: configUSE_TRACE_FACILITY = 1 일때 Queue의 구조 Public Queue Management(cont.)
  • 69.  xQueueCreate( uxQueueLength, uxItemSize )  xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) 새로운 Queue를 생성한다. Queue가 가질 자료의 최대 항목 수 uxQueueLength와 각 항목 당 필요한 자료의 크기인(바이트수) uxItemSize를 매개변수로 받아 Heap memory로부터 Queue 헤더와 Queue 데이터 영역을 생성 후에 그 Handle값인 xQueue를 반환해 준다 – uxQueueLength : Queue가 가질 최대 항목 개수 – uxItemSize : Queue에 있는 하나의 항목이 필요로 하는 바이트 수  xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) Queue를 Mutex로 사용하기 위해 실제 Queue와 좀 다르게 생성한다. Queue Header만 생성한다.  xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )  unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) 해당 Queue의 Handle 값인 xQueue를 매개변수로 받아 Queue내의 매세지 개수를 반환한다.  void vQueueDelete( xQueueHandle pxQueue ) 해당 Handle값을 입력 받아 해당 Queue를 삭제하고 Queue내의 모든 항목의 Memory를 해제시킨다. xQueueCreate Public Queue Management API
  • 70.  xQueueSend( xQueue, pvItemToQueue, xTicksToWait )  xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait )  xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK(0) ) – xQueue: 해당 queue에 데이터를 저장하는 함수 – pvItemToQueue : Queue에 저장할 항목에 대한 포인터, 생성시 사용된 uxItemSize인자 즉 각 항목당 바이트 수에 의해 해당 포인터부터 정해진 바이트 수만큼 Queue영역으로 복사한다. – pxQueue->xTasksWaitingToReceive에 등록한 Task가 있으면 xTaskRemoveFromEventList( )를 호출 pdTRUE를 return 하면 portYIELD_WITHIN_API()를 수행 task switching을 진행한다. – xTicksToWait : Queue에 공간이 빌 때까지 Task가 기다리는 최대 시간  signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) 이 함수는 인터럽트가 disable 상태거나 scheduler가 suspend 상태일 때 호출되어져야 한다. ISR에서 호출될 수도 있다. The event list is sorted in priority order, so we can remove the first in the list, remove the TCB from the delayed list, and add it to the ready list – *pxEventList = &pxQueue->xTasksWaitingToReceive (예) – pxUnblockedTCB = pxQueue->xTasksWaitingToReceive 의 pvOwner가 가리키는 TCB가 된다. – TCB내의 xEventListItem과 xGenericListItem와 연결된 List에서 삭제하고 pxReadyTasksLists에 연결  portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) 이 함수는 빈 Queue가 없을 때 Queue 생성될 때까지 대기하는 시간을 check한다 xQueueSend Public Queue Management API(cont.)
  • 71. Public Queue Management API(cont.)  xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken )  xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken )  xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) : ISR(Interrupt Service Routine)내에서 해당 Queue에 자료를 전달하는 함수. – pxQueue: Queue handle – pvItemToQueue : Queue에 저장할 항목에 대한 포인터, 생성시 사용된 uxItemSize인자 즉 각 항목당 바이트 수에 의해 해당 포인터부터 정해진 바이트 수만큼 Queue영역으로 복사한다. – *pxHigherPriorityTaskWoken : ISR내에서 xQueueSendFromISR()에 의해 unblock된 Task의 Priority가 현재 실행중인 Task보다 높을 경우 xQueueSendFromISR()은 pxHigherPriority값을 pdTRUE로 만든다. 그럴 경우 ISR수행이 끝나지 않았음에도 unblock된 Task에 의해 Context Switch가 요청되어야 하므 로 ISR수행 후 pxHigherPriorityTaskWoken값을 이용하여 Context Switch 처리 여부를 결정할 수 있 다. – xCopyPosition : xQueueGenericSendFromISR( )를 호출하면서 Queue의 front or back에 저장 위치에 대한 정보를 전달한다.
  • 72.  xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xJustPeeking=pdFALSE 호출  xQueuePeek( xQueue, pvBuffer, xTicksToWait ): xJustPeeking=pdTRUE 호출 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) 해당 Queue에서 자료를 받는다. 항목을 성공적으로 받을 경우에 pdTRUE 1, 그렇지 않으면 pdFALSE 0 값을 반환한다. – xQueue: 해당 Queue의 Handle 값 – pvBuffer : 받은 자료를 저장할 Buffer의 포인터 – xTicksToWait : Queue에 공간이 빌 때까지 Task가 기다리는 최대 시간 – xJustPeeking: xQueueReceive에서는 xJustPeeking=pdFALSE, xQueuePeek에서는 xJustPeeking=pdTRUE  signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )  xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) xQueueReceive Public Queue Management API(cont.)
  • 73. Public Queue Management API(cont.)  xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) : ISR내에서 해당 Queue내의 자료를 지정된 Buffer복사한 후 제거한다. – pxQueue: Queue handle – pvBuffer : Queue에서 받은 자료를 저장할 Buffer의 포인터 – *pxTaskWoken : 해당 Queue가 full일 경우 빈공간이 생기길 기다리는 Task가 존재할 수 있다. 이 경 우 함수 실행 후 빈 공간이 생겨서 해당 Task의 Waiting상태가 풀릴 경우 pxTaskWoken은 pdTRUE 로 Set되며 아닐 경우 pdFALSE로 남아있게 된다.
  • 74.  crQUEUE_SEND( xCoRotineHandle xHandle, xQueueHandle pxQueue, void *pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE *pxResult ) : CoRoutine내에서만 사용되며 xQueueSend()와 기능이 동일하며, CoRoutine은 Stack을 유지하지 않 으므로 호출된 함수 내에서는 사용할 수 없다. – xHandle : CoRoutine handle – pxQueue: Queue handle – *pvItemToQueue : Queue에 넣을 자료의 포인터 – xTicksToWait : Queue가 사용 가능해질 때까지 CoRoutine이 대기하는 Tick의 수 – pxResult : Queue에 자료를 넣는데 성공시 pdPASS, 실패 시 projDefs.h에 정의된 값을 Set  crQUEUE_RECEIVE( xCoRotineHandle xHandle, xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait, portBASE_TYPE *pxResult ) : crQUEUE_SEND와 마찬가지로 CoRoutine내에서만 사용되며 xQueueReceive()와 동일, 마찬가지로 호출 – xHandle : CoRoutine handle – pxQueue: Queue handle – pvBuffer: 받을 자료를 저장할 포인터 값 – xTicksToWait : Queue가 사용가능해질 때까지 CoRoutine이 대기하는 Tick의 수 – pxResult : Queue에 자료를 넣는데 성공시 pdPASS, 실패 시 projDefs.h에 정의된 값을 Set된 함수 내 에서 사용할 수 없다. CoRoutine Queue Management Public Queue Management API(cont.)
  • 75. Public Queue Management API(cont.)  crQUEUE_SEND_FROM_ISR( xQueueHandle pxQueue, void *pvItemToQueue, portBASE_TYPE xCoRotinePreviouslyWoken ) : xQueueSendFromISR()과 동일한 기능을 가지며 차이점은 ISR과 Task간의 자료전달이 아니라 ISR과 CoRoutine간의 자료 전달이라는 점이다. – pxQueue: Queue handle – *pvItemToQueue : Queue에 넣을 자료의 포인터 – xCoRotinePreviouslyWoken : xQueueSendFromISR()과 동일하게 Queue에 자료를 보낸 후 Context Switch가 필요한 시점이 되면 pdTRUE값으로 Set된다.  crQUEUE_RECEIVE_FROM_ISR( xQueueHandle pxQueue, void *pvBuffer, portBASE_TYPE *pxCoRotineWoken ) : xQueueReceiveFromISR()과 같이 Queue로부터 자료를 받아 pvBuffer에 지정된 포인터 값으로 자료 를 전송한다. (복사 후 삭제) – pxQueue: Queue handle – pvBuffer: 받을 자료를 저장할 포인터 값 – pxCoRotineWoken : 해당 Queue가 Full 상태일 때 Queue가 비는 것을 기다리는 CoRoutine이 존재 시 Queue의 자료를 받은 후 pxCoRotineWoken값을 pdTRUE 값으로 Set한다.
  • 76. 예제 1 : Queue생성과 Data전송 Message Queue API 예제
  • 77. Message Queue API 예제(cont.)
  • 78. Message Queue API 예제(cont.)
  • 79.  예제 2 : CoRoutine 내에서 Queue 사용(crQUEUE_SEND(), crQUEUE_RECEIVE()) CoRoutine 내에서 Queue Message Queue API 예제(cont.)
  • 80. Message Queue API 예제(cont.)
  • 81. Message Queue API 예제(cont.)
  • 82.  공유 자원에 대하여 둘 이상의 프로세스가 접근할 경우 자원의 값이 변함에 의한 오류나 교착상태(Deadlock)가 생길 수 있는 Critical Section의 동기화 문제를 해결하기 위한 방법  하나의 프로세스가 공유 자원을 선점하였을 경우에 다른 프로세스들이 접근하지 못하도 록 막고, 사용 후 공유자원에 대한 사용권을 풀어줌으로써 자원 점유에 대한 중복을 막을 수 있게 한다.  공유 자원의 사용권 수에 따라 하나일 경우 Binary Semaphore, 둘 이상일 경우 Counting Semaphore, Binary Semaphore와 비슷하지만 소유권개념을 가지는 Mutex (Recursive Mutex)를 지원한다.  각 Semaphore들은 Queue를 이용한 매크로함수를 사용하여 구현된다. Semaphore (FreeRTOS) Semaphore
  • 83.  vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore ) : Queue의 길이가 1인 Binary Semaphore를 생성한다. – xSemaphore : 생성된 Semaphore의 Handle값  xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount ) : Counting Semaphore를 생성하기 위한 함수, 생성 시에 남아 있는 자료량과 최대 자료량을 결정할 수 있다. 생성 후 Semaphore의 Handle값을 반환한다. – uxMaxCount : 사용할 수 있는 최대 자료량 – uxInitialCount : Semaphore가 생성될때 남아있는 자료량 – 설정 상수 ( FreeRTOSconfig.h ) : configUSE_COUNTING_SEMAPHORES = 1  xSemaphoreCreateMutex( void ) : Mutex를 생성하는 함수, 생성 후 Semaphore의 Handle값을 반환한다.  xSemaphoreCreateRecursiveMutex( void ) : 한 Mutex를 받은 함수가 여러번 Take를 할 수 있는 Mutex를 생성 예를 들어 Task가 5번 Take를 할 경우에 다른 Task에서 Mutex를 얻기 위해서는 해당 Task가 5번 Give를 해야 한다. Semaphore API Semaphore(cont.)
  • 84.  xSemaphoreGive( xSemaphoreHandle xSemaphore ) : Task가 가지고 있는 Semaphore를 release한다. 그러기 위해서는 xSemaphoreCreateBinary(), xSemaphoreCreateCouting(), xSemaphoreMutex()가 선언되고 xSemaphoreTake()를 통해 Semaphore를 획득한 상태여야 한다. – xSemaphore : 해당 Semaphore의 Handle값  xSemaphoreGiveRecursive( xSemaphoreHandle xMutex ) : xSemaphoreCreateRecursiveMutex()를 통해 생성된 Mutex를 release한다. Mutex를 가지고 있는 Task의 경우 xSemaphoreTakeRecursive()를 통해 Take한 횟수만큼 Give를 해 주어야 다른 Task에서 Mutex에 접근할 수 있다. – xMutex : 해당 Mutex의 Handle값  xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore, portBASE_TYPE *pxHigherPriorityTaskWoken ) : xSemaphoreCreateBinary(), xSemaphoreCreateCounting()을 통하여 생성된 Semaphore를 ISR내에 서 release하는 함수. Mutex Type의 경우 사용할 수 없다. – xSemaphore : 해당 Semaphore의 Handle값 – pxHigherPriorityTaskWoken : Semaphore를 놓아 줌으로써 현재 실행되고 있는 Task보다 높은 Priority를 가진 Task가 unblock되었을 시 해당 변수를 pdTRUE로 Set해 준다. Semaphore API Semaphore(cont.)
  • 85. 예제 1 : BinarySemaphore Semaphore API 예제
  • 88. 예제 2 : Recursive Mutex와 소유권 문제 Semaphore API 예제(cont.)
  • 91. 예제 3 : Recursive Mutex Semaphore API 예제(cont.)
  • 94. 예제 4 : Counting Semaphore Semaphore API 예제(cont.)
  • 99. Memory Management RTOS에서는 Task Stack, Queue, Semaphore등을 생성할 때 Memory를 할당받는다. 하지만 이때 사 용되는 malloc(), Free() 는 Fragmentation에 의한 Memory 낭비가 있거나 Thread Safe(동시에 여러 개의 Thread 실행 시 결과의 Correct를 보장)에 문제, 연속적인 메모리 할당이 아닐 수 있으므로 생 기는 비결정적(Non – Determination) 수행속도에 의해 RTOS에서는 부적합 할 수 있다. FreeRTOS에 서는 이를 보장하기 위해서 malloc(), Free()대신에 pvPortMalloc(), vPortFree()를 Portable 계층에서 정의하여 Thread safe와 Memory낭비를 줄여주는 Scheme인 Heap_1, Heap_2, Heap_3를 지원하고 있다. Heap방식의 선택은 Compile시 Make file 설정을 통해 선택이 가능하다.
  • 100.  프로그램 상에서 Task나 Queue가 Delete되지 않을 경우 사용되며, Memory 할당 시에는 pvPortMalloc()을 통해 Stack Size에 맞춰 할당하게 되며 한번 할당되면 제거를 하지 않는 프로 그램에 맞는 Scheme이다.  A → B → C순으로 시간이 경과 할 때마다 Task가 들어오면 차례로 Task의 Size별로 Heap영역 을 할당하게 된다. Heap_1.c Memory Management(cont.)
  • 101.  Memory를 5 bytes, 25 bytes, 100 bytes단위로 Block을 구축하여 Memory 영역 할당 시 pvPortMalloc()을 통하여 요구된 Memory 영역의 크기와 비교 가장 요구조건을 만족시키면서 낭비가 없는 Block을 선택하여 설정하게 된다. 해당 Memory영역과 남은 Memory Block들은 list를 통하여 관리되고 사용되고 있는 Memory 영역을 제거할 경우에는 vPortFree()를 통하여 제거한 후 해당 블록을 빈상태로 list에서 관리하게 된다. 또한 할당 후 Block내에 남은 Memory들은 다시 단위로 쪼개어 Block화 함으로써 Fragmentation을 줄이게 한다. Heap_2.c Memory Management(cont.)

Notes de l'éditeur

  1. 커널: 펌웨어와 장치 드리이버의 도움을 받아 운영 체제는 모든 컴퓨터 하드웨어 장치에 대한 가장 기초 수준의 제어권을 제공한다. 커널은 램을 통해 프로그램을 위한 메모리 접근을 관리하며 어느 프로그램이 어느 하드웨어 자원에 접근할지를 결정하며 CPU의 동작 상태를 늘 최적으로 설정 및 초기화하고 디스크, 테이프, 플래시 메모리와 같은 매체의 파일 시스템을 갖춘 장시간 비휘발성 기억 장치를 위한 데이터를 정리한다. 운영 체제 내에서의 커널의 영역과 그 구성에 따라 모노리딕 커널(monolithic kernel), 마이크로 커널 (micro kernel)등으로 분류한다. 프로그램 실행 운영 체제는 응용 프로그램과 하드웨어 사이의 인터페이스 역할을 한다. 운영 체제는 응용 프로그램 개발을 단순하게 하는 서비스의 집합이다. 프로그램을 실행하면 운영 체제가 프로세스를 만든다. 커널은 메모리와 다른 자원을 할당하여 프로세스를 만들며, 이로써 멀티태스킹 환경에서 프로세스에 대한 우선 순위를 확립하고, 메모리에 프로그램 코드를 적재하며 프로그램을 실행한다. 그 뒤 프로그램은 사용자 및 장치와 상호작용한 다음 원하는 명령을 수행하게 된다. 운영 체제는 프로세스들을 생성하거나 삭제하고, 중단시키거나 재개시킨다. 프로세스 간의 동기화와 통신, Deadlock 처리에 관한 메커니즘을 제공한다. 1. 사용자 및 시스템 프로세스의 생성과 종료 관리 2. 프로세스의 일시 중지와 속개 3. 프로세스 동기화를 위한 수단의 제공 4. 프로세스간 통신을 위한 수단의 제공 5. 교착 상태 처리를 위한 수단의 제공 인터럽트 인터럽트는 주변 환경에 반응하고 상호작용하는 데에 효율적인 방법을 운영 체제에 제공하므로 운영 체제에 핵심적인 역할을 한다고 할 수 있다 모드 메모리 관리 멀티프로그래밍 운영 체제 커널은 현재 프로그램이 이용하는 모든 시스템 메모리를 관리해야 한다. 이로써 어느 특정한 프로그램이 다른 프로그램이 이미 사용하고 있는 메모리와 상호 작용하지 않게 한다. 프로그램이 시분할하므로 각 프로그램은 메모리에 독립적으로 접근해야 한다 가상메모리 멀티태스킹 멀티태스킹은 여러 개의 독립적인 컴퓨터 프로그램을 하나의 컴퓨터에 실행시키는 것을 가리킨다. 마치 태스크들이 동시에 수행하는 것처럼 보여 준다. 대부분의 컴퓨터가 한 번에 최대 한 두개를 수행할 수 있고 이는 일반적으로 시분할을 통해 수행된다. 다시 말해 각 프로그램은 컴퓨터의 실행 시간의 일부를 사용한다. 운영 체제 커널은 스케줄러라는 프로그램이 포함되어 있는데 이 프로그램은 얼마나 많은 시간을 각 프로그램이 실행에 소비하게 할 것인지를 결정하며 여기서 실행 제어권이 프로그램에 넘어갈 수 있게 한다. 제어권은 프로그램이 CPU와 메모리에 접근할 수 있게 하는 커널로 말미암아 프로세스로 넘어간다. 나중에 다른 프로그램이 CPU를 사용할 수 있게 하기 위해 제어권은 같은 메커니즘을 통하여 커널로 반환된다. 커널과 응용 프로그램 간의 제어권 이동을 이른바 문맥 교환이라고 부른다. 디스크 접근 및 파일시스템 디스크에 저장된 데이터로 접근하는 것은 모든 운영 체제의 기본 기능이다. 컴퓨터는 더 빠른 접근, 더 높은 신뢰성을 위해, 또 드라이브의 남은 공간을 더 잘 이용하기 위한 특정한 방식으로 구조화된 파일을 이용하여 디스크에 데이터를 저장한다. 파일을 디스크에 저장하는 이러한 방식을 파일 시스템이라고 부르며 파일이 이름과 특성을 가질 수 있게 한다. 또, 이러한 파일들을 디렉터리 트리로 정렬되는 특정 계급의 디렉터리와 폴더에 저장하게 한다. 초기의 운영 체제는 일반적으로 한 종류의 디스크 드라이브와 한 종류의 파일 시스템을 지원하였다. 초기의 파일 시스템들은 용량, 속도, 또 파일 이름과 디렉터리 구조의 종류에 제한이 있었다. 이러한 제한은 설계된 운영 체제의 제한에 반영되므로 특정한 운영 체제가 하나 이상의 파일 시스템을 지원하는 것을 매우 어렵게 만들었다. 더 단순한 수많은 운영 체제들은 기억 장치의 시스템에 접근하기 위한 제한된 옵션들을 지원하였는데, 유닉스와 GNU/리눅스와 같은 운영 체제들은 가상 파일 시스템(VFS)이라는 기술을 지원한다. 유닉스와 같은 운영 체제는 공통 API를 통해 접근하는 파일 시스템이나 디자인에 관계 없이 다양한 기억 장치를 지원한다. 그러므로 프로그램을 개발할 때 장치 접근에 대한 정보를 공부하지 않아도 되게 한다. VFS는 다양한 파일 시스템에, 특정한 장치 드라이버와 파일 시스템 드라이버를 사용하여 프로그램들이 무제한의 장치에 접근할 수 있는 기능을 운영 체제에 제공한다. 연결된 하드 드라이브와 같은 기억 장치들은 장치 드라이버를 통해 접근한다. 장치 드라이버는 드라이브의 특정한 언어를 이해하고 이 언어를 운영 체제가 모든 디스크 드라이브에 접근할 때 사용하는 표준 언어로 번역할 수 있다. 유닉스에서 이를 블록 장치의 언어라고 한다 장치 드라이버 장치 드라이버는 하드웨어 장치들과 상호 작용할 수 있도록 개발된 특정한 종류의 컴퓨터 소프트웨어이다. 네트위킹 현재 대부분의 운영 체제는 다양한 통신 프로토콜, 하드웨어, 응용 프로그램을 지원한다. 다시 말해, 서로 비슷하지 않은 운영 체제를 실행하는 컴퓨터가 자원(유무선 연결을 이용한 연산, 파일, 프린터, 스캐너)을 공유하기 위해 같은 망에 참여할 수 있다. 네트워크는 컴퓨터의 운영 체제가 원격 컴퓨터의 자원에 접근하는 데 필수적이다. 마치 리소스가 로컬 컴퓨터에 바로 연결되어 있는 것처럼 보이게 만들어 준다. 여기에는 컴퓨터의 그래픽, 사운드 하드웨어를 공유하거나 네트워킹 파일 시스템을 이용하는 등 단순한 통신에서 나오는 모든 것을 포함한다. 일부 네트워크 서비스는 컴퓨터의 자원을 투명하게 접근할 수 있게 한다. 이를테면 SSH는 네트워크로 이어진 사용자들이 컴퓨터의 명령 줄 인터페이스에 직접 접근할 수 있게 한다 보안 컴퓨터의 보안은 수많은 기술이 올바르게 동작하고 있는 지에 달려 있다. 또, 운영 체제는 보안을 위하여 특정 환경에 대한 권한을 사용자나 프로그램에 개별적으로 설정하고 인증 프로세스를 제공한다. 인터넷 보안은 특히 여러 사용자가 사용하는 시스템에 적절하다. 시스템을 사용하는 각 사용자는 개인 파일을 다른 사용자가 읽을 수 없게 할 수 있다 사용자 인터페이스 GUI
  2. Real-time system은 시스템이 논리적으로 완벽하게 동작해야 함은 물론이고 정해진 시간 내에 동작하지 않을 경우 심각한 결과가 발생하는 시스템을 말한다. Soft Real-time system: 가능한 한 빠르게 임무를 수행하지만 반드시 정해진 시간 내에 수행할 필요는 없다. Hard Real-time system: 어떤 사건이 발생했을 때 정확히 동작하는 것은 물론이고 반드시 정해진 시간 내에 그 임무를 마쳐야 한다.
  3. 시간 정보의 추상화 – tick ISR 유지 보수 / 확장성 모듈화 잘 정의된 Intertask communication으로 팀 개발 용이 더 쉬운 테스팅 코드 재사용 효율성 증대 배터리 사용 시간 증대 다양한 인터럽트 활용 혼합된 처리를 요청 Peripheral 을 쉽게 control
  4. 타스크란 자기 자신이 CPU를 독점하고 있다고 생각하고 수행하는 하나의 프로그램이다.
  5. DORMANT: Task 코드는 메모리에 올라가 있지만 Multitasking kernel에 등록되지 않아 실행되지 않는 상태 READY: 언제든지 실행될 수는 있지만 우선순위가 더 높은 다른 task가 실행되고 있는 상태 RUNNUING: Task가 CPU를 점유해서 실행되고 있는 상태. WAITING: I/O처리 완료, 공유자원 사용가능 상태, 타이머의 만료 등 특정 이벤트를 기다리는 상태. ISR: 인터럽트가 발생하여 인터럽트 서비스 루틴을 실행하는 상태.
  6. DORMANT: Task 코드는 메모리에 올라가 있지만 Multitasking kernel에 등록되지 않아 실행되지 않는 상태 READY: 언제든지 실행될 수는 있지만 우선순위가 더 높은 다른 task가 실행되고 있는 상태 RUNNUING: Task가 CPU를 점유해서 실행되고 있는 상태. WAITING: I/O처리 완료, 공유자원 사용가능 상태, 타이머의 만료 등 특정 이벤트를 기다리는 상태. ISR: 인터럽트가 발생하여 인터럽트 서비스 루틴을 실행하는 상태.
  7. 스케쥴링 적용 방법에 따라 Preemptive Nonpreemptive Preemptive scheduling 프로세스 우선순위 변동여부에 따라 : 정적 또는 동적 비실시간 프로세스 스케줄링 FCFS 스케줄링(First Come First Served Scheduling) SJF 스케줄링(Shortest Job First Scheduling) SRTF 스케줄링(Shortest Remaining-Time First Scheduling) RR 스케줄링(Round Robin Scheduling) HRN 스케줄링 다단계 큐 스케줄링(Multilevel Queue Scheduling) 다단계 피드백 큐 스케줄링(Multilevel Feedback Queue Scheduling) 실시간 프로세스 스케줄링 RM 스케줄링(Rate Monotonic Scheduling) EDF 스케줄링(Earliest Deadline First Scheduling)
  8. 스케쥴링 알고리즘을 평가하는 기준
  9. Binary Semaphore는 통신 포트와 같은 자원이 하나인 경우. Counting Semaphore는 Queue Buffer 와 같은 자원 관리
  10. 전산학에서 교착 상태란 다중 프로그래밍 환경에서 흔히 발생할 수 있는 문제이다 1971년에 E. G. 코프만 교수는 교착상태가 일어나려면 다음과 같은 네 가지 필요 조건을 충족시켜야 함을 보였다. 상호배제(Mutual exclusion) : 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다. 점유대기(Hold and wait) : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다. 비선점(No preemption) : 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다. 순환대기(Circular wait) : 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다. 이 조건 중에서 한 가지라도 만족하지 않으면 교착 상태는 발생하지 않는다. 이중 순환대기 조건은 점유대기 조건과 비선점 조건을 만족해야 성립하는 조건이므로, 위 4가지 조건은 서로 완전히 독립적인 것은 아니다.
  11. http://jbear.tistory.com/86
  12. Binary Semaphore는 통신 포트와 같은 자원이 하나인 경우. Counting Semaphore는 Queue Buffer 와 같은 자원 관리
  13. 선점형, 협조형 두가지를 조합한 하이브리드형 taskYield()란 함수로 running task가 임의로 process를 양보함 SafeRTOS 파생 제품은 코드 무결성에 대해 높은 수준의 신뢰성을 제공한다. Tickless mode: OS들은 전통적으로 주기적인 timer tick을 사용한다. Idle 상태에서도 tick을 사용하는데 이것을 사용하지 않도록 개선한 것이 tickless mode이다. 주로 C로 작성된 매우 작은 소스 코드 구조
  14. ‘out of the box’ 동작과 빠른 learning 커브를 허락하는 선택된 싱글 보드 컴퓨터를 위한 Pre-configured RTOS demo application
  15. 우선순위 할당에 제약이 없다. 하나 이상의 실시간 타스크는 동일한 priority를 할당할 수 있다.
  16. The uIP TCP/IP stack the copyright of which is held by Adam Dunkels The lwIP TCP/IP stack the copyright of which is held by the Swedish Institute of Computer Science
  17. vTaskStartScheduler( void ) : Kernel Tick처리를 시작시켜 생성된 Task들과 CoRoutine를 실행시키며, 실행 시 Idle Task가 생성된다.
  18. vTaskEndScheduler( void ) : Kernel Tick을 정지시키며 생성된 모든 Task를 삭제한다. vTaskSuspendALL( void ) : 현재 호출한 Task를 제외한 다른 Task들을 중지 상태로 한다. 실제 동작은 Scheduler를 Suspend한다. vTaskResumeALL( void ) : vTaskSuspendALL()을 통해 중지상태가 된 Task들을 재개시킨다. 마찬가지로 Scheduler를 Resume하게 된다.
  19. *pcHead: Points to the beginning of the queue storage area. *pcTail: Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. *pcWriteTo: Points to the free next place in the storage area. *pcReadFrom: Points to the last place that a queued item was read from. xTasksWaitingToSend: List of tasks that are blocked waiting to post onto this queue. Stored in priority order. xTasksWaitingToReceive: List of tasks that are blocked waiting to read from this queue. Stored in priority order. uxMessagesWaiting: The number of items currently in the queue. uxLength: The length of the queue defined as the number of items it will hold, not the number of bytes. uxItemSize: The size of each items that the queue will hold. xRxLock: Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. xTxLock: Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. ucQueueNumber; ucQueueType;
  20. xQueueSend 함수는 크리티컬 섹션 선언으로 Task switching을 지시하지만 크리티컬 섹션 해제 후에 Task switching 진행 taskENTER_CRITICAL(); { /* Is there room on the queue now? To be running we must be the highest priority task wanting to access the queue. */ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) { traceQUEUE_SEND( pxQueue ); prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); /* If there was a task waiting for data to arrive on the queue then unblock it now. */ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) { if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) { /* The unblocked task has a priority higher than our own so yield immediately. Yes it is ok to do this from within the critical section - the kernel takes care of that. */ portYIELD_WITHIN_API(); } } taskEXIT_CRITICAL();
  21. prvUnlockQueue( pxQueue ): pxQueue handle을 parameter 전달 The lock counts contains the number of extra data items placed or removed from the queue while the queue was locked. When a queue is locked items can be added or removed, but the event lists cannot be updated. pxQueue->xTxLock이 0보다 큰 경우 pxQueue->xTasksWaitingToReceive를 check하여 pxReadtTaskList or xPendingReadyList에 저장하고 Priority를 check하여 Task switching을 결정한다. pxQueue->xRxLock가 1보다 큰 경우 pxQueue->xTasksWaitingToSend를 check하여 pxReadtTaskList or xPendingReadyList에 저장하고 Priority를 check하여 Task switching을 결정한다.