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À» ¹ÝȯÇÑ´Ù. 
// ÁÖÀÇ : ÀÌ ÇÔ¼öÀDZ¸¼ºÀº ¿À·¼¸®°¡ °¡Àå ½È¾îÇÏ´Â ÇüÅ´٠
// Áï µð¹ÙÀ̽º¸¦ ¿ÀÇ ÇÒ¼ö ÀÖ´Â ±âȸ´Â ´Ü ÇѹøÀ¸·Î Á¦¾àÀ» °¡ÇÏ°í ÀÖ´Ù. 
// 
// Áï ÇÑ ¾îÇø®ÄÉÀ̼ǿ¡¼­ ¿ÀÇÂÀ» ÇÏ¿© Á¡À¯ÇÏ¸é ´Ù¸¥ ¾îÇø®ÄÉÀ̼ÇÀº Á¡À¯ÇÏÁö ¸øÇÑ´Ù. 
//------------------------------------------------------------------- 


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À» ¹ÝȯÇÑ´Ù. 
// ÁÖÀÇ : ÀÌ ÇÔ¼öÀDZ¸¼ºÀº ¿À·¼¸®°¡ °¡Àå ½È¾îÇÏ´Â ÇüÅ´٠
// Áï µð¹ÙÀ̽º¸¦ ¿ÀÇ ÇÒ¼ö ÀÖ´Â ±âȸ´Â ´Ü ÇѹøÀ¸·Î Á¦¾àÀ» °¡ÇÏ°í ÀÖ´Ù. 
// 
// Áï ÇÑ ¾îÇø®ÄÉÀ̼ǿ¡¼­ ¿ÀÇÂÀ» ÇÏ¿© Á¡À¯ÇÏ¸é ´Ù¸¥ ¾îÇø®ÄÉÀ̼ÇÀº Á¡À¯ÇÏÁö ¸øÇÑ´Ù. 
//------------------------------------------------------------------- 


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