반응형

시간 영역 vs 주파수 영역 (Spectrum Analysis)

  • 주파수란?
    • 정의 : 단위 시간당 반복되는 횟수 f [Hz]
      cos( 2πft ) → f, 주기 T = 1 / f
    • 시각화 : f = 1 Hz 면 1 초에 한 번 ‘구불 모양'
  • AC / DC 관점
구분 정의 예시
DC $f = 0 (주기 ∞) $ 배터리 3.7V
AC $f > 0 $ 60 Hz 전원, 2.4 GHz WiFi

 

  • 푸리에 변환
    • 명제: 모든 신호 = 무수한 사인, 코사인 합
      $ x(t) = \sum_k A_k \cos\left(2\pi f_k t + \phi_k\right) $
    • 실전 의미: 디지털 필터, EMI 분석, ADC 샘플링 범위 산정 때 ' 어떤 주파수 성분이 문제인가?' 를 바로 볼 수 있다.
    • 예시: rect (사각 파형) → 변환하면 sinc 함수 스펙트럼, 엣지가 가파를수록 고주파가 증가, PCB 배선에서 EMI가 원인

아날로그, 디지털 신호, 그리고 GND

포인트 아날로그 디지털
표현 연속 전압 / 전류 특정 threshold 초과 여부 (0 / 1)
관심 대역 전체 DC + 엣지의 AC (엣지 = Noise or info)

 

  • Bounce(린) : 스위칭 순간 과도(AC) 성분 때문에 전압이 튐 → 디지털 입력이 메타스테이블 or 잘못 인식
  • GND Plane : 모든 전위의 기준. 회로는 ‘GND ↔ 신호’ 루프를 최소화해야 EMI·ground bounce 감소
  • 바이패스(디커플링) 캐패시터 : AC 성분을 GND로 우회(return path) 시켜 Vcc 를 깨끗한 DC 로 유지

MCU 핀 바로 옆에 0.1 µF MLCC + 전원 인덕턴스 1 nH 미만 → 100 MHz 대역까지 효과.

 

R, L, C 핵심만 뽑기

  • 저항 (Registor)
    • 수식 $ R = \rho \frac{L}{A}$ (선 길이·굵기 따라 변함)
    • 직렬: $ R_{\text{eq}} = \sum R_i $
    • 병렬 : $\frac{1}{R_{\text{eq}}} = \sum \frac{1}{R_i}$
    • 전력: $P = I^2 R = \frac{V^2}{R}$

 

  • 캐피시터 (Capacitor)
    • 전압이 변할수록 전류가 흐른다 : $  I = C \frac{dv}{dt} $
    • 리액턴스 : $ X_C = \frac{1}{2\pi fC}$ (주파수 ↑ => 저항 ↓)
    • 용도 : 디커플링, AC 커플링, 필터 , 시정수 $\tau$ = $RC$
  • 인덕터 (Inductor)
    • 전류 변화에 저항 : $V = L\frac{di}{dt}
    • 리액턴스 : $X_L = 2\pi fL$ (주파수 ↑ => 저항 ↑)
    • 용도 : 전원 비드, 스위칭, SMPC, LC 필터

비드와 인덕터 차이 : 구조는 유사하지만 비드는 고주파 손실이 큰 소재라 저주파는 통하고 노이즈 잡는거에 특화 되어있음

 

필터 설계의 첫걸음

Low-Pass Filter (RC 예시)

  • 전달함수 $H(s) = \frac {1}{1+sRC}$ , 컷오프 $f_c = \frac{1}{2\pi RC}$
  • 용도 : 전원 레일 리플 제거, 센서 노이즈 억제

High-Pass / Band-Pass 개념도

  • HPF = CR 직렬 → 고주파만 꺼내서 오디오 톤 제어
  • BPF = HPF + LPF 조합 → 무선 수신 대역 선택

 

트랜지스터

영역 입력 출력 용도
Cut - off 너무 낮음 OFF (고저항) 스위치 '0'
Active 중간 증폭  $(I \propto \beta \cdot |\vec{B}|)$ 아날로그 Amp
Saturation 충분히 높음 온전히 ON 스위치 '1'
  • BJT vs MOSFET : FET 는 게이트에 전류 거의 안들어감→ MCU 직결 용이, 고속 스위칭·저손실.
  • Gate Charge/Qg : MOSFET 구동 시 고려해야 할 ‘충전해야 열림’. 드라이버 IC로 충·방전 속도 제어.

 

Pull up/down & Open Collector

기본 아이디어

  • Default 상태를 명확하게
    • Low-active pin → 항상 1로 당겨두고, 동작 시 0
    • High-active pin → 항상 0에 내려두고, 동작 때 1

회로 패턴

pull-up/down

 

  • 여러 마스터가 버스를 공유 → wired-AND/OR (I2C , Alert 핀 등)
  • 풀업 저항 계산 : $ R= \frac{V_{OH(min)}-V_{OL(max)}}{I_{sink(max)}} $
