|
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
|