Device

Go back

OS Review
Device Driver
NS Tools

Home
Papers
Daily Link


To Main
Printer Port로 LED 점멸 제어
 
=================== test.c ==========================================
// 
// 화일명 : test.c 
// 설 명 : 프린터 IO 포트 드라이버를 시험한다. 
// 작성자 : 유영창 (주)JDT 
// 저작권 : GNU 
// 수정일 : 
// 주 의 : 1. 이것은 학습을 위하여 커널 2.1이후용으로만 정의 하였다. 
// 2. 이것은 학습을 위하여 자체 헤더화일 정의를 사용하지 않았다. 
// 
//******************************************************************* 

#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h>
#include <sys/types.h> 
#include <sys/stat.h>
#include <fcntl.h>

//******************************************************************* 
// 
// 함수 정의 
// 
//******************************************************************* 

//------------------------------------------------------------------- 
// 설명 : 디바이스 드라이버를 열고 닫고 쓰는 시험을 한다. 
// 매계 : 없음 
// 반환 : 정상이면 0을 반환한다. 
// 주의 : 없음 
//------------------------------------------------------------------- 

int main(int argc, char **argv) 
{ 
    int dev; 
    int loop; 
    char buff[2]; 

    dev = open("prnioport", O_WRONLY|O_NDELAY ); 

    if (dev != -1) 
    { 
        printf( "PRNIOPORT OPEN OK \n"); 

        for( loop = 0; loop < 10; loop++ ) 
        { 
            sleep(1); // 1 초 대기 한다. 
            buff[0] = 0x00; // LED를 끈다. 
            write(dev,buff,1); // 프린터 포트에 쓴다. 
            sleep(1); // 1 초 대기 한다. 
            buff[0] = 0xff; // LED를 켠다. 
            write(dev,buff,1); // 프린터 포트에 쓴다. 
        } 

        close(dev); 

        printf( "PRNIOPORT CLOSE \n"); 

    } else { 
        printf( "PRNIOPORT OPEN FAIL \n"); 
        exit(-1); 
    } 

    return(0); 
} 
=================== test.c ==========================================


================ prnioport.c =========================================
// 
// 화일명 : prnioport.c 
// 설 명 : 프린터 IO 포트를 직접 제어 한다. 
// 작성자 : 유영창 (주)JDT 
// 저작권 : GNU 
// 수정일 : 
// 주 의 : 1. 이것은 학습을 위하여 커널 2.1이후용으로만 정의 하였다. 
// 2. 이것은 학습을 위하여 자체 헤더화일 정의를 사용하지 않았다. 
// 
//******************************************************************* 

#include <linux/ioport.h> 
#include <asm/uaccess.h>
#include <linux/module.h> 
#include <linux/fs.h> 
#include <asm/io.h> 


#define PRNIOPORT_MAJOR 88 // 프린터 IO 를 위한 메이저 번호 
#define PRNIOPORT_NAME "PRINT IO PORT" // 프린터 장치명 이름 
#define PRNIOPORT_MODULE_VERSION "PRINT IO PORT V0.2" // 프린터 장치명 이름 및 버전 번호 
#define PRNIOPORT_ADDRESS 0x0378 // LPT1은 이 주소를 사용. 
#define PRNIOPORT_ADDRESS_RANGE 3 // LPT1은 이 주소범위를 사용. 

//******************************************************************* 
// 
// 광역 변수 정의 
// 
//******************************************************************* 

static int prnioport_usage=0; // 디바이스 오픈 상태 1이면 사용 / 0이면 미사용 상태 

//******************************************************************* 
// 
// 함수 정의 
// 
//******************************************************************* 