반응형
반응형
개인 목적으로 사용되는 카테고리로 해당 글 외 전부 비공개

RTOS란?

RTOS(Real-Time Operating System) 는 “정해진 시간 안에 반드시” 작업을 끝내야 하는 시스템에 특화된 운영체제입니다.
여기서 Real-Time 은 “빠르다” 가 아니라 예측 가능하다(Deterministic) 는 뜻이 핵심입니다.

주 목적 최대 처리량, 사용자 편의 정해진 시간 내 작업 완료
스케줄링 우선순위 + 공평성(Time-sharing) 우선순위 기반 + 선점(Preemptive)
응답 지연 ms~초 단위도 허용 μs~ms, 지터(Jitter) 최소화
메모리 관리 가상 메모리, 페이지 교체 고정/정적 할당 선호
예시 Ubuntu, Windows 11 FreeRTOS, Zephyr, VxWorks, RT-Thread

 

RTOS의 핵심 구성 요소

  1. 태스크(Task)
    • 애플리케이션 코드 단위. 우선순위와 상태(Ready, Running, Blocked) 보유
  2. 스케줄러(Scheduler)
    • 가장 높은 우선순위의 Ready 태스크에 CPU를 양보
    • Preemptive 모드: 더 높은 우선순위 태스크가 생기면 즉시 선점
  3. ISR(Interrupt Service Routine)
    • 하드웨어 인터럽트에 즉각 반응해 태스크를 깨움
  4. IPC(Queue, Semaphore, Mutex 등)
    • 태스크 간 데이터 교환과 동기화로 데드락·경쟁 조건 방지
  5. 시스템 틱(SysTick)
    • 주기적 타이머 인터럽트로 태스크 시간관리(딜레이, 타임아웃)
    • 최근엔 전력 절감을 위해 Tickless 모드도 사용

 

왜 RTOS를 쓰는가?

  • 시간 제한이 있는 작업: 모터 제어, 산업용 로봇, 차량 ECU, 의료기기
  • 멀티태스킹: bare-metal 루프는 복잡도가 급상승 → 커널이 작업 분할
  • 코드 이식성 & 생태계: 드라이버/미들웨어, POSIX 레이어, 커뮤니티 지원

RTOS 선택 시 체크리스트

  1. 하드 실시간 vs 소프트 실시간
    • 하드: 마감시간 Miss ⇒ 시스템 실패 (ABS, 항공)
    • 소프트: Miss 시 품질 저하 허용 (오디오 스트리밍)
  2. 메모리/플래시 Footprint
    • 소형 MCU(수-십 KB)인지, 애플리케이션 프로세서(MB)인지
  3. 라이선스/커뮤니티
    • 상용(VxWorks, INTEGRITY, QNX 등) vs 오픈소스(FreeRTOS, Zephyr)
  4. 안전 인증(ASIL, SIL) 필요 여부
    • 자동차/의료 분야는 ISO 26262, IEC 61508 인증 지원 확인
  5. 툴체인 & 디버깅
    • Tracealyzer, Segger SystemView 등 실시간 분석 툴 지원
반응형
반응형

📌 ROM 코드

 

 

🧱 ROM 코드란?

  • 전원이 켜지거나 리셋된 직후 실행되는 SoC 내장 코드
  • 칩 제조 시 내장됨수정 불가 / 오픈소스 대체 불가
  • 외부 메모리 사용 전 실행되어야 하므로 온칩 SRAM만 사용
  • DRAM 컨트롤러 초기화 코드 없음 (디바이스마다 다르기 때문)

💾 SRAM 크기

  • SoC마다 다름 (보통 4KB ~ 수백 KB 수준)

📥 ROM 코드의 역할

  • 다양한 저장 장치에서 작은 코드 조각을 SRAM으로 로드
  • 예시
    • NAND Flash 앞쪽 페이지
    • SPI Flash
    • MMC/eMMC/SD 카드 첫 섹터 또는 MLO 파일
  • 로드 실패 시
    • 이더넷, USB, UART로 바이트 스트림 수신 시도 (UART는 주로 생산 과정에서 플래시에 코드 쓰기 위해 사용)

🔁 SPL (Secondary Program Loader)

  • SRAM 공간이 작아 U-Boot 같은 전체 부트로더를 못 넣는 경우 사용
  • SPL이 중간 단계 부트로더 역할 수행

🔚 종료 시점

  • SPL이 SRAM에 로드됨
  • ROM 코드는 SPL의 시작 지점으로 점프

 


SPL (Secondary Program Loader)

🔧 SPL의 역할

  • DRAM에 TPL(Tertiary Program Loader)을 로드하기 위한 준비 단계
  • 메모리 컨트롤러 및 필수 하드웨어 설정
  • 온칩 SRAM 내에서 실행되며, 용량 제한 있음

