平台总线(二)
来源:互联网 发布:微信公众号源码下载 编辑:程序博客网 时间:2024/05/02 05:54
任务:
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
- 平台总线(二)
- 平台总线(一)
- 平台总线(三)
- PCI总线(二)
- PCI总线(二)
- iic总线(二)
- SPI总线(二)
- CA总线(二)
- 平台总线
- 平台总线
- 平台总线
- can总线学习(二)
- CAN总线基础知识(二)
- CAN总线基础知识(二)
- PCI总线进阶(二)
- CAN总线基础知识(二)
- CAN总线基础知识(二)
- CAN总线基础知识(二)
- 如何成为一名黑客(网络安全从业者)——网络攻击技术篇(3/8 网络协议欺骗)
- some math problems solved by Recursion & divide and conquer
- 【一步步学OpenGL 8】 -《缩放变换》
- 【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)
- 【POJ2385】Apple Catching(简单DP)
- 平台总线(二)
- Android面试基础
- 如何理解递归
- android中activuty的简单总结
- Linux - C预习内容(七)
- java中常用的加密方式
- 学习python写网络爬虫(一)
- 从零开始学习Nodejs(一)
- 【Java TCP/IP Socket】Java NIO Socket VS 标准IO Socket