今天太晚了,很困,把mini 2440 beep的驱动的代码调试通过之后,开发板成功"滴~"的发出了声音,于是还是挺开心的,在睡觉前把这些代码贴上,择日详解,敬请关注.
首先是驱动代码:beepdriver.c
#include <linux/module.h> //#include <linux/error.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/gpio.h> #include <asm/uaccess.h> #include <asm/io.h> #include <mach/irqs.h> #include <mach/regs-gpio.h> #include <mach/hardware.h> #include <linux/device.h> #include <linux/cdev.h> #define BEEP_MAGIC 'k' #define BEEP_START_CMD _IO(BEEP_MAGIC, 1) #define BEEP_STOP_CMD _IO(BEEP_MAGIC, 2) MODULE_LICENSE("Dual BSD/GPL"); int major; int result; dev_t devno; static struct cdev beepDev; struct class *beep_class; void beep_stop(void) { s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPB(0), 0); } void beep_start(void) { s3c2410_gpio_pullup(S3C2410_GPB(0), 1); s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPB(0), 1); } static int beep_release(struct inode *node, struct file *file) { return 0; } static int beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case BEEP_START_CMD: beep_start(); break; case BEEP_STOP_CMD: beep_stop(); break; default: break; } return 0; } static int beep_open(struct inode *inode, struct file *filp) { return 0; } static ssize_t beep_read(struct file *file, char __user *buff, size_t count, loff_t *offp) { return 0; } ssize_t beep_write(struct file *file, const char __user *buff, size_t count, loff_t *offp) { return 0; } static struct file_operations beep_ops = { .owner = THIS_MODULE, .open = beep_open, .read = beep_read, .release = beep_release, .write = beep_write, .ioctl = beep_ioctl, }; //init beep driver and get major number. static int beep_init(void) { int err; char dev_name[] = "beep"; if (major) { devno = MKDEV(major, 0); result = register_chrdev_region(devno, 1, dev_name); } else { //系统自动分配设备号 result = alloc_chrdev_region(&devno, 0, 1, dev_name); major = MAJOR(devno); } if (result < 0) { printk(KERN_WARNING "beep: can't get major %d\n", major); } devno = MKDEV(major, 0); cdev_init(&beepDev, &beep_ops); beepDev.owner = THIS_MODULE; beepDev.ops = &beep_ops; err = cdev_add(&beepDev, devno, 1); if (err) { printk(KERN_NOTICE "Error %d adding beep%d", err, 0); } beep_class = class_create(THIS_MODULE, "beepdrv"); if (IS_ERR(beep_class)) { printk("Err:failed in creating class.\n"); return 1; } device_create(beep_class, NULL, MKDEV(major, 0), NULL, "beep"); printk("beep device installed, with major %d\n", major); printk("The device name is: %s\n", dev_name); return 0; } static void beep_exit(void) { cdev_del(&beepDev); unregister_chrdev_region(MKDEV(major, 0), 1); device_destroy(beep_class, MKDEV(major, 0)); class_destroy(beep_class); printk("beep device uninstalled\n"); } module_init(beep_init); module_exit(beep_exit);
其次是测试的代码:beeptest.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <linux/ioctl.h> #define BEEP_MAGIC 'k' #define BEEP_START_CMD _IO(BEEP_MAGIC, 1) #define BEEP_STOP_CMD _IO(BEEP_MAGIC, 2) int main(int argc, char *argv[]) { int i = 0; int dev_fd; dev_fd = open("/dev/beep", O_RDWR | O_NONBLOCK); if (dev_fd == -1) { printf("Can't open file /dev/beep\n"); exit(1); } printf("Start beep\n"); ioctl(dev_fd, BEEP_START_CMD, 0); getchar(); ioctl(dev_fd, BEEP_STOP_CMD, 0); printf("Stop beep and Close device\n"); close(dev_fd); return 0; }
最后是Makefile:
ifneq ($(KERNELRELEASE),) obj-m := beepdriver.o else KERNELDIR ?= /usr/src/linux-2.6.32.2 PWD := $(shell pwd) defalut: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: @rm -rf *.ko *.o *.symvers *.order *.mod.c endif
文章的脚注信息由WordPress的wp-posturl插件自动生成