📥 코드 로드 기능

  • ROM 코드와 유사하게 저장장치에서 코드 읽기 가능
    • 플래시의 프리셋 오프셋에서 로드
    • 파일 시스템 드라이버가 내장되어 있다면 u-boot.img 같은 파일 이름 기준 로딩도 가능

👤 사용자 인터페이스

  • 보통 사용자 입력은 불가능
  • 하지만 콘솔에 버전 정보, 진행 상황 출력 가능

💾 오픈소스 vs 바이너리

  • TI의 x-loader, Atmel의 AT91Bootstrap 등은 오픈소스 SPL
  • 제조사 제공 바이너리 블롭 형태의 SPL도 흔함

🧠 종료 시점

  • TPL이 DRAM에 로드됨
  • SPL이 해당 위치로 점프하여 TPL 실행

📊 부트 순서 다이어그램

 


TPL (Tertiary Program Loader)

🚀 TPL이란?

  • 이제 전체 기능의 부트로더(U-Boot 등) 실행됨
  • DRAM에서 실행되며, 부트 로딩의 최종 단계
  • 사용자 인터페이스, 명령어 기능, 자동 부트 등 포함

🛠 주요 기능

  • 커널 및 부트 이미지 로드 / 업데이트
  • 커널 자동 부팅 기능 포함 가능
  • FDT (Device Tree) 및 initramfs를 커널 이미지에 추가 가능 → 모든 구성 요소를 DRAM에 적재 가능

👤 사용자 인터페이스

  • 커맨드라인 UI 제공
  • 플래시에 이미지 저장하거나, 커널 수동/자동 부팅 가능

🧠 종료 시점

  • 커널 이미지가 DRAM에 완전히 적재됨
  • TPL이 커널로 제어를 넘김
  • 커널 실행 이후, TPL 및 이전 부트로더는 메모리에서 사라짐

📊 부트 순서 다이어그램

반응형
반응형

🧠 부트로더의 두 가지 주요 역할

  1. 시스템 초기화
    • 최소한의 시스템만 초기화 (DRAM, 인터페이스 등 아직 미설정)
  2. 커널 로드
    • 커널을 메모리에 로드하고 실행 환경 구성

⚙️ 부트 순서 요약

  1. 전원 ON 또는 리셋 시점
    • 시스템은 매우 제한된 상태
    • 동작 가능한 자원: CPU 코어, 온칩 메모리, 부트 ROM
  2. 초기 부트 코드 실행
    • DRAM 컨트롤러 설정
    • 메모리 접근 가능하게 됨
    • 부트로더 코드를 DRAM으로 복사
  3. 커널 로드 및 실행 준비
    • 커널을 플래시에서 DRAM으로 복사
    • 하드웨어 설정 정보와 커널 커맨드 라인을 커널에 전달
    • 제어를 커널로 넘김 → 부트로더는 더 이상 필요 없음

🧱 예전의 단순한 부트 구조 (NOR Flash 사용 시)

 

🔹 특징

  • 부트로더를 리셋 벡터(0xFFFFFFFC) 위치에 배치
  • NOR Flash는 직접 주소 매핑 가능 → 실행 간편
  • 초기 점프 명령어로 부트로더 코드 실행 시작

🔸 동작 흐름

  1. NOR Flash에서 부트로더 실행
  2. DRAM 초기화 후, 부트로더를 DRAM으로 복사
  3. 커널을 플래시에서 DRAM으로 복사
  4. 커널 실행

🌀 복잡한 현대 부트 시퀀스

  • NOR Flash가 아닌 다른 저장장치 사용 시 (e.g. NAND, eMMC 등)
  • 부트 과정이 멀티 스테이지로 복잡해짐
  • SoC에 따라 부트 절차가 매우 다름
  • 일반적으로:
    1. 부트 ROM → 1단계 부트로더
    2. 1단계 → 2단계 부트로더
    3. 2단계 → 커널 로딩

 

반응형
반응형

임베디드 리눅스 프로그래밍 완전정복

 

 

툴체인

  • 소스 코드를 타깃 장치에서 실행할 수 있는 실행 파일
  • 컴파일러, 링커, 런타임 라이브러리를 포함하는 컴파일 도구들의 집합
  • 리눅스 시스템의 나머지 세 가지 요소 (부트로더, 커널, 루트파일시스템)를 빌드하기 위해 툴체인이 필요
  • 리눅스용 툴체인은 대부분 GNU 프로젝트에서 만들어진 요소에 기반을 두고 있다.

GNU 툴체인 세 가지 주요 요소

  • Binutils: 어셈블리와 링커를 포함하는 바이너리 유틸리티의 집합
  • GCC: C와 여러 언어를 위한 컴파일러, 공통 백엔드를 사용해 어셈블리 코드를 만들고, GNU 어셈블러로 넘긴다.
  • C 라이브러리: POSIX 규격에 기반을 둔 표준 API

종류

 

CPU 아키텍처

  • CPU 종류: ARM, MIPS, x86_64 등
  • Big endian / Little endian: 두 가지 모드로 동작 할 수 있는 CPU가 있지만, 기계어 코드가 다르다.
  • ABI ( Application Binary Interface): 함수 호출간에 인자를 넘기는 호출 규칙

 

