• 검색 결과가 없습니다.

GPIO OUTPUT

문서에서 GettingStarted-with-HBE-EMPOSII (페이지 132-138)

8. 디바이스 드라이버

8.2. EMPOSⅡ에서 디바이스 드라이버 작성

8.2.5 GPIO OUTPUT

GPIO(General Purpose Input/Output)란 port pins으로 어플리케이션의 목적에 따라 input 이나 output의 신호를 발생하거나 획득을 원할 목적으로 사용되는 것이다. 이를 위해

GFER GPIO 포트 핀이 input일 때 falling-edge를 감지한다.

GEDR GRER이나 GFER로 설정된 값에 따른 결과를 설정한다.

GAFR GPIO 핀을 alternate function으로 전환한다.

이제 실제적으로 사용하는 레지스터들에 관하여 정리하여 보면 아래와 같다.

- GPIO 레지스터 정리 Register

Type

GPIO[31:0] GPIO[63:32] GPIO[84:64]

GPLR GPLR0 GPLR1 GPLR2

GPSR GPSR0 GPSR1 GPSR2

GPCR GPCR0 GPCR1 GPCR2

GPDR GPDR0 GPDR1 GPDR2

GRER GRER0 GRER1 GRER2

GFER GFER0 GFER1 GFER2

GEDR GEDR0 GEDR1 GEDR2

GAFR GAFR0_L GAFR0_U GAFR0_L GAFR0_U GAFR0_L GAFR0_U

위의 GPIO를 출력으로 사용하기 위한 방법은 다음과 같다.

1. GPDR로 포트 핀의 방향을 출력으로 설정한다. 해당 비트를 찾아 셋 하면 된다.

2. GPSR로 해당 비트를 셋 하면 GPIO 포트에 1로 셋 된다.

3. GPCR로 해당 비트를 셋 하면 GPIO 포트가 0으로 셋 된다.

현재 타겟 보드에는 GPIO 17번 포트는 led와 연결되어 있어 GPIO 출력을 사용할 수 있 다. 우리는 이 포트를 이용하여 GPIO 출력 디바이스 드라이버를 작성해 보자.

- gpio_led.c

#include <linux/ioport.h>

#include <asm/uaccess.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <asm/io.h>

#define GPIOLED_MAJOR 0

#define GPIOLED_NAME "GPIO LED"

#define GPIOLED_MODULE_VERSION "GPIO LED V0.1"

//Global variable

static int gpioled_usage = 0;

static int gpioled_major = 0;

// define functions...

int gpioled_open(struct inode *minode, struct file *mfile) { if(gpioled_usage != 0) return -EBUSY;

MOD_INC_USE_COUNT;

gpioled_usage = 1;

GAFR0_U = GAFR0_U & ( 0xc);

GPDR0 = GPDR0 | 0x20000;

return 0;

gpioled_usage = 0;

return 0;

ssize_t gpioled_write_byte(struct file *inode, const char *gdata, size_t length, loff_t *off_what) {

unsigned char c;

get_user(c,gdata);

if (c != 0) GPSR0 = GPSR0 | 0x20000;

else GPCR0 = GPCR0 | 0x20000;

return length;

static struct file_operations gpioled_fops = { write : gpioled_write_byte,

open : gpioled_open, release : gpioled_release,

;

int init_module(void) { int result;

result =

register_chrdev(GPIOLED_MAJOR,GPIOLED_NAME,&gpioled_fops);

if(result < 0) {

printk(KERN_WARNING"Can't get any major n");

return result;

gpioled_major = result;

printk("init module, ledioport major number : %d n",result);

return 0;

void cleanup_module(void) {

if(unregister_chrdev(gpioled_major,GPIOLED_NAME))

printk(KERN_WARNING"%s DRIVER CLEANUP FALLED n", GPIOLED_NAME);

- test.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int main(int argc, char **argv) {

int dev;

char buff;

if(argc <= 1) {

printf("please input the parameter! ex)./test on or off n");

return -1;

dev = open("/dev/gpio_led", O_WRONLY);

if (dev != -1) {

if(argv[1][0] == 'o' && argv[1][1] == 'n') buff = 1;

else if(argv[1][0] == 'o' && argv[1][1] == 'f' &&

else {

printf( "Device Open ERROR! n");

exit(-1);

return(0);

- Makefile

# led Device Driver Makefile

CC = arm-linux-gcc

KERNELDIR = /usr/local/linux-2.4.19-rmk4-pxa2-empx1 INCLUDEDIR = -I$(KERNELDIR)/include -I./

CFLAGS = -D__KERNEL__ -DMODULE -Wall -O2 -I$(INCLUDEDIR)

MODULE_OBJS = gpio_led.o MODULE_SRCS = gpio_led.c

TEST_TARGET = test TEST_OBJS = test.o TEST_SRCS = test.c

all: $(MODULE_OBJS) $(TEST_TARGET)

$(MODULE_OBJS) :

$(CC) $(CFLAGS) -c $(MODULE_SRCS)

$(TEST_TARGET) :

clean:

rm -f *.o

rm -f $(TEST_TARGET)

작성된 디바이스와 응용프로그램의 테스트를 위해 다음과 같이 디바이스 드라이버와 응용 프로그램을 컴파일 하고 시리얼 등을 통해 gpio.o와 test를 타겟 보드로 전송한다.

$ make

전송이 끝나면 insmod를 사용하여 디바이스 드라이버를 커널에 삽입하고 mknod로 특수 장치 파일을 만든다.

[root@EMPOS/root]$ insmod gpio_led.o

[root@EMPOS/root]$ mknod /dev/gpio_led c 253 0

이상으로 응용프로그램을 실행할 준비가 끝났으므로 응용프로그램을 다음과 같이 실행한 다

[root@EMPOS/root]$ ./test on

위와 같이 실행 하면 리셋 버튼 밑에 있은 GPIO led에 불이 들어 오고

“./test off”를 실행 시키면 GPIO led에 불이 꺼진다.

※ 동작 원리

GPIO led 디바이스 드라이버는 GPIO포트 17번을 이용하여 GPIO출력을 사용하기 위해 작성되었다. 우선 gpio_led.c의 open함수에서 해당 비트에 관련한 Alternate Function을 사용하지 않고 General Purpose I/O으로 사용하기 위해 레지스터 GAFR0_U을 사용하여 해당 GPIO 포트를 00으로 설정하고 GPDR0를 이용하여 GPIO 17포트를 출력으로 설정하 였다. write함수에서는 응용프로그램에서 넘겨준 값이 0이면 GPCR0를 이용하여 해당 비 트를 셋하고 0이 아니면 GPSR0를 이용하여 해당 비트를 셋 하여 GPIO LED 빛을 발하게 한다.

문서에서 GettingStarted-with-HBE-EMPOSII (페이지 132-138)