타겟보드를 이용하여 디바이스 드라이버를 배워보자!(10)



안녕하세요 이우영 입니다.


2011년도 마지막 주입니다. 한주간 마무리 잘하시고 2012년을 준비 합시다.

그럼 저는 오늘도 열심히 공부를 하겠습니다.

오늘은 간단하게 소스코드를 만들어 보도록 하겠습니다.

아직 이해 하기위해서는 알아야 할 정보가 많지만

직접 만들어 보기위한 포인트는 설명한거 같습니다.


사용하는 핀 정하기




오늘 사용할 핀은 EINT6번 핀입니다. H2의 68번에 연결되어 있습니다.


01.PNG


EINT6은 아래 그림과 같이 GPN6번 핀입니다.


02.PNG


이 핀을 이용하여 아래 그림의 LED를 깜빡이도록 하겠습니다.


EZ-S3C6410.jpg


아래 H2에서 표시한 부분을 핀같은것을 이용하여 전기가 흐르게 하면 위에 표시한 LED가 불이 들어옵니다.


 소스 코드 작성




int_dev.c

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/version.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/sched.h>

#include <linux/interrupt.h>

#include <linux/wait.h>

#include <linux/ioport.h>

#include <linux/slab.h>    

#include <linux/poll.h>    

#include <linux/proc_fs.h>

#include <linux/workqueue.h>

#include <asm/system.h>    

#include <asm/uaccess.h>

#include <asm/ioctl.h>

#include <asm/unistd.h>

#include <asm/io.h>

#include <asm/irq.h>

#include <asm/gpio.h>

#include <linux/irq.h>

#include <linux/time.h>                     

#include <linux/timer.h>     

#include <asm/mach/arch.h>

#include <plat/gpio-cfg.h>   

 

#define IRQT_FALLING                  IRQ_TYPE_EDGE_FALLING

 

#define INT_DEV_NAME                  "int_dev"

 

#define LED_GPIO_DATA_REGISTER        0x7F008184

#define LED_ON                        (7<<2)

 

#define PAGE_SIZES                    0x1000

 

volatile u32                          *led_data;

u32                                   irq;

 

//인터럽트가 동작할때 실행하는 함수

irqreturn_t int_interrupt(int irq, void *dev_id, struct pt_regs *regs)

{

        *led_data = ~(*led_data);    //LED에 전원 인가


        printk("intterrup!!\n");


        return IRQ_HANDLED;

}

 

int int_init() {

        u32 gpio;

 

        printk("int_dev_init!\n");


        //LED의 주소를 등록 (물리주소 -> 가상주소)

        led_data = ioremap(LED_GPIO_DATA_REGISTER, PAGE_SIZES);

 

        *led_data = LED_ON; //LED를 끈다.

       

//GPN6번 핀의 주소를 얻어온다.

        gpio = S3C64XX_GPN(6);


//GPN6번 핀에 풀업 저항을 넣어준다.

        s3c_gpio_setpull( gpio, S3C_GPIO_PULL_UP   );


//EINT6 주소를 얻어온다.

        irq = IRQ_EINT(6);


// EINT6 동작 방식 설정.

        set_irq_type( irq, IRQT_FALLING );


//인터럽트 등록

        request_irq( irq, int_interrupt, IRQF_DISABLED, INT_DEV_NAME, NULL );

 

        return 0;

}

 

void int_exit() {

        printk("int_dev_exit!\n");


//LED 주소 해제

        iounmap( led_data );


//인터럽트 해제

        free_irq(irq, NULL);

}

 

module_init(int_init);

module_exit(int_exit);

 

MODULE_LICENSE("Dual BSD/GPL");


Makefile

cc := arm-generic-linux-gnueabi-gcc-4.3.2

obj-m := int_dev.o

KDIR := /home/woo/device_driver/linux-2.6.29-ez-s3c6410

all:
make -C $(KDIR) SUBDIRS=$(PWD) modules
cp *.ko /nfs
clean:
rm -rf *.o
rm -rf *.ko
rm -rf *.mod.*
rm -rf .*.cmd
distclean:
rm -rf modules.order 
rm -rf Module.markers
rm -rf Module.symvers


실행 화면




그럼 하나씩 확인해 볼까요?


소스파일을 컴파일하고 보드에 올려 보겠습니다.


동작화면.PNG


int_dev.ko 파일을 등록 후 아까 알려준 위치를 핀으로 건드리면 화면과 같이 interrupt!! 메시지가 화면에 출력되고


보드의 LED에 불이 들어왔다 꺼졌다 할것입니다.


위에서 인터럽트가 동작 할때마다 토글 방식으로 LED에 전원을 넣어 줍니다.


보드에서 인터럽트를 사용해 보았습니다.


이 소스코드를 이용해서 다른 핀을 이용해 LED를 제어해 봅시다.

(한핀은 불을키고 다른 핀을 이용하여 LED를 꺼 봅시다.)


그럼 다음 시간까지 수고하세요~


빠른만남을 원하시면 http://ms-osek.org/ 여기로 찾아오세요~