Ubuntu 20.04 LTS 에 설치하는 명령어

$ sudo apt-get install autoconf automake bison bzip2 cmake \ 
flex g++ gawk gcc gettext git gperf help2man libncurses5-dev libstdc++6 libtool \ 
libtool-bin make
patch python3-dev rsync texinfo unzip wget xz-utils

 

권장 설치 명령어 예시

$sudo apt-get update
$sudo add-apt-repository universe
$sudo apt-get install autoconf automake bison bzip2 cmake \
$flex g++ gawk gcc gettext git gperf help2man libncurses5-dev \
$libstdc++6 libtool make patch python3-dev rsync texinfo unzip wget xz-utils

 

반응형
반응형
Audio/Video Device에 접근할 수 있도록 하는 일종의 Kernel API

 

V4L2 Flow

 

동작 순서

  • Application에서 ioctl을 이용하여 카메라 그동에 필요한 명령을 순차적으로 전송
  • 명렁들의 순서가 바뀌거나 누락되는 경우 V4L2 드라이버에서 오류 발생 확률 증가

  • QBUF, DQBUFC, STREAMON은 일반적으로 반복 수행 되어야 영상을 얻을 수 있다.
  • 위 동작을 반복하지 않는다면 1 프레임만 얻을 수 있다.
    • 대부분 반복문을 사용해서 지속성을 유지 시킴

QEURYCAP (Query Capability)

  • 수행되어야 하는 명령 중 가장 간단한 것 중 하나로 연결된 디바이스 이름
  • 수행 가능한 동작 등 장치의 정보를 사용자 영역에 알려주는 역할
  • 정보들을 v4l2_capability 구조체에 저장

S_FMT_VID_CAP

  • 비디오 디바이스를 실질적으로 동작 시키기 전, 디바이스 몇 부분을 설정하는 명령어
  • 이미지 포맷, 해상도 등등

V4L2 기본 개념 정리

  • V4L2 애플리케이션 (User-Space)
    • /dev/videoX 장치를 open() 해서 접근
    • ioctl() 호출을 통해 드라이버와 상호작용
    • ex) GStreamer, OpenCV, FFmpeg 등에서 활용
  • V4L2 드라이버 (Kernel-Space)
    • 카메라 센서 드라이버, ISP 드라이버, MIPI CSI/USB 드라이버가 포함됨.
    • V4L2 프레임워크를 사용하여 VIDIOC_* 명령을 처리
  • V4L2 장치 (Hardware)
    • 카메라 센서, 비디오 캡처 카드, SoC의 ISP(이미지 프로세서) 등 물리적인 하드웨어
User-Space:
  - open("/dev/video0")
  - ioctl(VIDIOC_QUERYCAP)   -> 드라이버에게 장치 정보 요청
  - ioctl(VIDIOC_S_FMT)      -> 해상도, 포맷 설정
  - ioctl(VIDIOC_REQBUFS)    -> 버퍼 요청
  - ioctl(VIDIOC_QBUF)       -> 버퍼를 큐에 넣음
  - ioctl(VIDIOC_STREAMON)   -> 스트리밍 시작
  - ioctl(VIDIOC_DQBUF)      -> 캡처된 프레임 가져오기

Kernel-Space (드라이버):
  - 위 요청을 받아 처리 후 응답

 

V4L2 장치 파일 : /dev/videoX

  • /dev/video0, /dev/video1 … 같은 형태로 존재
  • ls /dev/video* → 연결된 V4L2 장치 확인 가능

V4L2 드라이버 정보 조회 : VIDIOC_QUERYCAP

  • ioctl(fd, VIDIOC_QUERYCAP, &cap) 호출 시 드라이버가 지원하는 기능 확인 가능
struct v4l2_capability cap;
ioctl(fd, VIDIOC_QUERYCAP, &cap);
printf("Driver: %s\n", cap.driver);
printf("Device: %s\n", cap.card);
printf("Bus: %s\n", cap.bus_info);
printf("Capabilities: %08x\n", cap.capabilities);

 

V4L2 포맷 설정 : VIDIOC_S_FMT

  • 영상 크기나 픽셀 포맷을 설정
  • 포맷은 V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_MJPEG 등 이 있음
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 1920;
fmt.fmt.pix.height = 1080;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

ioctl(fd, VIDIOC_S_FMT, &fmt);

 

V4L2 버퍼 관리 : Memory buffering

V4L2에서는 프레임을 저장할 버퍼를 미리 할당하고, 장치와 사용자 공간이 이를 공유

버퍼 할당 (VIDIOC_REQBUFS)

  • V4L2_MEMORY_MMAP또는 V4L2_MEMORY_DMABUF(DMA) 방식 사용 가능
struct v4l2_requestbuffers req;
memset(&req, 0, sizeof(req));
req.count = 4;  // 버퍼 개수
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;

