android9.0 從driver到APP(1)--driver

注:本文爲個人學習記錄,可能存在個別或多處錯誤,歡迎指正和討論。

新建了一個 驅動程序,提供 “/dev/sample” 設備作爲測試使用。

/*
 * Sample Driver
 *
 * Copyright (C) 2012 Alex,All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>

#include <linux/sample.h>

static int sample_val = 0;
static int sample_open(struct inode *node, struct file *filp)
{
    printk(KERN_INFO"open sample dev done! \n");

    return 0;
}

static int sample_close(struct inode *node, struct file *filp)
{
 	printk(KERN_INFO"close sample dev done! \n");

    return 0;
}


static ssize_t sample_write(struct file *filp,const char __user *ubuf,
							size_t length,loff_t *offset)
{
	int rets = 0;
	if(length> sizeof(sample_val))
		length = sizeof(sample_val);

	rets = copy_from_user(&sample_val,ubuf,length);
    if(rets !=0){
		printk(KERN_ERR"sample_write failed! \n");
		rets = length - rets;
    }else{
        rets = length;
    }
	return rets;
}

static ssize_t sample_read(struct file *filp,char __user *ubuf,
							size_t length,loff_t *offset)
{
	int rets =0;
	rets = copy_to_user(ubuf,&sample_val,sizeof(sample_val));
    if(rets !=0){
		rets = sizeof(sample_val) - rets;
		printk(KERN_ERR"sample_read failed! \n");
	}
    else{
        rets = sizeof(sample_val);
    }
	return rets;
} 

static long sample_ioctl(struct file *filp , unsigned int cmd, unsigned long arg)
{
	int ret = 0;
	switch(cmd)
	{
		case SAMPLE_IOTEST_CMD:
			printk(KERN_INFO"SAMPLE_IOTEST_SETCMD! \n");
			break;

		case SAMPLE_IOTEST_SETVAL:
			printk(KERN_INFO"SAMPLE_IOTEST_SETVAL! \n");
			if(copy_from_user(&sample_val,(int __user *)arg,sizeof(sample_val))){
				ret = -EFAULT;
				printk(KERN_ERR"SAMPLE_IOTEST_SETVAL failed! \n");
			}
			break;

		case SAMPLE_IOTEST_GETVAL:
			printk(KERN_INFO"SAMPLE_IOTEST_GETVAL! \n");
			if(copy_to_user((int __user *)arg,&sample_val,sizeof(sample_val))){
				ret = -EFAULT;
				printk(KERN_ERR"SAMPLE_IOTEST_SETVAL failed! \n");
			}
			break;

		default:
			printk(KERN_ERR"unsupport commond! \n");
			break;
	}

	return ret;
}

static struct file_operations sample_fops = {
	.owner   = THIS_MODULE,
    .open    = sample_open,
    .release = sample_close,
    .read 	 = sample_read,
    .write	 = sample_write,
    .unlocked_ioctl = sample_ioctl,
};

static struct miscdevice sample_misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "sample",
    .fops = &sample_fops,
};

static int __init sample_init(void)
{
	int rets =0;
	printk("drivr sample \n");

    rets = misc_register(&sample_misc);
    if (rets != 0){
        printk("Sample misc register failed!");
         return -1;
    }

	return 0;
}

static void __exit sample_exit(void)
{
	misc_deregister(&sample_misc);
	return;
}


module_init(sample_init);
module_exit(sample_exit);

MODULE_AUTHOR("Alex");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("sample driver");
MODULE_VERSION("v0.0.1")

頭文件:

#ifndef _SAMPLE_H_
#define _SAMPLE_H_
/* ioctls
   0x53 is 'S'                              */
#define SAMPLE_IOTEST_CMD		0x5300
#define SAMPLE_IOTEST_SETVAL	0x5301
#define SAMPLE_IOTEST_GETVAL	0x5302
#endif

Android系統中使用魔術字會報錯,直接定義數字。
頭文件路徑:

include/uapi/linux/

HAL層關聯的路徑是:

bionic/libc/kernel/uapi/linux/

關於bionic的介紹:
Bionic是Android平臺爲了使用C/C++進行原生應用程序開發所有提供的POSIX標準C庫。它是Google爲Android操作系統提供的BSD標準C庫的衍生庫。同時Bionic是專門爲移動計算而精心設計的,針對移動設備上有限的CPU週期和可用內存進行了裁剪以提高工作效率。
網上還有很多介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章