最近在写按键中断搭配内核定时器给按键消抖时出现了段错误,然后经过不停的打印异常调试终于找到了问题所在,然后也总结了一些需要注意的细节问题。
细节1:平常定义变量的时候有时定义成指针有时又定义成普通变量,在传参的时候参数类型容易写错。
例如如下函数原型:第一个参数是结构体指针
static inline int of_get_named_gpio(struct device_node *np,const char *propname, int index)
但是我刚开始传参数的时候却传了个二级指针,&key.node
key.key_gpio = of_get_named_gpio(&key.node,"key-gpio",0);
所以出现了如下警告、警告、警告。为什么说三遍呢?因为警告很关键,我在写的时候就是因为忽略了警告问题从而出现了更多的问题,甚至驱动都加载不了。所以平常在写去驱动的时候编译完代码要记得关注一下warning。
细节2:有如下两个函数,功能都是查找设备树节点的,第一个是通过路径查找,第二个是通过节点名字查找。
struct device_node *of_find_node_by_path(const char *path)
struct device_node *of_find_node_by_name(struct device_node *from,const char *name)
但是却写成了这样:
参数写错就会报如下警告(很无语,明明是错的却不报error)
因为平时都有做笔记的习惯,会把需要用到的接口函数都记录下来以便下次使用,在复制粘贴的时候可能会复制错,所以说平时写的时候一定要注意这个问题,需要保证接口函数的正确性并且要注意参数。
这次段错误Segmentation fault是由什么原因引起的我就不做解释了,直接说结论:
可以看下图,我们在驱动入口函数这边是需要先创建一个设备的类然后再通过这个类创建一个设备device,可以知道这个device是依赖于这个类class的。
我们在驱动出口函数里卸载驱动的时候必须要满足有依赖的先卸载/删除,
例如你如果先把这里的类class删除掉,然后再卸载device的话,device在卸载的时候也是要去访问这个class的,但是class所占用的内存地址又被释放掉了,你又去访问这个地址那不就相当于访问了一块空指针了嘛,那肯定会出现内存混乱也就出现段错误Segmentation fault了。
入门linux驱动的萌新一枚,欢迎大佬们指正。