EZ-S3C6410 보드에서 부져를 구동하는 소스입니다.

부져는 GPIO의 GPN12 에 연결되어 있다고 가정하에 설명합니다.  


1. 디바이스 드라이버



#] vi dev_gpio.c


/*-----------------------------------------------------------------------------

  파 일 : dev_gpio.c

  설 명 : 

  작 성 : 

  날 짜 : 

  주 의 :

-------------------------------------------------------------------------------*/

#ifndef __KERNEL__

#define __KERNEL__

#endif


#ifndef MODULE

#define MODULE

#endif


#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/irq.h>

#include <linux/io.h>

#include <linux/delay.h>


#include <asm/system.h>     

#include <asm/uaccess.h>

#include <asm/irq.h>

#include <asm/ioctl.h>

#include <asm/unistd.h>

#include <asm/delay.h>


#include <mach/map.h>

#include <mach/gpio.h>

#include <plat/gpio-cfg.h>

#include <plat/regs-gpio.h>


#include "dev_gpio.h"


/// 로컬상수 정의 --------------------------------------------------------------*/

#define ON 1

#define OFF 0



/// 로컬변수 정의 --------------------------------------------------------------*/

static int usage   = 0;

static int showmsg = 0;

static int major   = GPIO_MAJOR_DEF;


//------------------------------------------------------------------------------

/** @brief   하드웨어 초기화

    @remark  인터럽트 설정은 반드시 초기화 순서를 지켜야 함

*///----------------------------------------------------------------------------

static void hw_gpio_init( void )

{

/// 출력설정 GPF12

s3c_gpio_cfgpin (S3C64XX_GPN(12), S3C64XX_GPN_OUTPUT(12));     /* GPN12 to OUTPUT12 */

s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_NONE);         /* */

}


//------------------------------------------------------------------------------

/** @brief   read

    @remark  

*///----------------------------------------------------------------------------

static ssize_t gpio_read(struct file *filp, char *buf, size_t count, loff_t *ppos)

{

return 1;

}


//------------------------------------------------------------------------------

/** @brief   write

    @remark  

*///----------------------------------------------------------------------------

static ssize_t gpio_write(struct file *filp, char *buf, size_t count, loff_t *ppos)

{

return 1;

}


//------------------------------------------------------------------------------

/** @brief   BUZZER ON/OFF 출력 제어

    @remark  

*///----------------------------------------------------------------------------

void set_buzzer_onoff( unsigned char val )

{

printk("TRACE %s %d>-------------- val : %d\n", __FUNCTION__, __LINE__, val);

gpio_set_value( S3C64XX_GPN(12), val );

}


//------------------------------------------------------------------------------

/** @brief   ioctl 함수

    @remark  

*///----------------------------------------------------------------------------

static int gpio_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )

{

    if( _IOC_TYPE( cmd ) != GPIO_IOCTL_MAGIC ) return -EINVAL;

if( _IOC_NR  ( cmd ) >= GPIO_IOCTL_MAGIC ) return -EINVAL;


switch (cmd)

{

case IOCTL_BUZZER_ON : set_buzzer_onoff( 0 ); return 0;

case IOCTL_BUZZER_OFF : set_buzzer_onoff( 1 ); return 0;

}  


return -EINVAL;

}


//------------------------------------------------------------------------------

/** @brief   어플리케이션에서 디바이스를  open 하였을때 호출되는 함수

    @remark  

*///----------------------------------------------------------------------------

static int gpio_open( struct inode *inode, struct file *filp )

{

usage ++;


if (showmsg) printk(" %s OPEN (%d)\n", DEV_NAME, usage );

    return 0;

}


//------------------------------------------------------------------------------

/** @brief   어플리케이션에서 디바이스를  close를 하였을때 호출되는 함수

    @remark  

*///----------------------------------------------------------------------------

static int gpio_release( struct inode *inode, struct file *filp)

{

    usage --;          

    if (showmsg) printk(" %s CLOSE\n", DEV_NAME );

    return 0;

}


//------------------------------------------------------------------------------

/** @brief   드라이버에 사용되는 접근 함수에 대한 함수 포인터 구조체를 정의 한다.

이 구조체는 fs.h에 정의 되어 있다.

    @remark  

*///----------------------------------------------------------------------------

static struct file_operations gpio_fops =

{

        open    : gpio_open, 

        release : gpio_release, 

        read    : gpio_read,

        write   : gpio_write,

ioctl   : gpio_ioctl,

};


//------------------------------------------------------------------------------

/** @brief   init

    @remark  

*///----------------------------------------------------------------------------

