gpio子系统在sysfs中构建leds类

1、内核配置

CONFIG_GPIO_SYSFS=y
CONFIG_GPIOLIB=y

(1)CONFIG_GPIO_SYSFS:决定sysfs是否支持gpio子系统,也就是能否在"/sys/class/“目录下看到gpio类;
(2)CONFIG_GPIOLIB:决定是否将”/drivers/gpio/gpiolib.c"编译进内核,如果选择否则在内核和驱动中不能使用gpio子系统相关的函数接口;
总结:CONFIG_GPIOLIB一般都是选择y,因为其他驱动会用到内核gpio子系统;CONFIG_GPIO_SYSFS根据自己的需求来进行选择,如果你不需要通过"/sys/class/gpio"目录下的文件来操作gpio口,就不需要开启;

2、gpio类创建过程

2.1、函数调用关系

gpiolib_sysfs_init()
	class_register(&gpio_class);	//创建gpio类
	gpiochip_export()
		sysfs_create_group()	//设置设备的属性

2.2、gpio类创建

2.2.1、postcore_initcall宏

#define __define_initcall(level,fn,id) \
	static initcall_t __initcall_##fn##id __used \
	__attribute__((__section__(".initcall" level ".init"))) = fn

#define postcore_initcall(fn)		__define_initcall("2",fn,2)

postcore_initcall(gpiolib_sysfs_init);

(1)gpiolib_sysfs_init()函数是创建gpio类的函数,内部调用class_register()函数进行创建;
(2)相当于定义了一个类型为initcall_t的静态局部变量__initcall_gpiolib_sysfs_init2,变量被赋值为gpiolib_sysfs_init函数指针,变量被赋予段属性".initcall2.init"。这样会保证在内核启动过程中自动调用gpiolib_sysfs_init()函数,创建好gpio类。

2.2.2、gpio_class 全局变量

//类属性
static struct class_attribute gpio_class_attrs[] = {
	__ATTR(export, 0200, NULL, export_store),
	__ATTR(unexport, 0200, NULL, unexport_store),
	__ATTR_NULL,
};

//类的信息
static struct class gpio_class = {
	.name =		"gpio",	//类的名字
	.owner =	THIS_MODULE,	//类的所有者

	.class_attrs =	gpio_class_attrs,	//类的属性
};

//调用关系
gpiolib_sysfs_init()
	class_register(&gpio_class);	//创建gpio类

(1)gpio_class变量类型是struct class结构体,所以调用class_register()函数创建类后,会看到/sys/class/gpio目录;
(2)/sys/class/gpio目录下有export和unexport文件,是因为在创建gpio类时,给类属性赋值了(gpio_class_attr[]变量);
(3)export和unexport是用于导出、撤销gpio口的,详情参见博客:《应用层通过/sys/class/gpio文件操作gpio口》

2.3、gpio类的设备属性设置

2.3.1、DEVICE_ATTR宏定义

#define __ATTR(_name,_mode,_show,_store) { \
	.attr = {.name = __stringify(_name), .mode = _mode },	\
	.show	= _show,					\
	.store	= _store,					\
}

#define DEVICE_ATTR(_name, _mode, _show, _store) \
	struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
	

用来定义一个struct device_attribute结构体变量,该类型的变量表示设备的属性,也就是将来在gpio类下的设备都有哪些文件夹;

2.3.3、DEVICE_ATTR宏定义展开分析

static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);


展开:
	struct device_attribute dev_attr_ngpio =  { \
		.attr = {.name = ngpio, .mode = 0444 },	\
		.show	= chip_ngpio_show,					\
		.store	= NULL,					\
	}

定义了struct device_attribute类型的变量dev_attr_ngpio,将来gpio类的设备目录里会看到ngpio文件,权限是0444,读ngpio文件调用函数chip_ngpio_show,因为store是NULL,所以ngpio文件不可写。

2.3.4、gpiochip_attr_group 全局变量

static const struct attribute *gpiochip_attrs[] = {
	&dev_attr_base.attr,
	&dev_attr_label.attr,
	&dev_attr_ngpio.attr,
	NULL,
};

static const struct attribute_group gpiochip_attr_group = {
	.attrs = (struct attribute **) gpiochip_attrs,
};

gpiochip_attr_group变量是个struct attribute 结构体指针数组,每一个成员都是gpio设备的一个属性,sysfs_create_group()函数
会读取gpiochip_attr_group变量去给gpio类的设备创建一系列属性;

3、把gpio端口创建为gpio类下的设备

函数调用关系

//在注册gpio资源时创建
gpiochip_add()
	gpiochip_export
	
//在创建gpio类时创建
gpiolib_sysfs_init()
	class_register(&gpio_class);	//创建gpio类
	gpiochip_export()

(1)在两个地方会为每个gpio端口创建gpio类的设备,一个是注册gpio端口资源时,另一个是在初始化gpio框架的sysfs时;
(2)struct gpio_chip结构体的exported变量是用来标记该端口的状态,gpio端口在初始化后exported变量会被置1,在创建的时候回去检查标志位, 所以不用担心重复创建;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在起飞的蜗牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值