参考地址: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 02 unload_rdwrdev
#!/bin/sh rmmod parport_drv.ko rm /dev/parport_dev