从头开始编写Linux字符设备驱动程序(1)(基于友好的arm tiny4412开发板)

从这篇博客文章开始,我将开始教你如何编写Linux设备驱动程序。

这是开始,如何编写第一个字符设备驱动程序。

首先,您需要编写最简单的字符设备驱动程序吗?还是我们需要知道什么? 1.每个字符设备必须至少具有一个设备号。

2.设备号=主设备号+次设备号。

3.相同类型设备的主要设备编号通常是相同的,但不是绝对的。

因此,要编写一个简单的字符设备驱动程序,我们需要在内核中包含这些头文件,因为我们需要调用一个基本宏和一些基本函数供我们使用。

#include& lt; linux / cdev.h& gt; #include& lt; linux / kdev_t.h& gt; #include& lt; linux / fs.h& gt;打开linux内核源代码,输入include / linux /,找到cdev.h,打开它,我们将看到以下结构:struct cdev {//与设备模型相关的struct kobject kobj; //哪个模块属于--->此模块结构模块* owner; //使用file_operations在用户模式下进行操作-& gt;有打开,读取,写入和其他方法const struct file_operations * ops; //链表,将设备插入链表到struct list_head list; //通过设备号匹配相应的驱动程序dev_t dev; //注册字符设备的Unsigned int计数; };您还将看到以下函数:void cdev_init(struct cdev *,const struct file_operations *); struct cdev * cdev_alloc(void);无效的cdev_put(struct cdev * p); int cdev_add(struct cdev *,dev_t,unsigned);复制代码无效的cdev_del(struct cdev *);无效的cd_forget(struct inode *);在这里,我们需要上面的结构,以及三个函数cdev_init,cdev_add,cdev_del和其余函数(目前不需要)。

以上功能暂时将不在本节中使用,而将在下一节中使用。

然后查看#include& lt; linux / kdev_t.h& gt;这个头文件,它具有我们需要的:#define MINORBITS 20 #define MINORMASK((1U& lt;& lt MINORBITS)-1)//从设备号中取出主要设备号#define MAJOR(dev )((unsigned int)((dev)& gt; MINORBITS))//从设备号中删除次设备号#define MINOR(dev)((unsigned int)((dev)& amp; ; MINORMASK))//创建设备编号#define MKDEV(ma,mi)((((ma)& lt;< MINORBITS)|(mi))我们接下来写的字符设备需要创建设备编号,因此我们需要MKDEV宏,第一个参数代表主要设备号,第二个参数代表次要设备号。

我们知道如何创建设备号,然后创建设备号,但是该设备尚未注册。

此时,我们需要#include& lt; linux / fs.h& gt;这个头文件中的一个函数:extern int register_chrdev_region(dev_t,unsigned,const char *);因为有注册,所以当然有释放,所以我们还需要:extern void unregister_chrdev_region(dev_t,unsigned);好了,有了这些基础知识,我们就可以开始第一个字符设备驱动程序的准备工作了。

要编写此简单字符设备,需要执行以下步骤:1.创建设备号2.注册设备号3.如何驱动模块退出,我们需要取消设备的操作。

好的,让我们开始编写代码:#include& lt; linux / init.h& gt; #include& lt; linux / module.h& gt; #include& lt; linux / sched.h& gt; #include& lt; linux / kernel.h& gt; #include& lt; linux / cdev.h& gt; #include& lt; linux / kdev_t.h& gt; #include& lt; linux / fs.h& gt; //定义一个结构变量以表示设备编号---& gt; cdev.h---& gt; dev_t dev_t dev_no; static int __init& nbsp; cdev_test_init(void){int ret; printk(“ CDEV的HELLO KERNEL! ”); // 1,创建一个设备号->第一个是主要设备号,第二个是次要设备号。

//主要设备号可以通过cat / proc / devices查看。

如果设备号已被占用,则需要使用未使用的设备号dev_no& nbsp; = MKDEV(222,2); // 2,已注册的设备号// count指示要分配多少个设备号ret = register_chrdev_region(dev_no,1,“ my_dev”); if(ret& lt; 0){//如果注册失败,则跳转到相应的位置。

goto register_error;}返回0; register_error:return ret;} static int __exit cdev_test_exit(void){//注销驱动程序-& gt;最后写1表示从dev_no unregister_chrdev_region(dev_no,1)开始的连续设备; return 0;} module_init(cdev_test_init); module_exit(cdev_test_exit); MODULE_LICENSE(“ GPL”);如前所述,编写一个Kconfig和Makefile Kconfig菜单“ 4412_CDEV_DRV”。

& nbsp; & nbsp; & nbsp;配置CDEV_TEST& nbsp; & nbsp; & nbsp; & nbsp; & nbsp;布尔“ cdev_test” & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;默认值n& nbsp; & nbsp; help& nbsp;如果您选择,则表示

联系方式

ARF系列片式电阻器设计为低内部电抗。薄膜技术应用于电阻器是适当的,以减少寄生电感和电容。 低内部电抗允许这些器件在高频下保持非常好的电阻器行为。

查看详情

在线咨询