ioctl(fd, VIDIOC_REQBUFS, &req);
  • V4L2_MEMORY_DMABUF로 하면 CPU 개입 없이 DMA로 직접 전송 가능.

버퍼 매핑 (VIDIOC_QUERYBUF, mmap())

  • 드라이버에서 할당된 버퍼를 mmap()을 이용해 사용자 공간으로 매핑
struct v4l2_buffer buf;
buf.index = 0;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;

ioctl(fd, VIDIOC_QUERYBUF, &buf);
void *buffer_start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);

 

V4L2 CAPTURE FLOW

V4L2에서는 Queue와 Dequeue 방식으로 프레임 처리

VIDIOC_QBUF

  • 비디오 버퍼를 장치에 등록
struct v4l2_buffer buf;

buf.index = 0;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;

ioctl(fd, VIDIOC_QBUF, &buf);

 

VIDIOC_STREAMON

  • 장치에서 캡처된 데이터를 가져옴
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(fd, VIDIOC_STREAMON, $type)

 

VIDIOC_DQBUF

  • 장치에서 캡처된 데이터를 가져옴
struct v4l2_buffer buf;

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;

ioctl(fd, VIDIOC_DQBUF, &buf);
process_frame(buffer_start);  // 프레임 데이터 처리
ioctl(fd, VIDIOC_QBUF, &buf);  // 다시 큐에 넣기
  • 위와 같은 방식으로 프레임이 큐 → 캡처 → 디큐 → 다시 큐 방식으로 순회

V4L2 기본 플로우

1. open("/dev/video0")  // 장치 오픈
2. ioctl(VIDIOC_QUERYCAP)  // 장치 정보 확인
3. ioctl(VIDIOC_S_FMT)  // 포맷 설정
4. ioctl(VIDIOC_REQBUFS)  // 버퍼 요청
5. ioctl(VIDIOC_QUERYBUF)  // 버퍼 정보 확인
6. mmap()  // 버퍼 매핑
7. ioctl(VIDIOC_QBUF)  // 버퍼 큐잉
8. ioctl(VIDIOC_STREAMON)  // 스트리밍 시작
9. ioctl(VIDIOC_DQBUF)  // 프레임 가져오기
10. ioctl(VIDIOC_QBUF)  // 버퍼 다시 큐에 넣기
11. ioctl(VIDIOC_STREAMOFF)  // 스트리밍 종료
12. close(fd)  // 장치 닫기
반응형

'임베디드 개발 노트' 카테고리의 다른 글

ARM assembly  (0) 2025.02.20
Basic #1  (0) 2024.08.26
SocketCAN  (0) 2024.04.22
ALSA  (0) 2023.12.21
Automotive SPICE (업데이트 中)  (0) 2023.06.20
반응형

ARM Register 구성

  • 범용 레지스터 (GPR) : General Purpose Register
    • R0 - R12
  • 특수 레지스터 (SPR) : Special Purpose Register
    • R13 (SP): Stack Pointer register
    • R14 (LR): Link Register
    • R15 (PC): Program Counter
  • CPSR: 상태 레지스터

ARM Assembly 특징

  • 첫 operand는 반드시 레지스터 이름이어야 한다.
  • immediate는 상수 앞에 “#”을 붙인다.
    • 단, LDR 명령어에서만은 예외적으로 “=’를 사용한다.
  • 간접 참조는 “[ ]” 를 사용한다.
  • 다른 ISA에 비해 비교적 간단.
  • x86처럼 push, pop이 없어서 RISC-V 처럼 SP를 일일이 계산해줘야 한다.
  • ARM은 RISC-V 처럼 32 비트의 고정된 명령어 길이를 갖는다.

MOV

  • 데이터 이동에 MOV명령이 사용된다.
    • cf. MOV stands for Move.
  • 단, 메모리 Load/Store 연산에도 MOV가 사용되는 x86과는 달리 레지스터 사이나 Immediate 연산에서만 사용된다.

ex)

  • MOV R0, R1 : R1의 값을 R0에 저장
  • MOV R0, #23 : immediate 23을 R0에 저장
  • immediate는 **#**으로 명시한다.

LDR

  • 메모리에서 레지스터로 데이터를 가져오는 로드 연산
    • cf. LDR stands for Load to Register
  • 레지스터에 immediate 값을 저장할 때도 사용
    • cf. MOV보다 큰 범위의 immediate 값을 명시할 때 , # 대신 **=**가 사용
  • ex)
    • LDR R0, = 0x1234: immediate 0x1234 값을 R0에 저장

STR

  • 레지스터 값을 메모리에 저장하는 Store 연산
    • cf. STR stands for Store

Indirect Addressing Mode

  • ARM 주소 지정 모드 중 간접 주소 지정이 존재
  • [ ] 를 사용한다.
  • C언어 포인터에 사용되는 간접 지정 연산자(*)와 비슷

