라즈베리파이로 임베디드 공부하는 방법
●디바이스 제어 방법과 비트 연산(AND/OR 등) 및 비트 값 출력 확인 방법
디바이스 제어 방법에는 비트 연산(AND, OR 등)과 비트 값의 출력 확인 방법이 포함됩니다. 이번 설명에서는 라즈베리파이 4를 기준으로 임베디드 공부 방법을 소개합니다. 라즈베리파이 3를 사용하시는 경우에도 이 방법을 적용할 수 있습니다.
비트 연산은 기초적이지만, 준비되지 않은 상태에서는 어렵게 느껴질 수 있습니다. AND 연산은 두 비트 모두 1일 때 결과가 1이 되고, OR 연산은 두 비트 중 하나라도 1이면 결과가 1이 됩니다. 이러한 비트 연산을 통해 하드웨어를 제어하는 것이 중요하며, 기본적인 내용이지만 반드시 숙지해야 합니다.
디바이스를 제어할 때는 syscall, proc, sys 등의 특수 파일 또는 시스템 콜을 기준으로 하며, 대부분 비트 연산을 사용합니다. 예를 들어, GPIO를 통해 하드웨어를 제어할 때 출력 모드 변경이나 값 지정에 비트 연산을 사용할 수 있습니다. 비트 연산 이해 없이 하드웨어 조정을 시도하면 어려움을 겪을 수 있습니다.
또한, 시프트 연산을 통해 값 변경도 중요한 개념입니다. 이는 곱하기나 더하기 연산보다 빠르게 값을 조정할 수 있으며, 하드웨어 제어에 있어 특정 비트를 켜거나 끄는 등의 조작을 간편하게 할 수 있도록 합니다.
비트 연산 외에도 XOR 등 다양한 복잡한 연산이 존재하지만, 기본적인 내용부터 숙지하는 것이 중요합니다. 공부를 너무 깊게 할 필요는 없으며, 기본적인 이해를 바탕으로 시작하는 것이 좋습니다.
●라즈베리파이 4 GPIO 구조
하드웨어 문서를 읽는 것은 라즈베리파이 4를 비롯한 임베디드 시스템을 공부하는 데 중요한 두 번째 단계입니다. 하드웨어 구조, 특정 보드에 대한 구조 등을 이해하는 것이 필요하며, 레퍼런스 보드를 포함하여 다양한 하드웨어 문서를 참고해야 합니다. 실제 업무에서 다루게 될 특정 보드들을 이해하고, 필요한 경우 하드웨어를 재구성하는 것이 포함됩니다.
대부분의 경우, 제조사에서 제공하는 보드를 약간 수정하여 사용하게 됩니다. 이 과정에서 스키마, 데이터 시트 등의 문서를 참고해야 하는데, 이러한 문서를 읽는 것은 쉽지 않습니다. 공부할 내용이 방대하기 때문에, 핵심 포인트를 집어 공부하는 것이 효율적입니다.
예를 들어, GPIO나 LED와 같은 구체적인 하드웨어 부품을 중심으로 학습하는 것이 좋습니다. 세부적인 부분을 일일이 이해하려 하기보다는, 선택한 하드웨어 포인트를 사용하는 데 집중하는 것이 필요합니다. 이를 통해 하드웨어를 켜고 끄는 기본적인 동작을 먼저 실습하고, 이후에 스키마나 데이터 시트를 참고하여 더 자세히 학습하는 것이 좋습니다.
예를 들면, 라즈베리파이에서 빨간색 또는 초록색 LED의 상태를 확인하고 이를 조정해 보는 실습을 할 수 있습니다. 이런 간단한 실습을 통해 하드웨어를 더 잘 이해할 수 있습니다.
학습 방법으로는 사용자 레벨에서 시작하여 점차적으로 더 자세한 정보로 들어가는 탑-다운 방식을 추천합니다. 이 방식은 초기에 간단한 확인을 통해 하드웨어의 동작 원리를 이해하고, 점차 디바이스에 대한 깊은 지식을 쌓아가는 방법입니다.
●현재 시스템에서 디바이스 트리(Device Tree Binary(.dtb)) 정보확인 (GPIO 확인)
현재 시스템에서 디바이스 트리(Device Tree Binary, .dtb) 정보를 확인하는 것은 하드웨어의 구성과 소프트웨어 설정을 이해하는 데 중요한 단계입니다. 디바이스 트리는 하드웨어의 구성 요소, 예를 들어 메모리, 버스, 주변 장치 등을 제어하기 위해 다양한 주소와 설정이 기술된 파일입니다.
디바이스 트리 정보 확인을 위해 첫 번째 단계로, 하드웨어 문서(스키마, 데이터 시트 등)를 확인하고, 실제 하드웨어와 비교해야 합니다. 그 다음 단계로, 소프트웨어 설정과의 연결을 확인해 보는 것이 필요합니다. 여기에는 시스템 콜을 사용하여 실제 하드웨어를 비트 단위로 제어하는 방법 등이 포함됩니다.
디바이스 트리 파일을 확인하기 위해, 예를 들어 /proc/cpuinfo를 통해 현재 시스템에 접속된 라즈베리 파이 정보와 커널 버전 등을 확인할 수 있습니다. 또한, dtc (Device Tree Compiler) 명령어를 사용하여 .dtb 파일을 읽고, 해당 디바이스 트리 정보를 분석할 수 있습니다.
GPIO 제어 방법으로는 /sys/class/gpio 디렉토리를 통한 접근이 일반적입니다. 이를 통해 GPIO 핀을 제어하고, 특정 핀의 상태를 확인할 수 있습니다. 예를 들어, 42번 GPIO 핀을 사용 중인 경우, 이를 통해 LED를 켜고 끄는 실습을 할 수 있습니다.
이 과정을 통해, 리눅스 시스템에서 명령어를 사용하여 이론적으로 이해한 내용을 실제로 증명할 수 있어야 합니다. 이는 리눅스 교육에서도 강조하는 중요한 점입니다. 실습을 통해 GPIO 핀을 켜고 끄는 과정을 경험하며, 실제 하드웨어와 소프트웨어 설정 사이의 연결을 이해하는 것이 중요합니다.
●데이터 시트를 통한 GPIO 레지스터 이해
데이터 시트는 각 보드의 GPIO 레지스터와 그 제어 방법에 대한 중요한 정보를 제공합니다. 각 제조사(예: 프리스케일, 엔비디아 등)는 해당 보드에 맞는 데이터 시트를 제공하며, 이 문서들은 종종 수천 페이지에 달할 수 있습니다. 이런 방대한 양 때문에 전체 문서를 처음부터 끝까지 읽는 것은 비효율적입니다.
데이터 시트 활용 방법은 다음과 같습니다.
특정 기능 이해: 처음에는 블루투스, USB, LED 등 특정 기능이나 센서에 초점을 맞추고 사용하는 것부터 시작합니다. 기본적으로 하드웨어를 켜고 끄는 것 같은 간단한 조작부터 익숙해지세요.
카테고리별 접근: 문서를 읽을 때는 카테고리를 정하여 집중적으로 해당 부분만을 탐구합니다. 예를 들어, GPIO에 대한 이해를 깊게 하고 싶다면 GPIO 레지스터와 관련된 섹션에 집중하세요.
실제와 연결: 데이터 시트에서 얻은 정보를 실제 하드웨어 설정과 소프트웨어 설정에 연결해 보세요. 이는 이론과 실제의 연결 고리를 만드는 데 중요합니다.
GPIO 레지스터 이해
레지스터 주소: GPIO에 대한 데이터 시트는 각 GPIO 핀을 제어하기 위한 레지스터의 주소와 크기, 그리고 제어 방법을 설명합니다.
비트 연산: 특정 GPIO 핀의 출력 모드를 설정할 때, 문서에 기술된 비트 값을 기준으로 레지스터를 조정합니다. 예를 들어, 29번, 28번, 27번 비트를 조정하여 출력 모드를 설정할 수 있습니다.
물리 주소와 가상 주소: 데이터 시트에서는 물리 주소를 제공하지만, 실제 사용 시에는 가상 주소를 통해 접근합니다. 이는 시스템의 메모리 관리 방식에 따른 것입니다.
이론적으로 배운 내용을 실제 명령어를 통해 확인하고 실습하는 것은 리눅스 시스템을 다루는 데 있어 중요합니다.
GPIO 핀 외에도 다양한 외부 장비(예: LED, 센서 등)를 연결하여 실제로 제어하는 실습을 통해 이론적 지식을 실제 상황에 적용해 보세요.
●/sys/class/gpio를 통한 GPIO 기본 제어 실습
GPIO 기본 제어 실습 과정:
1. GPIO 상태 확인
- 시스템에 연결된 GPIO 중, 21번 GPIO가 사용 중이지 않은 상태에서 시작합니다. 이는 `/sys/class/gpio` 디렉토리를 통해 `ls` 명령어로 확인할 수 있습니다.
2. GPIO 익스포트
- 사용하고자 하는 GPIO(예: 21번)를 시스템에 알리기 위해 `/sys/class/gpio/export`에 해당 GPIO 번호를 쓰면, 해당 GPIO가 시스템에 등록되어 사용할 수 있는 상태가 됩니다.
3. GPIO 방향 설정
- 등록된 GPIO의 방향을 입력(input) 또는 출력(output)으로 설정합니다. 예를 들어, 21번 GPIO의 방향을 설정하기 위해 `/sys/class/gpio/gpio21/direction` 파일에 `in` 또는 `out`을 쓰는 방식으로 변경할 수 있습니다.
4. GPIO 출력 제어
- GPIO가 출력 모드로 설정된 경우, `/sys/class/gpio/gpio21/value` 파일에 `1` (높은 전압) 또는 `0` (낮은 전압)을 써서 LED 등의 외부 장치를 켜고 끄는 실습을 할 수 있습니다.
5. GPIO 언익스포트
- 사용이 끝난 GPIO를 시스템에서 해제하기 위해 `/sys/class/gpio/unexport`에 해당 GPIO 번호를 쓰면, 해당 GPIO가 시스템에서 해제되어 다른 용도로 사용할 수 있게 됩니다.
특수 파일 이해:
- `/sys/class/gpio` 디렉토리 및 하위 파일들은 실제 물리적 파일이 아니라, 커널 메모리에 매핑된 특수 파일입니다. 이러한 파일들은 커널 변수와 함수와 직접 연결되어 있으며, 사용자가 직접 커널의 GPIO 관련 설정을 제어할 수 있게 합니다.
이러한 실습을 통해, 사용자는 리눅스 시스템에서 GPIO를 직접 제어하는 방법을 이해하고, 이론적 지식을 실제 하드웨어 조작으로 연결할 수 있습니다. 이 과정에서 `/sys/class/gpio` 디렉토리의 중요성과 리눅스 시스템의 파일 기반 제어 메커니즘에 대한 이해가 깊어집니다.
이 실습을 통해 리눅스 기반 시스템에서 GPIO를 사용하여 하드웨어를 제어하는 기본적인 방법을 학습하게 됩니다. 이는 임베디드 시스템 또는 IoT 프로젝트에서 직접 하드웨어를 제어하는 데 필요한 기초적인 능력을 제공합니다.
●/sys/class/gpio 통한 GPIO 제어 C코드 예제
1. GPIO 익스포트하기
GPIO 핀을 사용하기 위해서는 해당 핀을 시스템에 등록(익스포트)해야 합니다.
FILE * export_file = fopen("/sys/class/gpio/export", "w"); if (export_file == NULL) { perror("Error opening export file"); exit(1); } fprintf(export_file, "21"); fclose(export_file);
2. GPIO 방향 설정하기
GPIO 핀의 방향을 입력(input) 또는 출력(output)으로 설정합니다.
FILE * direction_file = fopen("/sys/class/gpio/gpio21/direction", "w"); if (direction_file == NULL) { perror("Error opening direction file"); exit(1); } fprintf(direction_file, "out"); fclose(direction_file);
3. GPIO 값 쓰기
GPIO 핀이 출력 모드인 경우, 해당 핀에 높은(1) 또는 낮은(0) 전압을 적용할 수 있습니다.
FILE * value_file = fopen("/sys/class/gpio/gpio21/value", "w"); if (value_file == NULL) { perror("Error opening value file"); exit(1); } fprintf(value_file, "1"); // LED 켜기 fclose(value_file);
4. GPIO 언익스포트하기
사용이 끝난 GPIO 핀을 시스템에서 해제합니다.
FILE * unexport_file = fopen("/sys/class/gpio/unexport", "w"); if (unexport_file == NULL) { perror("Error opening unexport file"); exit(1); } fprintf(unexport_file, "21"); fclose(unexport_file);
추가적인 고려사항:
- 위 예제 코드는 단순화된 형태로, 실제 사용 시 에러 처리와 리소스 관리를 보다 세심하게 고려해야 합니다.
- GPIO 핀 번호, 방향, 값 등은 프로젝트의 요구사항에 따라 달라질 수 있으며, 해당 부분을 적절히 수정하여 사용하면 됩니다.
- 이와 같은 방법으로 LED 뿐만 아니라 다양한 센서와 장치를 리눅스 기반의 시스템에서 직접 제어할 수 있습니다.
* 라즈베리파이 4 데이터시트 문서 링크: https://datasheets.raspberrypi.com/bcm2835/bcm2835-peripherals.pdf https://datasheets.raspberrypi.com/rpi4/raspberry-pi-4-reduced-schematics.pdf
다음과 관련된 리얼리눅스 추천 강의는 임베디드로드맵입니다.https://reallinux.co.kr/roadmap/arm