2-3 BEEP 驱动程序开发(包含驱动和测试程序)
来源:互联网 发布:java网上订餐系统源码 编辑:程序博客网 时间:2024/06/05 12:42
1、电路图
2、Linux-2.6.32.2内核重要头文件目录:
linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
linux-2.6. 32.2/arch/arm/plat-s3c24xx/gpio.c
linux-2.6. 32.2/include/linux/asm-generic/io.h
linux-2.6. 32.2/include/linux/wait.h
链接关系。如:出现asm则链接之后的内容
asm --- linux-2.6.32.2/include/linux/asm-generic
mach --- linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach
plat --- linux-2.6.32.2/arch/arm/plat-s3c24xx/include/plat
linux-2.6.32.2/arch/arm/plat-s3c/include/plat
3、代码阅读分析
拿到驱动代码首先看下面这个两个宏:
module_init(beep_init); /*模块加载时调用beep_init函数进行加载*/
module_exit(beep_cleanup); /*模块卸载时调用beep_cleanup函数进行清除*/
4.源代码beep_drv.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> /*出现asm 则它会连接到 linux-2.6.32.2/include/linux/asm-generic*/#include <asm/uaccess.h>#include <mach/regs-clock.h>#include <plat/regs-timer.h> #include <mach/regs-gpio.h>//这个文件在inux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/regs-gpio.h中// /opt/linux-2.6.34/arch/arm/mach-s3c2410/include/mach/regs-gpio.h#include <linux/cdev.h>static int beep_major = 0;/*全局主设备号*/module_param(beep_major, int, 0);/*传递参数这里没有到*/MODULE_AUTHOR("Hanson He"); /*声明作者*/MODULE_LICENSE("Dual BSD/GPL");/*指定使用什么协议的*/#define BEEP_MAGIC 'k'#define BEEP_START_CMD _IO (BEEP_MAGIC, 1)#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)/* _IO(type,nr)用于构造无参数的命令编号;*//* * 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 outputs3c2410_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_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;}/* * Set up the cdev structure for a device. */static void beep_setup_cdev(struct cdev *dev, int minor,struct file_operations *fops){int err, devno = MKDEV(beep_major, minor);/*由主次设备号生成设备号*/ cdev_init(dev, fops); /* 初始化cdev*/dev->owner = THIS_MODULE;dev->ops = fops;err = cdev_add (dev, devno, 1);/* 注册设备*//* Fail gracefully if need be */if (err)printk (KERN_NOTICE "Error %d adding beep%d", err, minor);}/* * Our various sub-devices. *//* Device 0 uses remap_pfn_range */static struct file_operationKERNELDIR ?=/home/student/linux-2.6.32.2all: beep_test beep_test : beep_test.c#arm-linux-gcc -I$(KERNELDIR) -s -Wl,-warn-common --static -o $@ $^arm-linux-gcc -I$(KERNELDIR) -o $@ $^clean :rm beep_tests beep_remap_ops = { ?*file_operations的对象beep_remap_ops,并对其赋值*/.owner = THIS_MODULE, /*指向模块本身*/.open = beep_open, /*把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 cdev BeepDevs;/* * Module housekeeping. */static int beep_init(void)/*模块加载时调用beep_init函数进行加载*/{int result;dev_t dev = MKDEV(beep_major, 0);char dev_name[]="beep";/* Figure out our device number. */if (beep_major)/*设备号的分配*/result = register_chrdev_region(dev, 1, dev_name); /*手工 分配*/else {result = alloc_chrdev_region(&dev, 0, 1, dev_name);/*系统分配一个设备号0:第一个次设备号,1:一个设备*/beep_major = MAJOR(dev);/*取得主设备号*/}if (result < 0) {printk(KERN_WARNING "beep: unable to get major %d\n", beep_major);return result;}if (beep_major == 0)beep_major = result;/* Now set up cdev. */beep_setup_cdev(&BeepDevs, 0, &beep_remap_ops);printk("beep device installed, with major %d\n", beep_major);printk("The device name is: %s\n", dev_name);return 0;}static void beep_cleanup(void)/*模块卸载时调用beep_cleanup函数进行清除*/{cdev_del(&BeepDevs);/*注销设备*/unregister_chrdev_region(MKDEV(beep_major, 0), 1);/*释放占用的设备号*/printk("beep device uninstalled\n");}module_init(beep_init); /*模块加载时调用beep_init函数进行加载*/module_exit(beep_cleanup); /*模块卸载时调用beep_cleanup函数进行清除*/EXPORT_SYMBOL(beep_major);/*????*/相应的Makefile文件(参考)ifeq ($(KERNELRELEASE),)#KERNELDIR ?= /your/target/source/directory/KERNELDIR ?=/home/lwb/linux-2.6.32.2PWD := $(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_drv.oendif
5、 应该编译驱动、下载到板子上、注册。
6、 创建设备节点
$mknod /dev/node_name c major minor //char dev_name[]="beep";这里node_name为beep
7、 测试程序代码
#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;}
相应的Makefile文件KERNELDIR ?=/home/lwb/linux-2.6.32.2all: beep_test beep_test : beep_test.c#arm-linux-gcc -I$(KERNELDIR) -s -Wl,-warn-common --static -o $@ $^arm-linux-gcc -I$(KERNELDIR) -o $@ $^clean :rm beep_test
8、 编写Makefile
KERNELKDIR?=/opt/linux-2.6.32.2/include
all:test
test:test.c
arm-linux-gcc–I $(KERNELDIR) –o S@ S^ //–I $(KERNELDIR)表包含头文件
clean:
rm –rf test
9、举例:编写BEEP测试程序
9.1编写BEEP测试程序beep_drv.c,编译生成beep_drv.ko
9.2上电开发板,运行uImage内核
9.3下载模块文件到开发板
9.4动态加载模块文件insmod beep_drv.ko
9.5查看BEEP驱动系统自动分配的主设备号cat /proc/devices |grep beep
9.6制作BEEP对应的设备文件节点 mknod /dev/beep c major 0
9.7将编译生成的beep_test,下载到开发板,测试BEEP驱动
- 2-3 BEEP 驱动程序开发(包含驱动和测试程序)
- Tq2440 驱动学习(2)-beep驱动
- linux驱动开发—beep
- Android驱动开发-- 2.测试驱动程序
- LCD驱动程序三(驱动测试和总结)
- Linux驱动程序开发(4) - 字符设备驱动(3)-LED设备驱动和应用程序
- 驱动测试程序编写、驱动程序卸载与测试
- Linux globalfifo 驱动程序和测试程序
- Beep蜂鸣器驱动程序分析
- DM6467的OV5642 Linux驱动程序开发(三)——驱动测试
- Linux驱动开发⑤--在驱动程序中测试CPU中断
- S3C2440 测试程序(一)PWM控制蜂鸣器Beep(2000, 100)
- 测试驱动开发和IOC
- 内核驱动笔记(二)——beep驱动
- Nodejs的测试和测试驱动开发
- WDF驱动开发(3)- 用户模式程序和驱动的数据交互
- Windows驱动程序开发基础(四)驱动的编译调试和安装
- cppunit - 测试驱动开发入门(2)
- Android 设备驱动开发
- IOS学习笔记36——UIPasteboard/UIMenuController(二)
- JavaScript动态时间
- 我们该如何设计数据库(三)
- 黑马程序员--javaIO 之BufferedReader
- 2-3 BEEP 驱动程序开发(包含驱动和测试程序)
- Mongodb 安装与使用
- javaScript切换网页背景色
- Java 中的时间差
- Dede推荐文章与热点文章不显示?
- 【人脸识别】关于识别识别的一些名词解释以及函数说明
- php 5.3装apd高级调试器
- php从命令行中接收参数
- 捕鱼达人代码例子下载地址 Win版