==================================Outline====================================
저수준 C프로그래밍
- sysfs를 이용한 GPIO 제어
- 라즈베리 파이 커널 빌드와 디바이스 드라이버
- 커널 빌드
- 모듈 프로그래밍
디바이스 드라이버 프로그래밍
- 'file_operations' 구조체의 명령어
----------------------------------------------------------------------------
저수준 C프로그래밍
sysfs를 이용한 GPIO 제어
p/474
sys파일 시스템은 하드웨어에 대한 정보를 체계적으로 제공한다. Raspbian 커널에 GPIO포트를 제어하기 위한 드라이버가 포함되어 있고 sys 파일 시스템을 통해 사용자에게 GPIO포트 설정 및 제어를 수행할 수 있는 기능이 포함되어 있다.
export파일을 제어하고자 하는 GPIO 포트 번호를 써주면 해당 핀의 파일명이 심볼릭 링크 파일로 생성된다.
이 링크를 제어하여 led를 제어할 수 있다.
라즈베리 파이 커널 빌드와 디바이스 드라이버
p/478
리눅스 커널은 리눅스 커뮤니티에서 제공한다. 사용자 편의에 위해 다양한 기능을 추가하여 공개하는 것을 배포판이라고 한다. Debian은 잘 알려진 배포판이다.
//GPL(General Purpose License)
리눅스는 GPL을 기반으로 하는 오픈소스 커널이기 때문에 이것을 사용하는 모든 프로램은 소스 코드를 공개해야 할 의무가 있다.
안드로이드는 리눅스 기반이지만 gcc컴파일러와 헤더파일을 사용하지 않기 때문에 소스 코드를 공개할 필요가 없다.
간단한 C파일을 작성하여 컴파일해보자. 컴파일이 완료되면 해당 파일의 정보를 살펴본다.
ELF32 format, ARM 아키텍쳐 사용
//커널 소스 다운로드 이전에 했음으로 넘어간다.
커널 빌드
p/493
ATmega32는 리눅스 기반에서도 작동한다.
'ia64' 인텔의 CPU를 말한다.
RaspberryPi2의 아키텍쳐는 'mach-bcm2709'를 사용한다.
초보자들을 위해 기본적인 설정이 ‘config' 파일로 제공된다. 초보자의 경우는 기본적인 ‘config’파일을 사용한다.
커널 빌드 시 교재 p/493의 1 - 4단계까지만 수행하고 나머지 과정은 파일을 복사하여 진행하는 것이 빠르다.
‘menu-config ’시 수정된 내용이 있으면 저장 메시지를 띄워준다.
‘WinSCP’는 파일 전송을 위해 사용되는 프로그램이다. 필요할 경우 설치하여 사용한다.
커널 빌드는 지난 시간에 수행했음으로 따로 할 필요는 없다.
모듈 프로그래밍
p/507
리눅스의 경우 주변 장치는 운영체제에 의해 관리된다. 운영체제는 커널 모드와 사용자 모드로 구분해 주소 공간을 분리하고 시스템 자원을 관리한다. 이 때 장치에 대한 관리 권한은 커널 모드에만 제공된다. 시스템 콜 기반으로 커널을 관리하는 경우는 커널 소스를 직접 수정해야 하고, 컴파일과 리셋의 과정을 수행해야 한다. 모듈을 사용한다면 커널 빌드 없이 장치를 사용할 수 있다. 다만 모듈을 사용할 경우 커널 버전이 모듈 커널의 버전과 일치해야 하며 root 계정으로만 작업 가능하다.
교재 p/508 ~ p/509의 소스를 실행하여 간단한 모듈 동작 과정과 사용법을 알아보자.
/*** 소스 ***/
[Makefile]
obj-m := simple_mod.o
KDIR := /usr/src/linux
PWD := $(shell pwd)
FILE := simple_mod
all:
@echo
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
dmesg | tail -5
clean:
@echo
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
dmesg | tail -5
up:
@echo
insmod $(FILE).ko
dmesg | tail -5
lsmod
down:
@echo
rmmod $(FILE)
dmesg | tail -5
lsmod
[simple_mod.c]
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
int simple_mod_init(void)
{
printk("simple module loaded\n");
return 0;
}
int simple_mod_exit(void)
{
printk("simple module unloaded\n");
return 0;
}
module_init(simple_mod_init);
module_exit(simple_mod_exit);
MODULE_LICENSE("GPL");
셸 명령어에 따른 모듈이 내부에 적재될 때 메모리 위치를 살펴보자.
총 4GB의 메모리라고 했을 때 커널은 상위 1GB영역에 위치한다. 이러한 커널은 다시 세 영역으로 나뉜다. 하위 16MB영역은 직접 액세스 영역, 16 ~ 896MB 영역은 Norname Zone, 896MB에서 나머지 영역은 High Memory Zone으로 구분된다.
shell 명령어 창에서 ‘/pro/kallsysm'명령어를 입력하면 커널 심볼 테이블을 볼 수 있다.
//페이지를 나누어서 출력시키기 위한 명령어 'more' -> '/pro/kallsysm | m
디바이스 드라이버 프로그래밍
p/517
디바이스 드라이버를 사용하기 위해서는 ‘file_operation’구조체에 정의 되어 있는 open, close, read, write 함수 등을 사용해야 한다.
file_operation 구조체는 linux/fs.h에 포함되어 있으며 함수 포인터들을 멤버로 가지고 있다.
프로그램이 직접적으로 하드웨어를 제어하는 것은 kernel에 의해 금지된다. 프로그램은 커널을 통해 하드웨어를 제어해야한다. 커널은 모든 장치를 파일화하여 관리한다. 하드웨어 대한 정보를 ‘/dev’ 폴더에 저장해 놓는다.
사용자는 임의적으로 하드웨어 장치를 생성할 수 있는 명령어는 'mknod'이다.
존재하는 장치의 구동을 위한 명령어는 'insmod'이다. 'insmod'는 장치를 초기화하기 위해 'Init' 함수를 사용한다. 또한 ‘file_oeration'구조체의 함수를 사용하여 장치를 제어하게 된다.
응용 프로그램 개발자는 파일이름만 알면 장치를 제어할 수 있다. 때문에 상세한 장치구조에 대해서는 굳이 알 필요가 없다.
'file_operations' 구조체의 명령어
open: 디바이스 드라이버가 실제로 사용되기 위해 호출되는 함수. ‘open'함수는 장치 열기에 성공했을 시, 파일 디스크립터가 아닌 ’0'을 반환한다.
release: 'close'함수와 같은 기능을 한다. 즉 연결되어 있는 파일 장치를 닫는 역할을 한다.
read: 디바이스에 대한 입력을 위해 사용되는 함수이다.
write: 디바이스의 출력을 위해 사용되는 함수이다.
ioctl: read/write 이 외의 다양한 연산을 제공한다. read/write 기능 또한 'ioctl'에서 구현 가능하다.
mmap: 메모리 매핑을 위한 함수로써 물리적 주소를 가상 공간으로 변환해 준다.
poll: 인터럽트의 처리와 연관되어 사용되는 함수이다.
'read' 함수의 4번째 인자는 읽어 들일 데이터의 시작점이다.
p/521 예제 코드 분석
예제는 내일 쳐본다.
'Busan IT > 로봇제어' 카테고리의 다른 글
LED 제어 디바이스 드라이버 (0) | 2015.11.06 |
---|---|
라즈베리 파이 커널 빌드와 디바이스 드라이버 (0) | 2015.11.04 |
저수준 C 프로그래밍 (0) | 2015.11.02 |
BCM 라이브러리 PWM LED Dimming (0) | 2015.10.30 |
푸쉬 버튼을 이용한 LED on/off 제어 (0) | 2015.10.28 |