Linux並口設備驅動程序設置

參考地址:http://oss.org.cn/kernel-book/ldd3/ch09s03.html

並口的管腳

13腳接led的正輸入,25腳接led的負極


驅動代碼:

parport_drv.c

#include
#include
#include
#include
#include
#include
#include

#include"parport_drv.h"

#define	Drv_major 240
#define Drv_name  "parport_drv"
#define Drv_read_addr 0x379
#define Drv_write_addr 0x378

int parport_open(struct inode *inode, struct file *filp)
{
	printk(KERN_ALERT "open the parport_dev\n");
	return 0;
}

ssize_t parport_write(struct file *filp, const char *buf, size_t count, loff_t *f_ops)
{
	unsigned char status;
	int loop;
	for(loop = 0; loop < count; loop++)
	{
		get_user(status, (char *)buf);
		outb(status, Drv_write_addr);
	}
	return count;
}

ssize_t parport_read(struct file *filp, char *buf, size_t count, loff_t *f_ops)
{
	unsigned char status;
	int loop;
	for(loop = 0; loop < count; loop++)
	{
		status = inb(Drv_read_addr);
		put_user(status, (char *) &buf[loop]);
	}
	return count;
}

long	parport_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int loop;
	struct dat data;
	switch(cmd)
	{
		case PARPORT_WRITE:
//			outb(status, Drv_write_addr);
			copy_from_user(&data, (struct dat *)arg, sizeof(data));			
			printk(KERN_ALERT "out put %d\n",data.loop);
			for(loop = 0; loop < data.loop; loop ++)
			{
				printk(KERN_ALERT "the %dth loop, write %d\n",loop,data.buf[loop]);
				outb(data.buf[loop], Drv_write_addr);
				wmb();
			}
			break;

		case PARPORT_CLOSE:
			outb(0x00, Drv_write_addr);
			wmb();
			break;
	}
	return 0;
}

int parport_release(struct inode *inode, struct file *filp)
{
	printk(KERN_ALERT "close the module parport_dev\n");
	return 0;
}

struct file_operations parport_fops = {
	.owner	=	THIS_MODULE,
	.write	=	parport_write,
	.read	=	parport_read,
	.open	=	parport_open,
	.unlocked_ioctl	=	parport_ioctl,
	.release=	parport_release,
};

int parport_init(void)
{
	int result;

	result = register_chrdev(Drv_major, Drv_name, &parport_fops);
	if(result < 0)
		return result;
	printk(KERN_ALERT "hello the module parport_dev\n");

	return 0;
}

void parport_exit(void)
{
	printk(KERN_ALERT "exit the module parport_drv\n");
	unregister_chrdev(Drv_major, Drv_name);
	
}

module_init(parport_init);
module_exit(parport_exit);
parport_drv.h
#ifndef	_PARPORT_DRV_H
#define _PARPORT_DRV_H


#define	PARPORT_WRITE	1
#define	PARPORT_CLOSE	2


struct dat{
	int loop;
	unsigned char *buf;
};


#endif

測試代碼par_test.c


#include 
#include 
#include 
#include 
#include 
#include "parport_drv.h"
#define DEVICE_NAME "/dev/parport_dev"

int main()
{
	int fd;
	char buf[128];
	int loop;

	fd = open(DEVICE_NAME, O_RDWR | O_NDELAY);

	if(fd < 0)
	{
		perror("open device");
		exit(1);
	}
	else
	{
//		printf("waiting for input ...\n");
//
//		while(1)
//		{
//			if(read(fd, buf, 1) == 1)
//			{
//				printf("read data [%2X]\n", buf[0] & 0xFF);
//				if(!(buf[0] & 0x10))
//					break;
//			}
//			sleep(1);
//		}
//		printf("input ok ... \n");
//		printf("led begins to flash ... \n");
//		for(loop = 0; loop < 5; loop++)
//		{
//			buf[0] = 0xff;
//			write(fd, buf, 1);
//			sleep(1);
//			buf[0] = 0x00;
//			write(fd, buf, 1);
//			sleep(1);
//		}
		int i;
		int arg=0x99;
		unsigned char buf[255];
		struct dat da;
		da.loop = 4;
		da.buf = (unsigned char *)malloc(5 * sizeof(unsigned char));
		for(i = 0;i< da.loop; i++)
			da.buf[i] = i*2+1;
		for(i=0;i<da.loop;i++)
			printf("test:%d\n", da.buf[i]);
		ioctl(fd, PARPORT_WRITE,&da);
		sleep(1);
		ioctl(fd, PARPORT_CLOSE);
		sleep(1);
		close(fd);
	}

	return 0;
}
	

1 load_rdwrdev
#!/bin/sh

insmod parport_drv.ko
mknod /dev/parport_dev c 240 0
2 unload_rdwrdev
#!/bin/sh

rmmod parport_drv.ko
rm /dev/parport_dev
發佈了51 篇原創文章 · 獲贊 23 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章