Linux實現字元裝置驅動的基礎步驟

來源:互聯網
上載者:User

標籤:des   io   ar   os   sp   div   on   2014   art   

Linux應用程式層想要操作kernel層的API,比方想操作相關GPIO或寄存器,能夠通過寫一個字元裝置驅動來實現。


1、先在rootfs中的 /dev/ 下產生一個字元裝置。注意主裝置號 和 從裝置號。可用例如以下shell指令碼產生:

if [ ! -e audioIN ];then     sudo mknod audioIN c 240 0     fi

產生的裝置為 /dev/audioIN ,主裝置號240,從裝置號0。


2、寫audioINdriver.ko ,audioINdriver.c 基本代碼架構例如以下:代碼中定義了裝置名稱audioIN,裝置號240, 0 ,與之前建立的裝置一致。

/************************************************************************** * audioINdriver.c * * kang_liu <[email protected]> * 2014-07-15\**************************************************************************/#include <asm/uaccess.h>#include <asm/errno.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/module.h>#include <linux/cdev.h>#include <mach/gpio.h>//#include <mach/at91_rstc.h> /* debug *///#include <mach/at91_pmc.h>//#include <mach/at91_rstc.h>//#include <mach/at91_shdwc.h>#include <mach/irqs.h>//#include "generic.h"//#include "clock.h"#include <mach/w55fa92_reg.h>#include <asm/io.h>#define DEV_MAJOR 240#define DEV_MINOR 0#define NUM_MINORS 1#define DEVICE_NAME "audioIN"#define ERR(fmt, args...) printk(KERN_ALERT __FILE__ ": " fmt, ##args)#define MSG(fmt, args...) printk(KERN_INFO __FILE__ ": " fmt, ##args)#define DBG(fmt, args...) printk(KERN_DEBUG __FILE__ ": " fmt, ##args)static ssize_t user_gpio_read(struct file *fp, char __user *buff,                       size_t count, loff_t *offp){    char str[32] = {0};    char out[32] = {0};    int n, err;//    printk("lk~~~~~~~read buff = %s\n",buff);    err = copy_from_user(str, buff, count);//    printk("lk~~~~~~~read str = %s\n",str);    if (err)        return -EFAULT;sprintf(out,"return values");memset(buff, 0, count);err = copy_to_user(buff, out, sizeof(out));if (err)    return -EFAULT;    return n;}static ssize_t user_gpio_write(struct file *fp, const char __user *buff,                        size_t count, loff_t *offp){    int err;    char tmp[32];   //    printk("lk~~~~~~~write buff = %s\n",buff);    err = copy_from_user(tmp, buff, count);//    printk("lk~~~~~~~write tmp = %s\n",tmp);    if (err)        return -EFAULT;if('1' == tmp[0]){//LINE INprintk("line in\n");}else if('0' == tmp[0]){//MIC INprintk("mic in\n");}    return count;}static ssize_t user_gpio_open(struct inode *inode,struct file *fp) {//  printk("open gpio devices\n");     return 0; } static struct file_operations user_gpio_file_ops = {  .owner = THIS_MODULE,  .write = user_gpio_write,  .read = user_gpio_read,  .open = user_gpio_open, };static struct cdev *dev;static void __exit user_audioIN_exit(void){printk("exit audioIN\n");    dev_t devno = MKDEV(DEV_MAJOR, DEV_MINOR);    unregister_chrdev_region(devno, NUM_MINORS);    cdev_del(dev);    return;}static int __init user_audioIN_init(void){printk("init audioIN\n");    int err = 0;    int i;    dev_t devno = MKDEV(DEV_MAJOR, DEV_MINOR);    err = register_chrdev_region(devno, NUM_MINORS, DEVICE_NAME);    if (err)        goto fail_devno;    dev = cdev_alloc();    dev->ops = &user_gpio_file_ops;    dev->owner = THIS_MODULE;       err = cdev_add(dev, devno, NUM_MINORS);    if (err)        goto fail_cdev;        return err;fail_cdev:fail_devno:    unregister_chrdev_region(devno, NUM_MINORS);fail_gpio:    return err;}module_init(user_audioIN_init);module_exit(user_audioIN_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("kang_liu <[email protected]>");MODULE_DESCRIPTION("Access GSEIO from userspace."); 

這裡就能夠調用kernel層的一些API進行底層的操作。


Makefile:產生audioINdriver.ko

# Comment/uncomment the following line to disable/enable debugging#DEBUG = yBUILD_TOOLS_PRE = arm-linux-CC=$(BUILD_TOOLS_PRE)gccLD=$(BUILD_TOOLS_PRE)ld# Add your debugging flag (or not) to CFLAGSifeq ($(DEBUG),y)  DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlineselse  DEBFLAGS = -O2endifKERNEL_DIR = ../../../linux-2.6.35.4EXTRA_CFLAGS += $(DEBFLAGS)EXTRA_CFLAGS += -I$(LDDINC)EXTRA_CFLAGS +=-I$(KERNEL_DIR)/arch/arm/mach-w55fa92/includeEXTRA_CFLAGS +=-I$(KERNEL_DIR)/arch/armEXTRA_CFLAGS +=-I$(KERNEL_DIR)/arch/arm/includeEXTRA_CFLAGS +=-I$(KERNEL_DIR)/arch/arm/include/linuxifneq ($(KERNELRELEASE),)# call from kernel build systemaudioIN-objs := audioINdriver.oobj-m:= audioINdriver.oelseKERNELDIR ?= $(KERNEL_DIR)#KERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD       := $(shell pwd)modules:$(MAKE) ARCH=arm CROSS_COMPILE=$(BUILD_TOOLS_PRE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modulesendifclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symversdepend .depend dep:$(CC) $(CFLAGS) -M *.c > .dependifeq (.depend,$(wildcard .depend))include .dependendif

3. 產生好 .ko 以後,就能夠在ARM板上,載入驅動。

insmod audioINdriver.ko


4、載入驅動成功後,就能夠在應用程式層直接操作裝置 /dev/audioIN,來實現相關功能,將一些參數傳到驅動層,運行相關kernel層的代碼。

應用程式層測試程式例如以下:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/syscall.h>#define BUF_LEN 32int s_audioInFd = 0;int InitAudioInDevice(){s_audioInFd = open("/dev/audioIN",O_RDWR);if (s_audioInFd > 0){return 1;}else{printf("Can't open the GSE IO device\n");return 0;}}void UninitAudioInDevice(){if (s_audioInFd > 0)close(s_audioInFd);}int getAudioIn(){char buffer[BUF_LEN] = {0};if (s_audioInFd > 0){memcpy(&buffer[0], "lk_test", 7);//printf("get buffer = %s\n", buffer);int len = read(s_audioInFd, buffer, 7);//printf("get buffer = %s, len = %d\n", buffer, len);return len;}return -1;}int setAudioIn(int micLine){char buffer[BUF_LEN] = {0};if (s_audioInFd > 0){sprintf(buffer, "%d", micLine);int len = write(s_audioInFd, buffer, sizeof(buffer));if (len > 0)return 1;}return 0;}

當中的read 和 write函數,可從驅動中擷取一些返回值,也可將字串傳到驅動中。

驅動的入口為:

module_init(user_audioIN_init);
module_exit(user_audioIN_exit);


Linux實現字元裝置驅動的基礎步驟

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.