- 임베디드 시스템: 내부에 Computer(마이크로 프로세서/마이크로 컨트롤러)를 내장한 제품 혹은 시스템
- 일반적인 계산 목적이 아니라 특별한 임무를 수행하도록 프로그램이 내장되어 있는 시스템
- 목적에 알맞은 Processor의 특징에 의존한다
- 일반적으로 보다 큰 시스템의 일부이거나 독립됨
- 하드웨어와 소프트웨어의 변경이 매우 어려움
- 가격에 예민함
임베디드 시스템처럼 호스트 시스템과 타겟 시스템이 다를 때 애플리케이션을 개발하기 위해선:
- 효과적인 개발을 위한 특정 툴과 개발방법이 필요, 개발툴에 Hardware에 대한 Setting을 해줘야 함
- Host 시스템이 Target에 알맞은 기계어를 생성하기 위해서 Cross Toolchain이 있어야 한다
- 타켓 시스템의 디버깅을 위해 전용 디버깅 장비를 사용함
- 개발 툴에 대해서, 그리고 개발 툴이 어떻게 동작하는지에 대해서 일반 애플리케이션 개발자보다 더 많이 알고 있어야 한다.
- 하나의 프로세스가 CPU를 차지하고 있을 때, 우선순위가 높은 다른 프로세스가 현재 프로세스를 중단시키고 CPU를 점유하는 스케줄링 방식
- 실시간 응답환경, Deadline 응답환경 등 우선순위가 높은 프로세스를 빠르게 처리해야 할 경우 등에 유용
- 리눅스에서도 선점형 우선순위 Task를 지원함
- 임베디드 시스템은 반응, 동작 시간에 예민하기에 선점형 스케줄링을 지원하는 리눅스를 주로 사용함
- 네트워크 상에 연결된 다른 컴퓨터의 하드디스크를 내 컴퓨터의 하드디스크처럼 사용하는 것
- 115200, 8N1로 세팅
- Modem and Dialing 세팅은 A,B를 모두 비워줌
- 설정이 끝난 후에 Save setup as dfl 실행하여 저장
ROM의 주요 특징:
- 비휘발성: ROM은 전원이 꺼져도 저장된 데이터가 유지된다.
- 읽기 전용: 기본적으로 데이터를 읽을 수만 있고, 쓰기나 수정이 어렵다.
- 느린 접근 속도: RAM에 비해 데이터 접근 속도가 상대적으로 느리다.
- 영구 저장: 부팅 정보, 펌웨어 등 변경이 거의 없는 중요 데이터를 저장한다.
- 낮은 용량: 일반적으로 RAM보다 저장 용량이 작다.
- ROM에 파일시스템을 압축해 넣도록 설계된 cramfs라는 파일시스템이 있다. 간단하고 작으며 압축률이 높은 것이 특징이다.
이에 반해 RAM은 휘발성이며, 읽기와 쓰기가 모두 가능하고, 접근 속도가 빠르지만 전원이 꺼지면 저장된 데이터가 사라진다.
-
High Definition Multimedia Interface (고선명 멀티미디어 인터페이스)
-
HDMI는 디지털 셋톱박스, DVD 플레이어 등에서 출력되는 고화질의 디지털 멀티미디어 신호를 모니터, 디지털 텔레비전 등의 디스플레이 장치에 연결할 때 사용하는 비압축 방식의 디지털 오디오/비디오 인터페이스 규격
-
HDMI는 PC와 디스플레이의 인터페이스 표준 규격인 DVI(Digital Visual Interface)를 A/V 가전용으로 변경한 것
-
영상과 음성 신호를 압축하지 않고 플레이어에서 디스플레이 장치로 전송하기 때문에 별도의 디코더 칩이나 소프트웨어를 필요로 하지 않으며, 영상/음성/제어 신호 가 하나의 케이블로 전송되므로 기존의 번거로운 A/V 배선을 간단하게 할 수 있다.
-
2002년 12월에 HDMI 1.0의 규격이 발표됨 (현재는 HDMI 2.0까지 나옴)
-
HDMI 시스템 구조는 신호를 발생시키는 소스(Source)와 수신하는 싱크(Sink)로 구성
-
신호는 차등신호를 이용하여 신호손실을 줄인 TMDS(Transition Minimized Differential Signaling) 채널과 디스플레이 장치가 지원하는 비디오 포맷 정보를 전달하기 위한 DDC(Display Data Channel), 그리고 제어신호를 전달하기 위한 CEC(Consumer Electronics Control)로 구성되어 있다.
- Non Interlace Scanning(Progresive Scanning)
- 순차적으로 주사선을 이동
- Interlace Scanning
- 짝수, 홀수 라인을 교대로 제공
- 순차 스캔에 비해 1/2의 스캔라인 신호를 전송하기에 작은 대역폭으로 전송 가능
- 초당 60번의 데이터를 전송, 자연스럽게 초당 60회 CRT 화면에 새롭게 재생(refresh)되어 깜박거림이 없어지게 됨
- 표시
- 마지막에 p자가 붙으면 Progresive (ex. 720p, 1080p, etc..)
- 마지막에 i자가 붙으면 Interlace (ex. 1080i)
- https://blog.naver.com/fainstec_sales/221643541674
-
frame buffer란 linux system에서 그래픽을 표현할 수 있는 특정 메모리 디바이스를 말함.
-
PC라면 그래픽 카드, 일반 임베디드 시스템에서 LCD controller를 frame buffer 장치라고 함.
-
최근에는 IP화 되어서 CPU에 내장
-
frame buffer를 user level application이 제어할 수 있도록 만들어진 device driver를 frame buffer driver라고 함 (
/dev/fb0
) -
LCD에 출력하는 원리
- User level에서 전송한 frame buffer data를 LCD driver가 수신하여 LCD controller가 TFT-LCD에 출력한다.
- User level과 driver간에 “
/dev/fb0
”라는 node를 통하여 data를 전송하며, driver가 할당한 memory를 user application에서도 사용할 수 있도록 memory mapping을 한다.
- 빨간색 사각형 박스 그리는 예제
...
include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include "videodev2.h"
#include "hdmi_api.h"
#include "hdmi_lib.h"
#include "s3c_lcd.h"
#define FB_DEV "/dev/fb0"
typedef struct FrameBuffer {
int fd;
void *start;
size_t length;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
} FrameBuffer;
int fb_open(FrameBuffer *fb) {
int fd, ret;
fd = open(FB_DEV, O_RDWR);
if(fd < 0){ perror("FB Open"); return -1; }
ret = ioctl(fd, FBIOGET_FSCREENINFO, &fb->fix);
if(ret < 0){ perror("FB ioctl"); close(fd); return -1; }
ret = ioctl(fd, FBIOGET_VSCREENINFO, &fb->var);
if(ret < 0){ perror("FB ioctl"); close(fd); return -1; }
fb->start = (unsigned char *)mmap (0, fb->fix.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(fb->start == NULL) { perror("FB mmap"); close(fd); return -1; }
fb->length = fb->fix.smem_len;
fb->fd = fd;
return fd;
}
void fb_close(FrameBuffer *fb){
if (fb->fd > 0) close(fb->fd);
if (fb->start > 0) {
msync(fb->start, fb->length, MS_INVALIDATE | MS_SYNC);
munmap(fb->start, fb->length);
}
}
int main() {
int i, j, x, y, ret, endFlag=0, ch;
unsigned int *pos;
unsigned int phyLCDAddr = 0;
FrameBuffer gfb;
printf("Hdmi Draw Box Test Program Start\n");
ret = fb_open(&gfb);
if(ret < 0){
printf("Framebuffer open error");
perror("");
return -1;
}
// get physical framebuffer address for LCD
if (ioctl(ret, S3CFB_GET_LCD_ADDR, &phyLCDAddr) == -1) {
printf("%s:ioctl(S3CFB_GET_LCD_ADDR) fail\n", __func__);
return 0;
}
printf("phyLCD:%x\n", phyLCDAddr);
hdmi_initialize();
hdmi_gl_initialize(0);
hdmi_gl_set_param(0, phyLCDAddr, 1280, 720, 0, 0, 0, 0, 1);
hdmi_gl_streamon(0);
x = 50, y = 100;
pos = (unsigned int*)gfb.start;
//Clear Screen(Black)
memset(pos, 0x00, 1280*720*4);
// Draw Box
for (i=x; i<x+100; i++) {
for (j=y; j<(y+100); j++) {
pos[j*1280+i] = 0xFFFF0000; // Red
}
}
// ...
hdmi_gl_streamoff(0);
hdmi_gl_deinitialize(0);
hdmi_deinitialize();
fb_close(&gfb);
return 0;
}
-
그래픽 버퍼를 처리하는 H/W 가속 기능
- H/W 이미지 카피: 원하는 위치에 이미지 카피, 소스 이미지를 자름, H/W DMA를 통한 고속 변환 (CPU의 자원 소모 없음)
- 이미지 포맷 변환: Ex) ARGB32 -> RGB16
- 스케일 변환(이미지 크기 변환)
- 로테이션: 이미지를 회전, 반전시킴
- Alpha Blending: 반투명화
- 디스플레이 되는 영역에 메모리 Write가 일어나면 화면 깜빡임 (Flickering)이 일어남
- 여분의 버퍼에 모든 화면을 그리고 난 뒤에 해당 버퍼를 디스플레이 버퍼에 옮김
-
주기 (Period): 진동이 한 번 완전히 반복되는 데 걸리는 시간
-
주파수 (Frequency): 신호가 1초 동안 진동하는 횟수
-
진폭 (Amplitude): 진동의 중심에서 최대 변위까지의 거리, 소리의 경우 진폭이 클수록 더 큰 소리를 의미한다.
-
나이키스트의 정리
- 표본화 시 원음을 그대로 반영하기 위해서는 원음이 가지는 최고 주파수의 2배 이상으로 표본화 해야 한다.
- 음악 CD의 표본화율이 44.1KHz
사운드를 재생하거나 마이크 입력을 받을 때
- TinyALSA는 리눅스 커널에서 ALSA와 인터페이스하기위한 작은 라이브러리
- 녹음 및 플레이를 위한 기본 pcm 및 믹서 API를 제공
- 기본 API
pcm_open
: 사운드 디바이스를 사용하기 위해서 Open 한다.int pcm_write(struct pcm *pcm, const void *data, unsigned int count);
: 사운드 디바이스에 데이터를 넣는다. 즉 사운드를 Play한다.int pcm_read(struct pcm *pcm, void *data, unsigned int count);
: 사운드 디바이스로부터 데이터를 받는다. 마이크등의 입력을 Capture한다.int pcm_close(struct pcm *pcm);
: 사운드 디바이스를 닫는다.