ex)

  • STR R0, [R1]: R1에 저장되어 있는 값을 주소로서 참조한 메모리 공간에 R0 값을 저장
  • LDR R0, [R1]: R1에 저장되어 있는 값을 주소로서 참조한 메모리 공간에 존재하는 값을 R0으로 로드
    • LDR R0, [0x1234] 은 사용 불가

Base Plus Offset

Post-indexing

  • base 로 명령어 실행 후 base에 offset 을 더하여 base 를 갱신
    • LDR R0, [R1], #4: R1 주소에 있는 값을 R0으로 로드 후 R1 값에 +4를 수행
    • LDR R0, [R1], R3, LSL #2: R1주소에 있는 값을 R0으로 로드 후 R3의 값에 2번 왼쪽 시프트를 한 값을 더하기 수행
  • ex)

Pre-indexing

  • 명령어를 실행하기 전 base에 offset을 더하는 방식
  • base 값은 갱신하지 않는다.
    • LDR R0, [R1, #4]: R1 + 4 주소에 있는 값을 R0으로 로드 수행
  • ex)

Auto-indexing

  • Pre-indexing과 동일하지만, base 값을 갱신한다는 점이 다름
  • Pre-indexing 명령어 뒤에 ! (suffix)를 붙여서 사용
    • LDR R0, [R1, #4]!: R1 + 4 주소에 있는 값을 R0으로 load하고, R1 값은 갱신한다.
  • ex)

ADD

  • ADDS처럼 suffix s가 붙은 명령은 동일하게 동작하지만, ARM 프로세서의 모드를 바꾼다.
    • ADD R0, R1, R2: R0 = R1 + R2
    • ADD R0, R1, #128 ; R0 = R1 + 128
  • ex)

SUB

SUB R0, R1, R2: R0 = R1 - R2

SUB R0, R1, #128: R0 = R1 - 128

Data Types in ARM Core

  • Byte: 8 bits
  • Halfword: 16 bits
  • Word: 32 bits
  • Doubleword: 64 bits

Processor registers are 32 bits in size.

Declaration

keyword bytes

.byte 1
.hword 2
.word 4
.quad 8
.octa 16
반응형

'임베디드 개발 노트' 카테고리의 다른 글

V4L2 (Video 4 Linux 2)  (0) 2025.02.26
Basic #1  (0) 2024.08.26
SocketCAN  (0) 2024.04.22
ALSA  (0) 2023.12.21
Automotive SPICE (업데이트 中)  (0) 2023.06.20
반응형
순서 상관없이 마음대로 정리하는 게시글 입니다.

Program

  • 프로그램의 실행은 파일 시스템에 존재하던 실행 파일이 메모리에 적재 된다는 뜻
    • 파일 시스템에 있는 실행 파일이 메모리에 적재될 때 실행 파일 전체가 메모리에 적재되지 않으며 일부분만 메모리에 올라가고 나머지는 디스크의 특정 영역인 스왑 영역에 존재한다.
  • 프로그램이 CPU를 할당받고 명령을 수행하고 있는 상태

Process Address Space

    • code
      -. 시스템 콜, 인터럽트 처리 코드
      -. CPU, 메모리 등 자원 관리를 위한 코드
      -. 편리한 인터페이스 제공을 위한 코드
  • data
    -. PCB(Process Controll Block) : 현재 수행 중인 프로세스의 상태, CPU 사용 정보 등을 유지하기 위한 자료구조
    -. CPU, Memory 등 하드웨어 자원을 관리하기 위한 자료구조가 저장
  • stack 
    -. 각 Process의 커널 스택을 저장
    -. 프로세스는 함수 호출시 자신의 복귀 주소를 저장하지만, 커널은 커널 내의 주소가 된다.
    -. 각각의 프로세스마다 별도의 스택을 두어 관리한다.
커널은 힙메모리를 사용하지 않는다. 커널은 리눅스에서 동적메모리 할당을 위해 필요한 기능들을 커널이 제공하는데, 운영체제는 커널에서 제공하는 기능을 사용해서 메모리 풀(memory pool)을 관리한다.

  • Process address space는 프로세스가 코드에서 참조하는 논리적 주소 집합.
    → 허용되는 32비트 주소의 경우 주소 범위는 0에서 0x7FFFFFFF. (2^31개의 가능한 숫자)
  • 프로세스에는 프로세스 주소 공간 ( 가상 주소 공간) 이라는 논리 메모리 영역이 있으며 물리 주소 영역에 맵핑
    • 일반적으로 0에서 최대 주소까지 연속적인 메모리
    • 물리적 메모리는 연속적이지 않을 수 있다.
  • 프로세스가 동적 메모리를 요청할 때 (예시 : malloc()을 통해), 추가적인 물리적 메모리를 할당받는 것이 아니라, 새로운 범위의 가상 주소 공간을 사용할 권리를 부여받습니다.
