致驱动工程师的一封信
作者:smcdef 发布于:2018-4-14 21:00 分类:统一设备模型
注:部分代码分析举例基于linux-4.15。
device { rst-gpio = <&gpioc_ctl 10 OF_GPIO_ACTIVE_LOW>; irq-gpio = <&gpioc_ctl 11 0>; interrupts-extended = <&vic 11 IRQF_TRIGGER_RISING>; };
int device_probe(struct platform_device *pdev) { rst_gpio = of_get_named_gpio_flags(np, "rst-gpio", 0, &flags); if (flags & OF_GPIO_ACTIVE_LOW) { struct gpio_desc *desc; desc = gpio_to_desc(rst_gpio); set_bit(FLAG_ACTIVE_LOW, &desc->flags); } irq = of_irq_get(np, 0); trigger_type = irq_get_trigger_type(irq); request_threaded_irq(irq, NULL, irq_handler, trigger_type, "irq", NULL); }
驱动按照以上代码实现的话,如果修改中断触发类型或者电平有效状态只需要修改dts即可。例如不同的IC复位电平是不一样的,有的IC是高电平复位,有的IC却是低电平复位。其实这就是一个电平有效状态的例子。
static inline int gpio_export(unsigned gpio, bool direction_may_change); static inline int gpio_export_link(struct device *dev, const char *name, unsigned gpio);
cat /proc/interrupts
输出信息不想多余的介绍。看代码去。根据输出的irq num,假设是irq_num。请进入以下目录。看看下面都有什么文件。摸索这些文件可以为你调试带来哪些方便。
cd /proc/irq/irq_num
dts和sysfs有什么关联
曾经写过一篇dts解析的文章http://www.wowotech.net/device_model/dt-code-file-struct-parse.html。最后一节其实说了一个很有意思的东西。但是仅仅是寥寥结尾。并没有展开。因为他不关乎我写的文章的的主题。但是,他却和调试息息相关。
cd /sys/firmware/devicetree/base
该目录的信息就是整个dts。将整个dts的节点以及属性全部展现在sysfs中。他对我们的调试有什么用呢?Let me tell you。如果你的项目非常的复杂,例如一套代码兼容多种硬件配置。这些硬件配置的差异信息主要是依靠dts进行区分。当编译kernel的时候,你发现你很难确定就是你用的是哪个dts。可能你就会凭借自己多年的工作经验去猜测。是的,你的经验很厉害。但是,如何确定你的dts信息是否添加到kernel使用的dts呢?我觉得你应该got it。就到这个目录去查找是否包含你添加的ndoe和property。dts中有status属性可以设置某个devicec是否使能。当你发现你的driver的probe没有执行的时候,我觉得你就需要确定一遍status是不是“ok”、“okay”或者没有这个属性。
远不止我所说的这个功能,还可以判断当前的硬件是匹配哪个dts文件。你还不去探索一波源码的设计与实现吗?节点为什么出现在某些目录?为什么有些节点的属性cat却是乱码?就是乱码,你没看错。至于为什么。点到为止。
1. 通过sysfs确定对应的device是否注册成功。
2. 通过sysfs确定对应的driver是否注册成功。
3. 通过sysfs中dts的展开信息得到compatible属性的值,然后和driver的compatible进行对比。

评论:
2018-04-22 17:36
int gpiod_get_value(const struct gpio_desc *desc)
{
int value;
VALIDATE_DESC(desc);
/* Should be using gpio_get_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
value = gpiod_get_raw_value_commit(desc);
if (value < 0)
return value;
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
value = !value;
return value;
}
看看这个if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))value = !value;你的疑问可以通过全局搜索FLAG_ACTIVE_LOW,或者你的driver调用的接口追踪函数是否用到该flag
2018-04-17 20:02
功能
最新评论
文章分类
随机文章
文章存档
- 2024年2月(1)
- 2023年5月(1)
- 2022年10月(1)
- 2022年8月(1)
- 2022年6月(1)
- 2022年5月(1)
- 2022年4月(2)
- 2022年2月(2)
- 2021年12月(1)
- 2021年11月(5)
- 2021年7月(1)
- 2021年6月(1)
- 2021年5月(3)
- 2020年3月(3)
- 2020年2月(2)
- 2020年1月(3)
- 2019年12月(3)
- 2019年5月(4)
- 2019年3月(1)
- 2019年1月(3)
- 2018年12月(2)
- 2018年11月(1)
- 2018年10月(2)
- 2018年8月(1)
- 2018年6月(1)
- 2018年5月(1)
- 2018年4月(7)
- 2018年2月(4)
- 2018年1月(5)
- 2017年12月(2)
- 2017年11月(2)
- 2017年10月(1)
- 2017年9月(5)
- 2017年8月(4)
- 2017年7月(4)
- 2017年6月(3)
- 2017年5月(3)
- 2017年4月(1)
- 2017年3月(8)
- 2017年2月(6)
- 2017年1月(5)
- 2016年12月(6)
- 2016年11月(11)
- 2016年10月(9)
- 2016年9月(6)
- 2016年8月(9)
- 2016年7月(5)
- 2016年6月(8)
- 2016年5月(8)
- 2016年4月(7)
- 2016年3月(5)
- 2016年2月(5)
- 2016年1月(6)
- 2015年12月(6)
- 2015年11月(9)
- 2015年10月(9)
- 2015年9月(4)
- 2015年8月(3)
- 2015年7月(7)
- 2015年6月(3)
- 2015年5月(6)
- 2015年4月(9)
- 2015年3月(9)
- 2015年2月(6)
- 2015年1月(6)
- 2014年12月(17)
- 2014年11月(8)
- 2014年10月(9)
- 2014年9月(7)
- 2014年8月(12)
- 2014年7月(6)
- 2014年6月(6)
- 2014年5月(9)
- 2014年4月(9)
- 2014年3月(7)
- 2014年2月(3)
- 2014年1月(4)
2023-10-15 20:26