linux--bus总线模块驱动中级---实现总线模块和设备模块

根据以上两篇博客的介绍,总线模块和 设备模块的程序设计思路完全相同

步骤:

1、首先在模块初始化函数中 注册设备(总线设备、实际的设备 device)

2、创建属性文件 属性文件就是对设备的操作(包括读取 写入操作)--注意在创建的时候这两个都会使用到一个类似的宏来定义文件属性结构体

使用的宏是: BUS_ATTR(name,mod,show,store);//注意参数的意义 第一个为名字 第二个为模式 第三                                         个为读取函数,第四个为 写入函数

device使用的宏:DEVICE_ATTR(name.mod.show,store);//参数意义相同

3、实现属性文件中的读写函数就好了

总线模块程序代码如下::代码中有标注 注意去看内核源代码:

#include<linux/init.h>
#include<linux/module.h>
#include<linux/device.h>
#include<linux/kernel.h>
#include<linux/string.h>

MODULE_AUTHOR("kong-hua-sheng");
MODULE_LICENSE("GPL");
static char* Version="$Revision:2.0 $";

static void my_bus_release(struct device* dev)
{
printk("call my_bus_release!!\n");
}
struct device my_bus_dev =
{
.init_name = "my_bus_dev",
.release = my_bus_release,
};
struct bus_type my_bus_type =
{
.name = "my_bus",
};
EXPORT_SYMBOL(my_bus_type);//将这两个结构体导出
EXPORT_SYMBOL(my_bus_dev);


static ssize_t show_bus_version(struct bus_type *bus,char *buf)
{
return snprintf(buf,PAGE_SIZE,"%s\n",Version);
}
static BUS_ATTR(version,S_IRUGO,show_bus_version,NULL);

static int __init my_bus_init(void)
{
int ret;
printk("call bus_init()!!\n");
/* 注册总线*/
ret = bus_register(&my_bus_type);
if(ret)
return ret;
/**创建属性文件*/
if(bus_create_file(&my_bus_type,&bus_attr_version))
printk("Fail to create version attribute\n");

/*注册总线设备*/
ret = device_register(&my_bus_dev);
if(ret)
printk("Fial Rgister device:my_bus!!\n");
return ret;


}

static int __exit my_bus_exit(void)
{
printk("call bus_exit()!!\n");
device_unregister(&my_bus_dev);
bus_unregister(&my_bus_type);
}
module_init(my_bus_init);
module_exit(my_bus_exit);

下面是device模块的函数

#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/string.h>
#include<linux/device.h>
/*device驱动的书写步骤和bus的步骤几乎相同*/
MODULE_AUTHOR("kong-hua-sheng");
MODULE_LICENSE("GPL");
extern struct device my_bus_dev;
extern struct bus_type my_bus_type;

static void my_dev_release(struct device* dev)
{
printk("call my_dev_release!!\n");
}

struct device my_dev =
{
.init_name = "my_dev",//设备的名称
.bus = &my_bus_type,//决定设备属于哪条总线
.parent = &my_bus_dev,//父类设备???
.release = my_dev_release,
};
static ssize_t mydev_show(struct device* dev,struct device_attribute *attr,char *buf)//读取的时候调用的函数
{
return sprintf(buf,"%s\n","This is my device!!!\n");
}
static DEVICE_ATTR(dev,S_IRUGO,mydev_show,NULL);//最后一个参数应该是store函数 写入是调用的函数,,注意参数的意义以及他们什么时候调用

static int __init my_dev_init(void)
{
int ret;
//首先要注册 设备
ret = device_register(&my_dev);
if(ret)
return ret;
//创建属性文件

ret = device_create_file(&my_dev,&dev_attr_dev);//注意第二个参数的 创建 是用宏来创建的
return ret;
}
static int __exit my_dev_exit(void)
{
printk("device exit()!!\n");
device_unregister(&my_dev);
return 0;
}
module_init(my_dev_init);
module_exit(my_dev_exit);


下面是makefile

ifneq ($(KERNELRELEASE),)
obj-m := bus.o device.o
else
KDIR := /khs/linux-2.6.38
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*
endif


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值