주소 유형 설명
Physical address 컴파일 후 프로그램이 주 메모리에 로드되면 로더는 물리 주소에 대한 맵핑을 생성
Relative address 컴파일 할 때 컴파일러는 심볼 주소를 상대 주소로 변환
Symbolic address 소스 코드에서 참조되는 주소가 대부분이며, 구성 요소는 변수 명, 상수 및 명령어 레이블

Processor : 컴퓨터 시스템 안에 있는 CPU

 

  • 프로세서와 메모리는 컴퓨터 시스템에 있어 중요한 부분
  • 프로세서는 컴퓨터의 여러 연산을 담당하는 핵심 부분
  • 메모리는 프로세서가 효율적으로 동작을 할 수 있게 도와주는 조력자 역할
  • 프로세서는 저장장치에 직접적으로 접근할 수 없고 메모리를 거쳐야 함

Stack / Heap Memory

프로그램이 실행 중일 때 메모리를 차지한다.

때로는 할당되는 메모리를 알지 못할 수도 있으며, 새 변수를 만들 때마다 프로그램은 해당 변수를 저장하기 위해 더 많은 메모리를 할당한다.

 

Memory Layout

실행 중인 각 프로그램은 다른 프로그램과 분리된 자체 메모리 레이아웃을 가지고 있으며, 레이아웃은 다음을 포함한 많은 세그먼트로 구성된다.

 

  • Stack : 지역 변수 저장
  • Heap : 프로그래머가 할당할 수 있는 동적 메모리
  • Data : 초기화된 변수와 초기화되지 않은 변수로 구분된 전역 변수를 저장
  • Text : 실행되는 코드를 저장

프로그램 메모리의 각 메모리 위치를 정확히 파악하기 위해 메모리의 각 바이트에 주소를 할당하며, 주소는 0에서 가능한 가장 큰 주소까지 이어진다.

 

C++ Program Memory layout

주소를 16진법 숫자로 표현한다.

예를 들어, 가능한 가장 작은 주소는 0x00000000(0x는 16진법을 의미함)이고 가능한 장 큰 주소는 0xFFFFFFFF이다.


스택 (Stack)

  • 스택 세그먼트는 메모리의 높은 주소에 있다.
  • 함수가 호출될 때마다 해당 함수에 스택 메모리를 할당한다.
  • 새로운 지역 변수가 선언되면 해당 함수에 변수를 저장하기 위해 더 많은 스택 메모리가 할당된다.
  • 할당이 된다면 스택은 아래로 증가한다.
  • 함수가 반환되면 함수의 스택 메모리 할당이 해제되고, 모든 로컬 변수가 무효화됨을 의미한다.
  • 스택 메모리의 할당 및 할당 해제는 자동으로 수행된다.

 

 

반응형

'임베디드 개발 노트' 카테고리의 다른 글

V4L2 (Video 4 Linux 2)  (0) 2025.02.26
ARM assembly  (0) 2025.02.20
SocketCAN  (0) 2024.04.22
ALSA  (0) 2023.12.21
Automotive SPICE (업데이트 中)  (0) 2023.06.20
반응형

Configure a SocketCAN Interface

# ls /sys/class/net
can0  can1  eth0  lo
  • can0, can1을 사용할 수 있지만 활성화되어 있지는 않습니다.

 

# ifconfig -a
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:29

can1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:31

eth0      Link encap:Ethernet  HWaddr B2:06:10:A8:3D:F7
          inet addr:192.168.13.63  Bcast:192.168.13.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4122 errors:0 dropped:961 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:358370 (349.9 KiB)  TX bytes:0 (0.0 B)
          Interrupt:35

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
  • 사용 가능한 네트워크 인터페이스를 확인합니다

 

# ip link set can0 up type can bitrate 500000
  • can0 을 활성화 하려면 위와 같이 설정합니다.

 

# ip -details link show can0
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
    link/can  promiscuity 0 minmtu 0 maxmtu 0
    can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
        bitrate 500000 sample-point 0.875
        tq 12 prop-seg 69 phase-seg1 70 phase-seg2 20 sjw 1 brp 1
        m_can: tseg1 2..256 tseg2 2..128 sjw 1..128 brp 1..512 brp_inc 1
        m_can: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..32 dbrp_inc 1
        clock 80000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

 

  • can0 세부 설정 정보 확인합니다

 

# ip link set can0 down
  • can0 비활성화 방법

 

SocketCAN : Example C code

 

#include <net/if.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <unistd.h> 
#include <cstring> 
#include <iostream>
#include <cstdlib>

int main() 
{
    int s;
    struct sockaddr_can addr;
    struct ifreq ifr;
    struct can_frame frame;

    system("ip link set can0 up type can bitrate 500000"); 

    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

    strcpy(ifr.ifr_name, "can0");
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    bind(s, (struct sockaddr *)&addr, sizeof(addr));

    frame.can_id = 0x123; 
    frame.can_dlc = 4; 
    frame.data[0] = 0xFF; 
    frame.data[1] = 0xFF; 
    frame.data[2] = 0xFF; 
    frame.data[3] = 0xFF; 

    write(s, &frame, sizeof(struct can_frame));

    close(s);

    system("ip link set can0 down"); 
}
반응형

