buffer.c
#include <linux/fs.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/ioport.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/irq.h> #include <linux/interrupt.h> #include <asm/mach/irq.h> #include <asm/arch/regs-gpio.h> static int major = 0; static struct class *cls; #define BUF_LEN 10 static char kern_buf[BUF_LEN]; static volatile int r = 0, w = 0; static wait_queue_head_t read_waitq; static wait_queue_head_t write_waitq; static int isEmpty(void) { return (r == w); } static int isFull(void) { return (r == ((w+1)%BUF_LEN)); } static int putData(char val) { if (isFull()) { return -1; } else { kern_buf[w] = val; w = (w+1)%BUF_LEN; return 0; } } static int getData(char *p) { if (isEmpty()) { return -1; } else { *p = kern_buf[r]; r = (r+1)%BUF_LEN; return 0; } } ssize_t buffer_read(struct file *file, char __user *buf, size_t size, loff_t *offset) { int i = 0; char val; do { wait_event_interruptible(read_waitq, !isEmpty()); while ((i < size) && getData(&val) == 0) { copy_to_user(buf+i, &val, 1); wake_up_interruptible(&write_waitq); i++; } } while (i < size); return size; } ssize_t buffer_write(struct file *file, const char __user *buf, size_t size, loff_t *offset) { int i = 0; char val; do { wait_event_interruptible(write_waitq, !isFull()); while ((i < size) && !isFull()) { copy_from_user(&val, buf+i, 1); putData(val); i++; wake_up_interruptible(&read_waitq); } } while (i < size); return size; } static struct file_operations buffer_fops = { .owner = THIS_MODULE, .read = buffer_read, .write = buffer_write, }; int buffer_init(void) { major = register_chrdev(0, "buffer", &buffer_fops); cls = class_create(THIS_MODULE, "buffer_class"); class_device_create(cls, NULL, MKDEV(major, 0), NULL, "buffer"); // mdev會根據/sys下的這些内容建立/dev/buffer init_waitqueue_head(&read_waitq); init_waitqueue_head(&write_waitq); return 0; } void buffer_exit(void) { unregister_chrdev(major, "buffer"); class_device_destroy(cls, MKDEV(major, 0)); class_destroy(cls); } module_init(buffer_init); module_exit(buffer_exit); MODULE_LICENSE("GPL"); |
reader.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char **argv) { int fd; char buf[10]; int i; fd = open("/dev/buffer", O_RDONLY); read(fd, buf, 10); printf("data: "); for (i = 0; i < 10; i++) printf("%c ", buf[i]); printf("\n"); return 0; } |
writer.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char **argv) { int fd; char buf[10]; int i; if (argc != 2) { printf("Usage: \n"); printf("%s string\n", argv[0]); return 0; } fd = open("/dev/buffer", O_WRONLY); write(fd, argv[1], strlen(argv[1])); return 0; } |