平台总线(二)

来源:互联网 发布:微信公众号源码下载 编辑:程序博客网 时间:2021/05/13 03:51
任务:

1, 构建bus, device, driver


2, 实现匹配方法


3, 实现driver probe

/* mybus.c */#include <linux/init.h>#include <linux/module.h>#include <linux/device.h>#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_versionBUS_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/创建文件 versionret = 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");<span style="color:#cc0000;"></span>

/* mydevice.c */#include <linux/init.h>#include <linux/module.h>#include <linux/device.h>#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 <linux/init.h>#include <linux/module.h>#include <linux/device.h>#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

# MakefileROOTFS_DIR = /opt/filesystemMODULE_NAME = mybusMODULE_NAME2 = mydriverMODULE_NAME3 = mydeviceifeq ($(KERNELRELEASE), )KERNEL_DIR = /home/linux-3.0.8CUR_DIR = $(shell pwd)all :make -C $(KERNEL_DIR) M=$(CUR_DIR) modulesclean :make -C $(KERNEL_DIR) M=$(CUR_DIR) cleaninstall:cp -raf *.ko   $(ROOTFS_DIR)/drv_moduleelseobj-m = $(MODULE_NAME).oobj-m += $(MODULE_NAME2).oobj-m += $(MODULE_NAME3).oendif



0 0
原创粉丝点击