'임베디드 개발 노트' 카테고리의 다른 글

ARM assembly  (0) 2025.02.20
Basic #1  (0) 2024.08.26
ALSA  (0) 2023.12.21
Automotive SPICE (업데이트 中)  (0) 2023.06.20
CAN (업데이트 中)  (0) 2023.06.20
반응형

ALSA (Advanced Linux Sound Architecture)

  • 리눅스 운영체제에서 오디오 기능을 관리하고 제공하기 위한 디바이스 프레임워크
  • User Space Library / Kernel Space Driver를 지칭
  • Linux AUDIO
  • 오픈 소스 / 라이센스 : GPL , LGPL

 


ALSA Kernel driver

  • ALSA Kernel driver는 사용자 공간의 시스템 콜에 대응 (System call : open, ioctl, write, read, close)
  • Device driver로 부터의 요청에 대응 (Register, Unregister, Update)
  • ALSA Kernel driver는 사용자 공간과 사운드카드 디바이스 드라이버의 인터페이스를 담당하며, 오디오 버퍼 및 시그널을 관리 및 운용


ALSA Library

  • 어플리케이션에게 공통된 API를 제공하여 ALSA Kernel driver를 사용할 수 있도록 함
  • ALSA Library도 복잡한 구성으로 이루어져 있음
  • ALSA Library가 /dev/snd/* 의 device file을 제어함으로 Application에서 device file을 open, close 할 필요가 없음


ALSA SoC

ALSA SoC layer (driver)

  • ALSA는 x86의 사운드 카드 때문에 생겨남
  • 임베디드 프로세서에 대응하기 위하여 ALSA SoC Layer가 생성됨

    ASoC (ALSA SoC) 의 목표
    • Audio Codec Driver 독립적 및 재사용 가능 하도록 설계
    • Audio Codec 과 I2S 및 PCM Audio interfac의 연결을 쉽도록 설계
    • Dynamic Audio Power Management(DAPM) 설계 (Audio Codec 내 Power Block 자동 제어 알고리즘)
    • Pop 및 Click 잡음 감소 (Audio Codec의 Power를 up/down 하면서 생겨나는 잡음을 줄임)
    • Board 특정 컨트롤을 위해 설계. 예를들면 스피커 앰프를 위한 소리 제어
        → ASoC의 도움 없다면 Audio Function과 별개로 GPIO 제어로 스피커 앰프를 ON/OFF 시켜야 한다)    

        ASoC driver 구분    

  1. Codec : Audio Codec Control을 제어
  2. Platform : SoC DMA 제어
  3. Machine : Audio 관련 Device 연결 상태 정의 및 제어
  4. Component (DAI) : I2S 및 I2C,PCM,PDM...( Audio Interface)을 제어


Embedded System Audio Circuit

 

Audio Circuit & ASoC Driver

Codec driver는 audio codec을 제어하는 driver

 

Platform driver는 dma와 memory 관련 driver (alloc / free)

 

ALSA Operation diagram

x86 / Embedded system ALSA 구조

 

 

Playback , Capture

ASoC drive들은 Playback(Capture)시 매번 호출 되는 구조는 아니며, 처음 한번 연결할 때 호출된다.

 

 

ALSA Buffer FIFO 동작 방식

# 그림의 데이터 쓰기 및 쓰기 순서 표현은 숫자로 표기한다.

1. 500ms 분량의 버퍼가 있고, 100ms 5개로 나눴다고 가정.                 

2. 앱에서 사용자가 100ms 데이터를 2번 쓰기를 했을 경우 그림은 아래와 같다.

 

3. 데이터가 버퍼에 다 채워졌을때는 아래와 같고 앱에서는 더이상 쓸 공간이 없기 때문에 슬립(Sleep) 상태로 변환된다.

 

4. 오디오 장치가 100ms 데이터를 출력하였을 때, 1번 데이터를 소진한 것이므로 버퍼에 여유 공간이 생긴다.

 

5. 기존에 슬립하고 있던 앱에서 깨어나서 데이터 출력으로 생겨난 여유 공간에 데이터를 다시 채운다.
(Sleep, Wakeup for write)이 반복된다.

 

ALSA Mixer

Audio Codec

ALSA는 사용자 공간(User Space)에서 오디오 코덱을 제어하기 위해서 Mixer(SND CONTROL)을 사용한다.

사용자 공간에서 오디오 코덱의 레지스터에 직접 접근하지 않는다.

 

계속 작성 진행 중

반응형

'임베디드 개발 노트' 카테고리의 다른 글

Basic #1  (0) 2024.08.26
SocketCAN  (0) 2024.04.22
Automotive SPICE (업데이트 中)  (0) 2023.06.20
CAN (업데이트 中)  (0) 2023.06.20
Analog /Digital Signal , Ground  (0) 2023.04.06

+ Recent posts