2-3 BEEP 驅動程式開發(包含驅動和測試程式)

來源:互聯網
上載者:User

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驅動

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.