static __init int gpio_init( void )

{

int ret;


/// 장치를 등록한다. ============================================

major &= 0xff;

if( !register_chrdev( major, DEV_NAME, &gpio_fops ) )  

{

printk("\n register device %s OK (major=%d)\n\n", DEV_NAME, major );

}        

else

{        

printk("\n unable to get major %d for %s \n\n", major, DEV_NAME );

return -EBUSY;

}


/// 하드웨어 초기화

hw_gpio_init();



return 0;

}


//------------------------------------------------------------------------------

/** @brief   exit

    @remark  

*///----------------------------------------------------------------------------

static __exit void gpio_exit( void )

{

    /// 장치등록을 해지한다.

    unregister_chrdev( major, DEV_NAME );


    printk("\n unregister %s OK\n\n", DEV_NAME );

}



module_init(gpio_init);

module_exit(gpio_exit);


module_param(major, int, 0);

module_param(showmsg, int, 0);

MODULE_AUTHOR("tsheaven@falinux.com");

MODULE_LICENSE("GPL");


/* end */



2. 헤더파일


#] vi dev_gpio.h


/*-----------------------------------------------------------------------------
  파 일 : dev_gpio.h
  설 명 : 
  작 성 :
  날 짜 :
  주 의 :

-------------------------------------------------------------------------------*/
#ifndef _DEV_GPIO_H_
#define _DEV_GPIO_H_


/* 모듈관련 -------------------------------------------------------------------*/
#define GPIO_MAJOR_DEF 194
#define DEV_NAME "EZ-S3C6410 GPIO ver 1.00"

/* ioctl 함수의 command -------------------------------------------------------*/
#define GPIO_IOCTL_MAGIC 'd'

#define IOCTL_BUZZER_ON _IO ( GPIO_IOCTL_MAGIC, 1 )
#define IOCTL_BUZZER_OFF _IO ( GPIO_IOCTL_MAGIC, 2 )

#endif  // _DEV_GPIO_H_



3. 어플리케이션


#] vi app_gpio.c


//------------------------------------------------------------------------------

// 파일명   : main.c

// 프로젝트 : 

// 작성자   :

// 작성일   :

// 수정일   : 

//

// 설  명   : 

//             

//------------------------------------------------------------------------------

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/stat.h>


#include "dev_gpio.h"


#define VERSION_STR "Ver 1.00"


int dev_fd; //  파일핸들


//------------------------------------------------------------------------------

// 설명 : 디바이스 드라이버 열기

// 주의 : 없음

//------------------------------------------------------------------------------

int dev_open( char *fname, unsigned char major, unsigned char minor )

{

int dev;

dev = open( fname, O_RDWR|O_NDELAY );

if (dev == -1 )

{

mknod( fname, (S_IRWXU|S_IRWXG|S_IFCHR), (major<<8)|(minor) );

dev = open( fname, O_RDWR|O_NDELAY );

if (dev == -1 )

{

printf( " Device OPEN FAIL %s\n", fname );

return -1;

}

}

        

return dev;

}


//------------------------------------------------------------------------------

// 설명 : main함수를 정의 한다.

// 주의 : 없음

//------------------------------------------------------------------------------

int main( int argc, char **argv )

{       

printf( "\n  Program Ver %s  %s %s\n", VERSION_STR, __DATE__, __TIME__ );


dev_fd = dev_open("/dev/gpio", GPIO_MAJOR_DEF, 0 );


ioctl( dev_fd, IOCTL_BUZZER_ON );

sleep(1);

ioctl( dev_fd, IOCTL_BUZZER_OFF );


close( dev_fd );


return 0;

}



4. Makefile


#] vi app_gpio.c


#

# kernel 2.6 driver Makefile

#

obj-m := dev_gpio.o


KDIR   := /kernel/linux

PWD   := $(shell pwd)


APP = app_gpio


default:

$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

arm-generic-linux-gnueabi-gcc -o $(APP) $(APP).c


clean :

rm -rf *.ko

rm -rf *.mod.*

rm -rf .*.cmd

rm -rf *.o



[주의]

1.  Makefile 에서   KDIR  := /kernel/linux     은 S3C610 커널이 있는 디렉토리 위치를 써야 합니다.

2. 크로스 컴파일러가 설치되어 있어야 합니다. 현재 사용된  GCC 크로스 컴파일러는 arm-generic-linux-gnueabi-gcc 입니다.



다음에는 디바이스 드라이버 방식이 아닌 어플리케이션에서 직접 mmap를 이용하여 부져를 구동해 보도록 하겠습니다.