달공이와 임베디드

디바이스 드라이버 프로그램의 구성 본문

디바이스 드라이버

디바이스 드라이버 프로그램의 구성

하일리99 2016. 8. 23. 15:58


디바이스 드라이버 프로그램의 구성


디바이스 드라이버는 크게 세가지 부분으로 나뉘어 진다.

다음 예제는 GPIO 를 통한 LED 제어를 하기 위해 만들어진 코드이다.



1. 디바이스 드라이버의 전체적인 사용함수 정의부 및 디바이스 드라이버 커널 적재/반납부

 


"file_operations 구조체에 미리 정의되어 있는" 함수 중에서 구현하고자 하는 디바이스 드라이버에서 사용될 함수를 선언하여 주고, 모듈 형태로 구성되는 디바이스 드라이버를 "커널내부에 문자장치로 등록"하여, 사용자 어플리케이션이 장치에 접근할 때 사용할 선언되있는 함수를 이 문자 장치(디바이스 드라이버 모듈)과 연결하는 역할을 수행한다. 


※ 윈도우에서는 디바이스를 따로 처리하지만, 리눅스에서는 디바이스를 "Virtual File System (VFS) 인터페이스"를 통해 관리하는 즉, 디바이스를 파일처럼 조작하며 관리한다. 


 register_chrdev 의 인자를 살펴보면, 장치의 번호, 장치의 이름, 사용함수 임을 확인할 수 있다.

원형 : int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);


 register_chrdev 의 파라미터를 살펴보면 세번째 파라미터에 file_operations 구조체의 포인터를 넣는데, 이를 이용해서 사용자 프로그램에서 시스템콜( 예를들어, open, read, close )이 호출되면 VFS에서 그것을 커널에 등록되어 있는 하드웨어 제어함수를 호출하도록 되어 있는 것이다. linux/fs.h 파일에 정의되어 있는 file_operations 의 구조체는 다음과 같다.

 



2. 기본적인 장치에 대한 Open(open) & Close(release)과 사용함수

 


 앞서, 이 디바이스 드라이버에서 사용할 함수를 open, release, read 로 선택해 주었다. 이제 그 함수에 대한 정의가 필요하다. 1) open & release 함수의 경우에는 장치파일이 사용자 프로그램에서 " open(fd,FLAGS) & close(fd) " 와 같은 "파일접근 시스템콜"이 호출될 때, "작성된 디바이스 드라이버에서 동작"하게 되는 함수이다. 2) read 함수의 경우도 마찬가지로 read 파일접근 시스템콜이 호출될 때, 디바이스 드라이버에서 호출되는 함수이다. 이와 같은 함수로는 write, read, ioctl 등이 있겠다.


※ 여기서 알아두어야 할 함수는 copy_to_user 함수와 copy_from_user 함수이다. 

 copy_to_user() 함수 : 커널 메모리 블록 데이터를 사용자 메모리 블록 데이터에 써 넣는다.

 copy_from_user() 함수 : 사용자 메모리 블록 데이터를 커널 메모리 블록 데이터에 써 넣는다.


 → 사용자 메모리 블록 데이터에 바이트 크기 단위 만큼 써 넣는다. 유효성 검사를 수행.

 → 정상적으로 수행되면 0 이상의 값, 그렇지 않으면 0보다 작은 값 반환


  int copy_to_user(void __user * to, const void * from, unsigned long n)

  int copy_to_user(void * to, const void __user * from, unsigned long n)


1) copy_to_user() : read 함수에 사용( 장치에서 데이터를 읽어 응용프로그램에게 전달 )

2) copy_from_user() : write 함수에 사용( 응용프로그램에서 값을 받아 커널로(장치로) 값 전달 )

3) 헤더로 <asm/uaccess.h> 사용



3. 장치제어 함수

 




 

 장치제어 함수는 파일 형태로 만들어진 장치파일에 접근한 후, 실질적인 동작( 값을 읽어오거나 변경하거나, 예를들어 GPIO 의 Register 값을 읽어오거나 변경하거나 )을 수행하는 디바이스 드라이버의 함수부이다. 위에 코드를 살펴보면, 포인터를 이용하여 GPIO 의 가상메모리 공간에 접근하여 GPIO Register 값을 수정하거나 읽거나 하고 있는 것을 보인다.




디바이스 드라이버의 메소드 정리 ★


http://cs.sch.ac.kr/lecture/Embedd/07-EmbedSW-11-DeviceDriver.pdf 



GPIO 에 대해서
 1) GPIO 란 General Purpose IO 를 의미한다.
 2) 라즈베리파이 GPIO 구성 http://pinout.xyz/pinout/pin35_gpio19
 3) 라즈베리파이 GPIO register 구성 https://cdn-shop.adafruit.com/product-files/2885/BCM2835Datasheet.pdf
 4) GPIO register 읽는 법


참고자료
http://raspberrypi.ssu.ac.kr/control/2722

http://cs.sch.ac.kr/lecture/Embedd/07-EmbedSW-11-DeviceDriver.pdf 

http://pinout.xyz/pinout/pin35_gpio19
https://cdn-shop.adafruit.com/product-files/2885/BCM2835Datasheet.pdf



'디바이스 드라이버' 카테고리의 다른 글

Module 생성을 위한 과정  (0) 2016.08.23
디바이스 드라이버에 대한 이해  (0) 2016.08.23
Comments