//------------------------------------------------------------------- 
// 설명 : 어플리케이션에서 디바이스 open을 하였을때 호출되는 함수 
// 매계 : 없음 
// 반환 : 정상이면 0을 반환한다. 
// 주의 : 이 함수의구성은 오렐리가 가장 싫어하는 형태다 
// 즉 디바이스를 오픈 할수 있는 기회는 단 한번으로 제약을 가하고 있다. 
// 
// 즉 한 어플리케이션에서 오픈을 하여 점유하면 다른 어플리케이션은 점유하지 못한다. 
//------------------------------------------------------------------- 


int prnioport_open(struct inode *minode, struct file *mfile) 
{ 

    // 이미 사용중이면 사용중이라는 값을 되돌린다. 
    if( prnioport_usage != 0 ) return -EBUSY; 

    MOD_INC_USE_COUNT; // 모듈 사용 증가 카운터 매크로 

    prnioport_usage = 1; // 사용 중 

    printk("PRN IOPORT DRIVE OPEN \n"); 

    return(0); 
} 


//------------------------------------------------------------------- 
// 설명 : 어플리케이션에서 디바이스를 close를 하였을때 호출되는 함수 
// 매계 : 없음 
// 반환 : 정상이면 0을 반환한다. 
// 주의 : 이 함수의구성은 오렐리가 가장 싫어하는 형태다 
// 즉 디바이스를 오픈 할수 있는 기회는 단 한번으로 제약을 가하고 있다. 
// 
// 즉 한 어플리케이션에서 오픈을 하여 점유하면 다른 어플리케이션은 점유하지 못한다. 
//------------------------------------------------------------------- 


int prnioport_release(struct inode *minode, struct file *mfile) 
{ 
    MOD_DEC_USE_COUNT; // 모듈 사용횟수를 감소 시킨다. 

    prnioport_usage = 0; // 사용하지 않음을 표시 

    printk("PRN IOPORT DRIVE CLOSE \n"); 

    return 0; 
} 


//------------------------------------------------------------------- 
// 설명 : 어플리케이션에서 디바이스를 write를 하였을때 호출되는 함수 
// 매계 : gdata : 어플리케이션 영역의 버퍼 주소 
// length : 버퍼 크기 
// off_what : ? 
// 반환 : 정상이면 처리된 바이트 수를 반환한다. 
// 주의 : 없음 
//------------------------------------------------------------------- 


