Linux\Android 常用驱动框架

driver.c

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>

#include "driver.h"

static int xxx_dt_parse(struct platform_device *pdev)
{
	int m, n;
	unsigned char i;
	struct device_node *node, *child;
	struct xxx_dev *ldev;
	enum of_gpio_flags flags;
	ldev = platform_get_drvdata(pdev);
	node = pdev->dev.of_node;
	if (!node) {
		printk("get node fail !!!  \n");
		return -ENODEV;
	}
	printk("%d  \n",  of_get_available_child_count(node));
	i=0;
	for_each_child_of_node(node, child){
		enum of_gpio_flags flags;
		if(i == 0)
		{
			ldev->d.pin = of_get_gpio_flags(node->child, 0, &flags);
			pr_info("led_gpio = %u\n", ldev->d.pin);
			i++;
		}
		else
		{
			ldev->c.pin = of_get_gpio_flags(node->child, 0, &flags);
			pr_info("led_gpio = %u\n", ldev->c.pin);
		}
	}
	ldev->led_gpio = of_get_named_gpio_flags(node, "xxx_sda", 0, &flags);
//	ldev->led_gpio = of_get_gpio_flags(node->child, 0, &flags);
	if (!gpio_is_valid(ldev->led_gpio)) {
		pr_err("gpio %d is not valid\n", ldev->led_gpio);
		return -EINVAL;
	}
	ldev->d.pin = ldev->led_gpio;
	ldev->d.active_low = flags & OF_GPIO_ACTIVE_LOW;
	pr_info("led_gpio = %u\n", ldev->d.pin);
	pr_info("active_low = %u\n", ldev->d.active_low);
	m = gpio_request(ldev->d.pin, "data");
	n = gpio_direction_output(ldev->d.pin, 1);
	printk("\nrequst, pin:  %d, %d\n", m, n);

	return 0;
}

static long xxx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	switch(cmd) {	
		case LED_RING:
			printk("ring !!!  \n");
			break;
		case LED_USB:
			printk("usb !!!  \n");
			break;
	}
	return 0;
}

static ssize_t xxx_write(struct file *file,const char __user *buf,size_t count,loff_t *pos)  
{ 
    char lbuf[30];
    if (count >= sizeof(lbuf))
    count = sizeof(lbuf)-1;
    if (copy_from_user(lbuf, buf, count))
	return -EFAULT;
    lbuf[count] = 0;
    return count; 
}

static int xxx_open(struct inode *inode,struct file *file)  
{
	printk(" open!!! \n");
	return 0;
}

static const struct file_operations mis_fops = { 
	.owner	= THIS_MODULE,
        .open       = xxx_open,  
        .write      = xxx_write,
		.unlocked_ioctl = xxx_ioctl,
};

struct miscdevice mis = {
	.minor = 255,
	.name = "xxx",
	.fops = &mis_fops,
};

static int xxx_probe(struct platform_device *pdev)
{
	ldev = kzalloc(sizeof(struct xxx_dev), GFP_KERNEL);
	platform_set_drvdata(pdev, ldev);
	if (xxx_dt_parse(pdev)) {
			pr_info("get dt error!");
			return 0;
	}
	ldev->cdev = &mis;
	printk("\n misc_register is  %d\n", misc_register(ldev->cdev));
	return 0;
}

void obj_test_release(struct kobject *kobject);
ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf);
ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count);
 
struct attribute test_attr = {
	.name = "xxx",
	.mode = S_IRWXUGO,
};

static struct attribute *def_attrs[] = {
	&test_attr,
	NULL,
};

struct sysfs_ops obj_test_sysops =
{
	.show = kobj_test_show,
	.store = kobj_test_store,
};

struct kobj_type ktype = 
{
	.release = obj_test_release,
	.sysfs_ops=&obj_test_sysops,
	.default_attrs=def_attrs,
};

void obj_test_release(struct kobject *kobject)
{
	printk("eric_test: release .\n");
}

//读该文件的时候调用show 函数
ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf)
{
	printk("have show.\n");
	printk("attrname:%s.\n", attr->name);
	sprintf(buf,"%s\n",attr->name);
	return strlen(attr->name)+2;
}

//写该文件的时候调用store 函数
ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count)
{
	printk("store  \n");
	return 0;
}

static const struct of_device_id xxx_dt_match[] = {
	{
		.compatible = "xxx",     //compate  with  dts
	},
	{},
};

static struct platform_driver xxx_driver = {
	.driver = {
		.name = "xxx",
		.owner = THIS_MODULE,
		.of_match_table = xxx_dt_match,
	},
	.probe = xxx_probe,
};

struct kobject kobj;
static int xxx_init(void)
{
	if( platform_driver_register(&xxx_driver) ) {
			pr_err("failed to register driver\n");
		return -ENODEV;
	}
	if( kobject_init_and_add(&kobj,&ktype,NULL,"kobj_text" ){
			pr_err("failed to init_and_add kobj\n");
		return -ENODEV;
	}
    return 0;
}

static void xxx_exit(void)
{
	printk("exit !!! \n");
	kobject_del(&kobj);
}

module_init(xxx_init);
module_exit(xxx_exit);

driver.h

#ifndef _DRIVER_H_
#define _DRIVER_H_

#include <linux/proc_fs.h>
#include <linux/miscdevice.h>

/*ioctl 宏声明*/
#define IOC_MAGIC  'a'
/*定义命令*/
#define LED_RING	_IO(IOC_MAGIC, 0)
#define LED_USB		_IO(IOC_MAGIC, 1)

enum {
	LED_GPIO_STATE_OFF = 0,
	LED_GPIO_STATE_ON,
};

struct dev_gpio {
	const char *name;
	unsigned int pin;
	unsigned int active_low;
	unsigned int state;
};

struct xxx_dev {
	struct dev_gpio c;
	struct dev_gpio d;
	struct miscdevice *cdev;
    int gpio;
    int flag;
};

struct xxx_dev *ldev;

#endif
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 Android 应用程序框架图: ![Android 应用程序框架图](https://developer.android.com/guide/platform/images/android-stack_2x.png) Android 应用程序框架是一个层次结构,其中应用程序的各个组件(如活动、服务、广播接收器和内容提供程序)通过应用程序框架与操作系统进行交互。该框架包括以下主要部分: 1. 应用程序层:该层包含应用程序组件,如活动、服务、广播接收器和内容提供程序。这些组件可以直接与用户进行交互或在后台运行。应用程序层还包括应用程序包管理器,该管理器负责安装、卸载和管理应用程序包。 2. 应用程序框架服务:该服务层提供了许多服务,如通知管理、活动管理、窗口管理和内容提供程序管理。这些服务可以由应用程序组件使用,并且它们通常是在后台运行的。 3. 核心库和运行时:该层包含 Android 运行时环境(ART)和核心 Java 库,这些库为应用程序提供了许多常用的功能,如集合、输入输出、网络和图形。此外,该层还包括 Android 系统库,这些库提供了访问 Android 操作系统的低级功能的接口。 4. 硬件抽象层(HAL):此层提供了硬件驱动程序的抽象接口,使 Android 操作系统可以与各种硬件设备进行通信,如相机、传感器和 Wi-Fi。 5. Linux 内核:该层提供了 Android 操作系统的基础,并负责管理设备驱动程序、内存管理、进程管理和网络协议栈等核心功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值