[Arm] GPIO 제어 디바이스 드라이버
1. 박진호님의 GPIO 디바이스 드라이버의 소스를 수정하여 작성하였습니다.
2. 개발환경
와우리눅스 파란 7.1
1. 컴파일에 필요한 헤더파일들을 확인 합시다..
1-1) 다음의 파일들이 있는가?
/usr/bin/arm-linux-gcc <=== 이 파일은 꼭 있어야 한다...
/usr/bin/arm-linux-g++
/usr/bin/arm-linux-ar
/usr/bin/arm-linux-ld
/usr/bin/arm-linux-nm
/usr/bin/arm-linux-strip
/usr/bin/arm-linux-objcopy
2-2) HowTo 문서 중 [ 6장 커널 설치 및 패치 ]의 내용을 탐독하시고, 커널을 컴파일 해야합니다.
모든 컴파일이 정상적으로 되었으면...
현재 문서 내용 중 " /ez/sw/kernel 이란 디렉토리에 설치하는 것을 가정하여 설명한다. "
는 글이 있습니다....
이것을 우리가 Makefile을 만들때 중요한 위치가 된다.....
이 내용은 아래 메이크 파일 만들기에서 설명하기로 한다.
암튼, 커널 컴파일 후 /ez/sw/kernel/linux 의 리스트이다..
[root@jdt linux]# ls -al
합계 2284
drwxr-xr-x 14 1046 snort 4096 4월 18 20:15 .
drwxrwxrwx 17 root root 4096 4월 18 20:15 ..
-rw-r--r-- 1 root root 15524 4월 18 20:12 .config <=== 생성확인
-rw-r--r-- 1 root root 16222 4월 18 20:11 .config.old
-rw-r--r-- 1 root root 2531 4월 18 20:12 .depend
-rw-r--r-- 1 root root 171424 4월 18 20:12 .hdepend
-rw-r--r-- 1 root root 41 4월 18 20:12 .menuconfig.log
-rw-r--r-- 1 root root 2 4월 18 20:13 .version
-rw-r--r-- 1 1046 snort 18633 9월 9 2000 COPYING
-rw-r--r-- 1 root root 77391 4월 18 20:07 CREDITS
drwxr-xr-x 30 1046 snort 4096 4월 18 20:10 Documentation
-rw-r--r-- 1 root root 38502 4월 18 20:07 MAINTAINERS
-rw-r--r-- 1 root root 17341 4월 18 20:10 Makefile
-rw-r--r-- 1 1046 snort 14491 3월 26 2001 README
-rw-r--r-- 1 1046 snort 2815 4월 7 2001 REPORTING-BUGS
-rw-r--r-- 1 root root 8888 4월 18 20:09 Rules.make
-rw-r--r-- 1 root root 214686 4월 18 20:15 System.map
drwxr-xr-x 20 1046 snort 4096 4월 18 20:07 arch
drwxr-xr-x 41 1046 snort 4096 4월 18 20:12 drivers
drwxr-xr-x 46 1046 snort 4096 4월 18 20:14 fs
drwxr-xr-x 28 1046 snort 4096 4월 18 20:13 include
drwxr-xr-x 2 1046 snort 4096 4월 18 20:13 init
drwxr-xr-x 2 1046 snort 4096 4월 18 20:15 ipc
drwxr-xr-x 2 1046 snort 4096 4월 18 20:13 kernel
drwxr-xr-x 2 1046 snort 4096 4월 18 20:15 lib
drwxr-xr-x 2 1046 snort 4096 4월 18 20:14 mm
drwxr-xr-x 27 1046 snort 4096 4월 18 20:15 net
drwxr-xr-x 5 1046 snort 4096 4월 18 20:13 scripts
-rwxr-xr-x 1 root root 1670348 4월 18 20:15 vmlinux
2. gpio 디바이스 드라이버를 위한 디렉토리를 만든다.
[root@jdt /]# cd /
[root@jdt /]# mkdir tgpio
[root@jdt /]# cd tgpio
[root@jdt /tgpio]#
작업할 위치이다...
3. EZBoard용 메이크파일을 만든다... [ ARM용 Makefile ]
[root@jdt /tgpio]# vi Makefile
//=======================================
중략...
KERNELDIR = /ez/sw/kernel/linux
INCLUDEDIR = $(KERNELDIR)/include -I./
include $(KERNELDIR)/.config
중략...
//=======================================
KERNELDIR = <=== 여기에 커널 컴파일을 한 디렉토리를 적어 주면 된다.....
INCLUDEDIR = <=== 컴파일시 참조할 헤더파일 디렉토리
즉, 헤더파일의 위치는 [ /ez/sw/kernel/linux/include ]이다.
include $(KERNELDIR)/.config <=== 커널 컴파일을 해야만 생기는 .config 파일이다.
4. gpio 디바이스 드라이버를 만든다... [ gpio.c ]
[root@jdt /tgpio]# vi gpio.c
5. gpio 테스트 프로그램을 만든다... [ test.c ]
[root@jdt /tgpio]# vi test.c
6. 컴파일을 한다...
[root@jdt /tgpio]# make clean
rm -f *.o *~ core .depend
[root@jdt /tgpio]# make dep
gccmakedep -I/amux/prg/kernel/linux/include -I./ -I/var/data/project/amux/prg/amuxapp/arminclude
[root@jdt /tgpio]# make
/usr/bin/arm-linux-gcc -Wall -D__KERNEL__ -DMODULE -I/amux/prg/kernel/linux/include -I./
-I/var/data/project/amux/prg/amuxapp/arminclude -O2 -c gpio.c
/usr/bin/arm-linux-gcc -Wall -D__KERNEL__ -DMODULE -I/amux/prg/kernel/linux/include -I./
-I/var/data/project/amux/prg/amuxapp/arminclude -O2 -c -o test.o test.c
/usr/bin/arm-linux-gcc -Wall -D__KERNEL__ -DMODULE -I/amux/prg/kernel/linux/include -I./
-I/var/data/project/amux/prg/amuxapp/arminclude -O2 test.o -o test
[root@jdt /tgpio]#
7. 컴파일이 정상적으로 수행 되었다.
위의 2 ~ 6의 작업은 첨부한 파일을 다운 받아서 tgpio.tar.gz 압축 파일을 풀면 된다...
[root@jdt /]# pwd
/
[root@jdt /]# ls
tgpio.tar.gz <=== 파일이 있는지를 확인한다..
[root@jdt /]# gzip -d ./tgpio.tar.gz
[root@jdt /]# tar xvf ./tgpio.tar
[root@jdt /]# ls
tgpio <=== 파일이 생성되었는지를 확인한다..
[root@jdt /]#
[root@jdt /]# cd tgpio
[root@jdt /tgpio]# cd tgpio
8. 이제 gpio 디바이스 드라이버와 test 프로그램을 만들었으니, 이지보드에 복사를 해야겠지요...
여기서, NFS파일시스템의 환경을 구축하여 파일을 복사 및 수정을 할 수도 있지만,
저번에 어떤 분이 램디스크를 만들때 에러가 발생한다고 하셨어 이번 기회에 같이 설명을 할까해서...
자, ramdisk 만드는 과정은 다음과 같다.
1) 저희가 제공한 cdrom이나, 자료실에 있는 sw/image/ramdisk.gz 파일을 /tgpio 폴더로 복사를 합니다.
[root@jdt /]# mount /dev/cdrom /mnt/cdrom <=== 이미 마운트되어 있으면 생략하시면 됩니다...
[root@jdt /]# cd /mnt/cdrom/sw/image
[root@jdt image]# pwd
/mnt/cdrom/sw/image
[root@jdt image]# ls -al
합계 2252
dr-xr-xr-x 1 root root 2048 2월 26 18:17 .
dr-xr-xr-x 1 root root 2048 2월 26 18:17 ..
-r-xr-xr-x 1 root root 18264 1월 25 22:01 blob
-r-xr-xr-x 1 root root 50880 1월 24 04:22 ezboot
-r-xr-xr-x 1 root root 33434 1월 19 11:56 ezflash
-r-xr-xr-x 1 root root 1580585 1월 16 22:11 ramdisk.gz
-r-xr-xr-x 1 root root 605908 1월 26 00:10 zImage
[root@jdt image]#
[root@jdt image]# cp ramdisk.gz /tgpio/
[root@jdt image]#
[root@jdt image]# cd /tgpio/
[root@jdt /tgpio]# ls -al
drwxr-xr-x 2 root root 4096 4월 18 16:28 .
drwxr-xr-x 22 root root 4096 4월 18 16:00 ..
-rwxr-xr-x 1 root root 1087 4월 17 22:01 Makefile
-rwxr-xr-x 1 root root 3650 4월 17 17:22 gpio
-rwxr-xr-x 1 root root 5962 4월 18 15:39 gpio.c
-rwxr-xr-x 1 root root 2776 4월 18 15:40 gpio.o
-r-xr-xr-x 1 root root 1580585 4월 18 16:28 ramdisk.gz
-rwxr-xr-x 1 root root 6218 4월 18 15:40 test
-rwxr-xr-x 1 root root 4047 4월 18 15:31 test.c
-rwxr-xr-x 1 root root 2592 4월 18 15:40 test.o
[root@jdt /tgpio]#
2) 여기서 위의 파일들이 모두 있는지를 확인한다.
3) 이젠 ramdisk를 풀어 마운트할 수 있는 디렉토리를 하나 만들자...
[root@jdt /tgpio]# mkdir ramdisk_disk
4) ramdisk.gz의 압축을 풀고, ramdisk_disk로 마운트하자....[ 이것이 ramdisk의 분해이다.. ]
[root@jdt /tgpio]# gzip -d ramdisk.gz
[root@jdt /tgpio]# mount -t ext2 -o loop ramdisk ramdisk_disk/
[root@jdt /tgpio]# cd ramdisk_disk/
[root@jdt ramdisk_disk]# ls -al
합계 18
drwxr-xr-x 14 root root 1024 1월 16 08:49 .
drwxr-xr-x 3 root root 4096 4월 18 16:35 ..
drwxr-xr-x 2 root root 1024 1월 25 23:29 bin
drwxr-xr-x 3 root root 2048 1월 26 00:28 dev
drwxr-xr-x 3 root root 1024 1월 26 00:09 etc
drwxr-xr-x 3 root root 1024 1월 16 08:49 home
drwxr-xr-x 3 root root 1024 4월 4 2000 lib
drwxr-xr-x 2 root root 1024 4월 4 2000 mnt
drwxr-xr-x 2 root root 1024 4월 4 2000 proc
drwxr-x--- 2 root root 1024 1월 16 08:51 root
drwxr-xr-x 2 root root 1024 4월 4 2000 sbin
drwxrwxrwt 2 root root 1024 4월 4 2000 tmp
drwxr-xr-x 7 root root 1024 4월 4 2000 usr
drwxr-xr-x 7 root root 1024 4월 4 2000 var
[root@jdt ramdisk_disk]#
5) 이것이 이지보드에 들어있는 ramdisk이다.
그럼 우리가 작업하려고하는 것을 하도록하자...
뭘해야할까???????//
5-1) 먼저 간단한 파일 복사부터 하도록 하자....
어디에다가 할까??? 고민 중.....
만만한게 tmp디렉토리니까.....여기에다 gpioEx라는 폴더를 하나 만들자..( 아무거나 상관없다 )
[root@jdt ramdisk_disk]# cd tmp
[root@jdt tmp]# pwd
/tgpio/ramdisk_disk/tmp
[root@jdt tmp]# mkdir gpioEx
[root@jdt tmp]# ls -al
합계 3
drwxrwxrwt 3 root root 1024 4월 18 16:41 .
drwxr-xr-x 14 root root 1024 1월 16 08:49 ..
drwxr-xr-x 2 root root 1024 4월 18 16:41 gpioEx
[root@jdt tmp]# cd gpioEx
[root@jdt gpioEx]#
[root@jdt gpioEx]# cp /tgpio/gpio.o /tgpio/ramdisk_disk/tmp/gpioEx/
[root@jdt gpioEx]# cp /tgpio/test /tgpio/ramdisk_disk/tmp/gpioEx/
[root@jdt gpioEx]#
<***> /tgpio/ramdisk_disk/tmp/gpioEx/ <==== 램디스크를 풀어 마운트한 디렉토리이다...
5-2) 복사를 모두 하였으면...디바이스 노드를 만들자.
[ 디바이스 노드는 이지보드 부팅 후 만들어 주어도 상관은 없다 ]
다음 위치로 이동
[root@jdt gpioEx]# cd /tgpio/ramdisk_disk/dev
[root@jdt dev]# pwd
/tgpio/ramdisk_disk/dev
<**주의> 디바이스 노드는 /dev 디렉토리에 만들어야 하는데...여기서 일반적으로
[root@jdt gpioEx]# cd /dev 이렇게 하시면 안되는것 아시죠....
여기는 현재 리눅스의 dev이지 램디스크를 만들기 위한 작업 디렉토리가 아니죠...
따라서.. 꼭 [root@jdt gpioEx]# cd /tgpio/ramdisk_disk/dev
[root@jgt dev]# mknod GPIO c 254 0
[root@jgt dev]# ls -al GPIO
crw-r--r-- 1 root root 254, 0 4월 18 17:01 GPIO
<참고>
gpio.c 소스 내용 중
=======================================================================
//메이저 번호 동적 할당
#define GPIO_MAJOR 254 // 메이저 번호에 254번 할당.
#define DEVICE_NAME "GPIO" // 디바이스 이름.
=======================================================================
이렇게 정의가 되어 있기 때문에...
디바이스 노드이 이름이 GPIO 가 되며,,,
메이져 번호가 254로 할당되어 254로 사용하였다..
즉, 이것은 모듈의 메이져 번호와 디바이스 노드의 번호가 항상 같아야 한다는 것이다..
그룹지정과 퍼미션에 대한 내용은 아직 잘 몰라서... 사용하지 않았다....
단지, 여기서는 디바이스 노드를 root 권한으로 root가 만들었고, 소유자가 root이다...
5-2) 복사와 디바이스 노드를 만들었으니... 이제 다시 램디스크를 압축하자..[ 이것이 램디스크 조립이다..]
[root@jgt dev]# pwd
/tgpio/ramdisk_disk/dev
[root@tsHeaven dev]# cd /tgpio
[root@tsHeaven /tgpio]# ls -al
drwxr-xr-x 3 root root 4096 4월 18 17:12 .
drwxr-xr-x 22 root root 4096 4월 18 16:00 ..
-rwxr-xr-x 1 root root 1087 4월 17 22:01 Makefile
-rwxr-xr-x 1 root root 3650 4월 17 17:22 gpio
-rwxr-xr-x 1 root root 5962 4월 18 15:39 gpio.c
-rwxr-xr-x 1 root root 2776 4월 18 15:40 gpio.o
-r-xr-xr-x 1 root root 6291456 4월 18 16:28 ramdisk
drwxr-xr-x 14 root root 1024 1월 16 08:49 ramdisk_disk
-rwxr-xr-x 1 root root 6218 4월 18 15:40 test
-rwxr-xr-x 1 root root 4047 4월 18 15:31 test.c
-rwxr-xr-x 1 root root 2592 4월 18 15:40 test.o
[root@tsHeaven /tgpio]#
여기서.. 마운드를 해제하고, 램디스크를 압축하자...
[root@tsHeaven /tgpio]# umount ./ramdisk_disk/
[root@tsHeaven /tgpio]# df
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/hda6 6965032 4700448 1910780 72% /
/dev/hda5 20469984 6802832 13667152 34% /mnt/disk_D
/dev/hdc 683940 683940 0 100% /mnt/cdrom
[root@tsHeaven /tgpio]# gzip ramdisk
[root@tsHeaven /tgpio]# ls -al
drwxr-xr-x 3 root root 4096 4월 18 17:24 .
drwxr-xr-x 22 root root 4096 4월 18 16:00 ..
-rwxr-xr-x 1 root root 1087 4월 17 22:01 Makefile
-rwxr-xr-x 1 root root 3650 4월 17 17:22 gpio
-rwxr-xr-x 1 root root 5962 4월 18 15:39 gpio.c
-rwxr-xr-x 1 root root 2776 4월 18 15:40 gpio.o
-r-xr-xr-x 1 root root 1590180 4월 18 16:28 ramdisk.gz
drwxr-xr-x 2 root root 4096 4월 18 16:32 ramdisk_disk
-rwxr-xr-x 1 root root 6218 4월 18 15:40 test
-rwxr-xr-x 1 root root 4047 4월 18 15:31 test.c
-rwxr-xr-x 1 root root 2592 4월 18 15:40 test.o
[root@tsHeaven /tgpio]#
9. 램디스크를 모두 만들었으니..이제...이지보드에 다운로드 해야겠지요...
minicom을 사용하여 다운로드를 하시기 바랍니다....
이것에 대한 설명은 HowTo문서에 자세하게 나와있기 때문에 생략합니다...
10.다운로드가 끝났으면. 이지보드를 부팅하고,,, login 하자...
Welcom to J.D&T EZBOARD.
ezboard login: root
Password:
[root@ezboard /root]$ cd /tmp/gpioEx/
[root@ezboard gpioEx]$ ls -al
drwxr-xr-x 2 root root 1024 Apr 18 2002 .
drwxrwxrwt 3 root root 1024 Apr 18 2002 ..
-rwxr-xr-x 1 root root 2776 Apr 18 2002 gpio.o
-rwxr-xr-x 1 root root 6218 Apr 18 2002 test
[root@ezboard gpioEx]$
11.이제 디바이스 드라이버를 적재하고, test프로그램을 실행시키자....
[root@ezboard gpioEx]$ insmod gpio.o
Init madule, Succeed. This Device is [GPIO] and Major Number is [254]
[root@ezboard gpioEx]$
[root@ezboard gpioEx]$ ./test
SA1100 GPIO D0-D7, D17, D24, red led All OFF.
EZBOARD GPIO DEVICE OPEN
GPIO Process Starting
# [1] LED ON
# [2] LED OFF
# [3] 0~255
# [4] Shift>>>>
# [5] Use Define
# [q] Quit
-----------------------------------
Command ?
12.종료 및 디바이스 드라이버를 제거하자
# [1] LED ON
# [2] LED OFF
# [3] 0~255
# [4] Shift>>>>
# [5] Use Define
# [q] Quit
-----------------------------------
Command ? q
EZBOARD GPIO DEVICE CLOSE
GPIO Process Ending
[root@ezboard gpioEx]$
[root@ezboard gpioEx]$ rmmod gpio
SA1100 GPIO D0-D7, D17, D24, Red LED All OFF.
GPIO Device EXIT SUCESS.
[root@ezboard gpioEx]$
참고
kelp의 유영창님 강좌에서 일부 발췌한 내용입니다.
[ http://kelp.or.kr/korweblog/?page=7&topic=14 StrongARM의 GPIO란? ]
gpio.c 소스 분석시 참고 하세요....
13. GPIO 레지스터 설명
레지스터 주소 | 이름 | 접근 | 풀어쓴 영문명 | 한글 설명 |
0x 9004 0000 | GPLR | 읽기 전용 | GPIO pin-level register | 핀 상태 검출 레지스터 |
0x 9004 0004 | GPDR | 읽기/쓰기 | GPIO pin direction register | 입출력 방향 설정 레지스터 |
0x 9004 0008 | GPSR | 쓰기 전용 | GPIO pin output set register | 출력 SeT 레지스터 |
0x 9004 000C | GPCR | 쓰기 전용 | GPIO pin output clear register | 츨력 Clear 레지스터 |
0x 9004 0010 | GRER | 읽기/쓰기 | GPIO rising-edge detect register | 상승 에지 검출 허가 레지스터 |
0x 9004 0014 | GFER | 읽기/쓰기 | GPIO falling-edge detect register | 하강 에지 검출 허가 레지스터 |
0x 9004 0018 | GEDR | 읽기/쓰기 | GPIO edge detect status register | 에지 검출 레지스터 |
0x 9004 0001C | GAFR | 읽기/쓰기 | GPIO alternate function register | 부가 기능 사용 허가 레지스터 |
13.1 핀과 비트 관계
각 레지스터의
비트 0이 GPIO 0번 핀에 해당되고
비트 27이 GPIO 27번핀에 해당되는 식으로 대응된다.
13.2 GPLR ( GPIO pin-level register ) : 핀 상태 검출 레지스터
이 레지스터는 GPIO의 핀에 인가된 전압 레벨값을 가지게 된다.
low로 인가되면 GPIO 핀에 해당되는 비트가 0으로 읽히게 되며
high로 인가되면 GPIO 핀에 해당되는 비트가 1로 읽힌다.
이 레지스터는 다른 설정 레지스터에 영향을 받지 않는다.
이 레지스터는 RESET시에 어떤 값이 될지를 알수는 없다.
13.3 GPDR ( GPIO pin direction register ) 입출력 방향 설정 레지스터
이 레지스터는 출력을 허용한다.
0 이면 입력 전용으로 설정하며
1 이면 출력이 가능하게 된다.
이 레지스터는 RESET시에는 클리된다.
13.4 GPSR ( GPIO pin output set register ) 출력 Set 레지스터
입출력 방향 설정 레지스터가 출력으로 설정되어 있고
부가 기능 사용이 허가 되어 있지 않은 상태에서
이 레지스터에 값을 쓰게 되면 GPIO 핀의 상태가
1 로 설정한 비트에 해당하는 핀을 High 상태로 만든다.
0 으로 설정한 비트는 이전 상태를 유지한다.
13.5 GPCR ( GPIO pin output clear register ) 출력 Clear 레지스터
입출력 방향 설정 레지스터가 출력으로 설정되어 있고
부가 기능 사용이 허가 되어 있지 않은 상태에서
이 레지스터에 값을 쓰게 되면 GPIO 핀의 상태가
1 로 설정한 비트에 해당하는 핀을 Low 상태로 만든다.
0 으로 설정한 비트는 이전 상태를 유지한다.
13.6 GRER ( GPIO rising-edge detect register ) 상승 에지 검출 허가 레지스터
이 레지스터는 입력 핀의 상태가 Low에서 High로 변했을때 에지 검출 레지스터를
1 로 설정하는 것을 허가 한다.
이 레지스터는 RESET시에 어떤 값이 될지를 알수는 없다.
13.7 GFER ( GPIO falling-edge detect register ) 하강 에지 검출 허가 레지스터
이 레지스터는 입력 핀의 상태가 High에서 Low로 변했을때 에지 검출 레지스터를
1 로 설정하는 것을 허가 한다.
이 레지스터는 RESET시에 어떤 값이 될지를 알수는 없다.
13.8 GEDR ( GPIO edge detect status register ) 에지 검출 레지스터
이 레지스터는 GRER이나 GFER의 허가 비트가 설정되어 있을 경우
해당 에지가 발생하면 1 로 설정하여 에지 발생을 표시한다.
이 레지스터는 클리어 데이타를 쓰기전에는 이전 상태를 유지한다.
이 레지스터는 RESET시에 어떤 값이 될지를 알수는 없다.
13.9 GAFR ( GPIO alternate function register ) 부가 기능 사용 허가 레지스터
이 레지스터는 GPIO의 부가적인 기능의 사용을 허가 한다.
이때는 디지탈 입출력으로는 사용할수 없다.
단 GPIO 0, GPIO 1, GPIO 17, GPIO 24는 해당되지 않는다.
이 레지스터는 RESET시에는 클리된다.
이 강의내용의 소유권은 (주)제이닷디앤티에 있습
'임베디드' 카테고리의 다른 글
[u-boot]u-boot에서 커널로 bootargs 넘겨주기 (0) | 2006.10.16 |
---|---|
[U-BOOT] short-load-bytes에러시 (0) | 2006.10.10 |
[U-boot] examples에서 컴파일 문제 (0) | 2006.09.20 |
[Arm] LFS를 이용한 ramdisk 구축 (0) | 2006.09.15 |
[Arm] libtermcap 라이브러리 설치 (0) | 2006.09.15 |