ssize_t prnioport_write_byte(struct file *inode, const char *gdata, size_t length, loff_t *off_what) 
{ 
    int i; 
    const char *data; 
    char c; 

    data=gdata; 

    for (i=0; i 
    { 
        get_user( c, (char *)(data+i) ); // 어플리케이션 영역에서 한 바이트를 얻는다. ( uaccess.h에 정의 되어 있다. ) 
        outb( c , PRNIOPORT_ADDRESS ); // 프린터포트에 쓴다. ( io.h에 정의 되어 있다. ) 
        printk( "write %0X \n",c & 0xff ); 
    } 

    // 사용된 길이만큼 돌려 준다. 
    return(length); 
} 


//------------------------------------------------------------------- 
// 설명 : insmod함수에 의해서 호출되는 함수 
// 매계 : 없음 
// 반환 : 정상이면 0을 반환한다. 
// 주의 : 없음 
//------------------------------------------------------------------- 


int init_module(void) 
{ 

// 드라이버에 사용되는 접근 함수에 대한 함수 포인터 구조체를 정의한다. 
// 이 구조체는 fs.h에 정의 되어 있다. 


static struct file_operations lcd_fops = 
{ 
    NULL, // loff_t (*llseek) (struct file *, loff_t, int); 
    NULL, // ssize_t (*read) (struct file *, char *, size_t, loff_t *); 
    prnioport_write_byte, // ssize_t (*write) (struct file *, const char *, size_t, loff_t *); 
    NULL, // int (*readdir) (struct file *, void *, filldir_t); 
    NULL, // unsigned int (*poll) (struct file *, struct poll_table_struct *); 
    NULL, // int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); 
    NULL, // int (*mmap) (struct file *, struct vm_area_struct *); 
    prnioport_open, // int (*open) (struct inode *, struct file *); 
    NULL, // int (*flush) (struct file *); 
    prnioport_release, // int (*release) (struct inode *, struct file *); 
    NULL, // int (*fsync) (struct file *, struct dentry *); 
    NULL, // int (*fasync) (int, struct file *, int); 
    NULL, // int (*check_media_change) (kdev_t dev); 
    NULL, // int (*revalidate) (kdev_t dev); 
    NULL // int (*lock) (struct file *, int, struct file_lock *); 
}; 


// 장치를 등록한다. 

if( !register_chrdev( PRNIOPORT_MAJOR, PRNIOPORT_NAME, &lcd_fops )) 
{ 

    printk(" register_chrdev %s Ok n", PRNIOPORT_MODULE_VERSION ); 

    // 영역이 이미 사용되고 있는지를 검사한다. ( ioport.h에 정의 되어 있다. ) 
    if (!check_region( PRNIOPORT_ADDRESS, PRNIOPORT_ADDRESS_RANGE )) 
    { 

        // 사용되지 않고 있다면 IO 영역을 등록한다. ( ioport.h에 정의되어 있다. ) 
        request_region( PRNIOPORT_ADDRESS, PRNIOPORT_ADDRESS_RANGE, PRNIOPORT_NAME ); 

        printk(" got %d addresses from %x \n",PRNIOPORT_ADDRESS_RANGE, PRNIOPORT_ADDRESS ); 

        printk(" %s DRIVE REGISTER OKn", PRNIOPORT_NAME ); 

    } else { 

        // 이미 사용되었다면 등록된 장치를 제거한다. ( ioport.h에 정의되어 있다. ) 

        unregister_chrdev( PRNIOPORT_MAJOR, PRNIOPORT_NAME ); 

        printk(" could not get %d addresses from %x \n",PRNIOPORT_ADDRESS_RANGE, PRNIOPORT_ADDRESS ); 
    } 

} else { 

    // 등록되지 못했다. 
    printk("unable to get major %d for %s \n", PRNIOPORT_MAJOR, PRNIOPORT_NAME ); 
} 

return 0; 

} 


//------------------------------------------------------------------- 
// 설명 : rmmod함수에 의해서 호출되는 함수 
// 매계 : 없음 
// 반환 : 없음 
// 주의 : 없음 
//------------------------------------------------------------------- 


void cleanup_module(void) 
{ 

// 커널에 등록된 IO 어드레스 영역을 해제한다. 
release_region( PRNIOPORT_ADDRESS, PRNIOPORT_ADDRESS_RANGE ); 


// 등록된 장치 함수 구조체를 해제한다. 
    if( !unregister_chrdev( PRNIOPORT_MAJOR, PRNIOPORT_NAME )) 
    { 
        printk("%s DRIVER CLEANUP OK \n", PRNIOPORT_NAME); 
    } else { 
        printk("%s DRIVER CLEANUP FAILED \n", PRNIOPORT_NAME); 
    } 

} 
==prnioport.c======================================================== 



==Makefile=========================================================== 
#DEBUG = y 

INCLUDEDIR = /usr/src/linux/include 

ifeq ($(DEBUG),y) 
DEBFLAGS = -O -g -DJIT_DEBUG -DJIQ_DEBUG -DALL_DEBUG 
else 
DEBFLAGS = -O2 
endif 

CFLAGS = -D__KERNEL__ -DMODULE -Wall $(DEBFLAGS) 

CFLAGS += -I$(INCLUDEDIR) 

OBJS = prnioport.o 

all: $(OBJS) 
$(CC) $(CFLAGS) -c $^ -o $@ 

clean: 
rm -f *.o *.~* 

==Makefile=========================================================== 


mknod /dev/prnioport c 88 0 

make

/sbin/insmod prnioport.o

test.c 컴파일 & 실행

/sbin/rmmod prnioport