6-1 MISC device driver development and instance
1. Instance
1.1 driver
(1) driver source code \ beep_misc \ driver \ beep_misc.c:
# Include <Linux/errno. h> # include <Linux/kernel. h> # include <Linux/module. h> # include <Linux/slab. h> # include <Linux/input. h> # include <Linux/init. h> # include <Linux/Serio. h> # include <Linux/delay. h> # include <Linux/CLK. h> # include <Linux/miscdevice. h> # include <Linux/gpio. h> # include <ASM/Io. h> # include <ASM/IRQ. h> # include <ASM/uaccess. h> # include <Mach/regs-clock.h> # include <plat/regs-timer.h> # include <Mach/ Regs-gpio.h> // opt/linux-2.6.34/ARCH/ARM/mach-s3c2410/include/Mach/regs-gpio.h # include <Linux/cdev. h> # define device_name "beep" module_author ("Hanson he"); module_license ("dual BSD/GPL"); # define beep_magic 'K' # define beep_start_cmd _ IO (beepmagic, 1) # define beep_stop_cmd _ IO (beep_magic, 2)/** open the device; in fact, there's nothing to do here. */INT beep_open (struct inode * inode, struct file * Filp) {return 0;} 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;} void beep_stop (void) {// Add your src here !!! // Set gpb0 as outputs3c2410_gpio_cfgpin (s3c2410_gpb (0), s3c2410_gpio_output); s3c2410_gpio_setpin (s3c2410_gpb (0), 0);} void beep_start (void) {// Add your src here !!! // Set gpb0 as round (s3c2410_gpb (0), 1); Round (s3c2410_gpb (0), s3c2410_gpio_output); s3c2410_gpio_setpin (s3c2410_gpb (0), 1 );} static int beep_ioctl (struct inode * inode, struct file * file, unsigned int cmd, unsigned long Arg) {// Add your src here !!! Switch (CMD) {Case beep_start_cmd: {beep_start (); break;} case beep_stop_cmd: {beep_stop (); break;} default: {break;} return 0 ;} static int beep_release (struct inode * node, struct file * file) {return 0;}/** our various sub-devices. * // * device 0 uses remap_pfn_range */static struct file_operations beep_remap_ops = {. owner = this_module ,. open = beep_open ,. release = beep_release ,. read = beep_read ,. write = beep_write ,. IOCTL = beep_ioctl,};/** there's no need for us to maintain any * Special housekeeping info, so we just deal with raw cdevs. */static struct miscdevice MISC = {. minor = misc_dynamic_minor, // dynamic device number. name = device_name ,. foPs = & beep_remap_ops,};/** module housekeeping. */static int beep_init (void) {int ret; ret = misc_register (& MISC); printk ("the device name is: % s \ n", device_name ); return 0;} static void beep_cleanup (void) {misc_deregister (& MISC); printk ("beep device uninstalled \ n");} module_init (beep_init); module_exit (beep_cleanup );
(2) makefile:
ifeq ($(KERNELRELEASE),)#KERNELDIR ?= /your/target/source/directory/KERNELDIR ?=/opt/linux-2.6.34PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions.PHONY: modules modules_install cleanelse obj-m := beep_misc.oendif
1.2 user program
(1) User source code \ beep_misc \ User \ main. C:
/* * main.c : test beep driver */#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 i = 0;int dev_fd;dev_fd = open("/dev/beep",O_RDWR | O_NONBLOCK);if ( dev_fd == -1 ) {printf("Cann'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;}
(2) makefile:
KERNELDIR ?=/opt/linux-2.6.34all: beep_test beep_test : main.c#arm-linux-gcc -I$(KERNELDIR) -s -Wl,-warn-common --static -o $@ $^arm-linux-gcc -I$(KERNELDIR) -o $@ $^clean :rm beep_test
Statement: This article is not original and organized from application embedding.