平台总线(二)

任务:

1, 构建bus, device, driver


2, 实现匹配方法


3, 实现driver probe

/* mybus.c */
#include 
#include 
#include 
#include "desc.h"

char bus_version[128] = "bus verison v1";

int mybus_match(struct device *dev, struct device_driver *drv)
{
	/*匹配成功返回1,失败返回0*/
	if (!strncmp(drv->name, dev->kobj.name, strlen(drv->name))) {
		printk("mybus_match ok !\n");
		return 1;
		
	} else {

		//表示匹配不成功
		return 0;	
	}
}

// /sys/bus/mybus/version
//  cat   version -->verison_show()
//  echo  "xxx"  > version  会调用version_store()
ssize_t version_show(struct bus_type *bus, char *buf)
{
	printk("-------^_*  %s-----------\n", __FUNCTION__);
	
	return snprintf(buf, 128,"%s-%d-%c", bus_version, 88, 'A');	
}

ssize_t version_store(struct bus_type *bus, const char *buf, size_t count)
{
	printk("-------^_*  %s-----------\n", __FUNCTION__);
	
	return snprintf(bus_version,128, "%s", buf);	
}

/*
#define BUS_ATTR(_name, _mode, _show, _store)	\
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
*/

//实际是一个结构体---struct bus_attribute  bus_attr_version
BUS_ATTR(version,0666, version_show, version_store);

struct bus_type mybus = {
	.name = "mybus",
	.match = mybus_match
};

static int __init mybus_init(void)
{
	int ret;

	/*1.构建一个总线mybus*/
	ret = bus_register(&mybus);
	if (ret < 0) {
		printk(KERN_ERR "bus_register fail\n");

		return ret;
	}

	// 可以在/sys/bus/mybus/创建文件 version
	ret = bus_create_file(&mybus, &bus_attr_version);
	if (ret < 0) {
		printk(KERN_ERR "bus_create_file fail\n");
		bus_unregister(&mybus);
		
		return ret;
	}
	printk("------*_^ %s--------\n",__FUNCTION__);

	return 0;
}

static void __exit mybus_exit(void)
{
	/*注销总线mybus*/
	bus_unregister(&mybus);
 
	printk(KERN_INFO "------*_^ %s--------\n",__FUNCTION__);
}

EXPORT_SYMBOL(mybus);

module_init(mybus_init);
module_exit(mybus_exit);

MODULE_LICENSE("GPL");

/* mydevice.c */
#include 
#include 
#include 
#include "desc.h"

extern struct bus_type mybus;

void  mydevice_release(struct device *dev)
{
	printk(KERN_INFO "------*_^ %s--------\n",__FUNCTION__);	
}

/*表示一个特定的设备信息*/
struct dev_desc info = {
	.name = "simple device",
	.irqno = 1212,
	.addr = 0x12121212,
	//...FIXME...	
};

struct device mydevice = {
	.init_name = "match",  	/* initial name of the device 跟device的符号相同才能通过bus匹配成功*/
	.bus = &mybus,				/* type of bus device is on */
	.release = mydevice_release,
	.platform_data = &info		/* Platform specific data, device*/
};

static int __init mydevice_init(void)
{
	int ret;

	/*1.构建一个device 并且注册到总线*/
	ret = device_register(&mydevice);
	if (ret < 0) {
		printk(KERN_ERR "device_register fail\n");
		return ret;
	}

	printk(KERN_INFO "------*_^%s--------\n",__FUNCTION__);

	return 0;
}

static void __exit mydevice_exit(void)
{
	/*注销device 并且注册到总线*/
	device_unregister(&mydevice);

	printk(KERN_INFO "------*_^%s--------\n",__FUNCTION__);
}


module_init(mydevice_init);
module_exit(mydevice_exit);

MODULE_LICENSE("GPL");


/* mydriver.c */
#include 
#include 
#include 
#include "desc.h"

extern struct bus_type mybus;

int mydrv_probe(struct device *dev)
{
	printk("------*_^%s--------\n",__FUNCTION__);

	/*获取到device中信息*/
	struct dev_desc * p = (struct dev_desc *)dev->platform_data;

	printk("name = %s\n", p->name);
	printk("irq = %d\n", p->irqno);
	printk("addr = 0x%x\n", p->addr);
	
	return 0;
}
int mydrv_remove(struct device *dev)
{
	printk("------*_^%s--------\n",__FUNCTION__);

	return 0;
}


struct device_driver mydriver = {
	.name = "match",	/*跟device的符号相同才能通过bus匹配成功*/
	.bus = &mybus,
	.probe = mydrv_probe,
	.remove = mydrv_remove
};

static int __init mydriver_init(void)
{
	int ret;

	/*1.构建一个driver并且注册到总线*/
	ret = driver_register(&mydriver);
	if (ret < 0) {
		printk(KERN_ERR "driver_register fail \n");
		return ret;
	}

	printk("------*_^%s--------\n",__FUNCTION__);

	return 0;
}

static void __exit mydriver_exit(void)
{
	/*注销driver*/
	driver_unregister(&mydriver);

	printk("------*_^%s--------\n",__FUNCTION__);
}

module_init(mydriver_init);
module_exit(mydriver_exit);

MODULE_LICENSE("GPL");

/* desc.h */
#ifndef __DESC_H__
#define __DESC_H__


//设计一个对象
struct dev_desc{
	char *name;
	int irqno;
	unsigned long addr;
};

#endif

# Makefile

ROOTFS_DIR = /opt/filesystem
MODULE_NAME = mybus
MODULE_NAME2 = mydriver
MODULE_NAME3 = mydevice
ifeq ($(KERNELRELEASE), )
KERNEL_DIR = /home/linux-3.0.8
CUR_DIR = $(shell pwd)
all :	
	make -C $(KERNEL_DIR) M=$(CUR_DIR) modules

clean :	
	make -C $(KERNEL_DIR) M=$(CUR_DIR) clean

install:	
	cp -raf *.ko   $(ROOTFS_DIR)/drv_module
else

obj-m = $(MODULE_NAME).o
obj-m += $(MODULE_NAME2).o
obj-m += $(MODULE_NAME3).o

endif



你可能感兴趣的:(Linux高级驱动)