linux 查看 字符设备驱动,Linux下字符设备驱动

【linux操作系统驱动分类】

字符设备: 串口,led,按键,一次只读取一个字节数据

块设备: 一次读取多个字节(512字节), 硬盘,内存

网络设备: 一次读取多字节数据

本文引用地址:http://emb.hqyj.com/Column/7464.html

ls -l /dev 查看文件属性

c开头的叫字符设备文件(char), 串口,Led,I2C

b开头的叫块设备文件 (block)

sudo mknod /dev/led c 500 0 //生成一个设备,跟char-read.ko关联

制作一个字符设备

【设备号】

设备和驱动是怎么关联到一起的?

是通过500 0 关联到一起的

500 主设备号(linux系统将一些常用的硬件设备进行了编号,比如串口主设备号4 ...)

0 次设备号(第一个串口 次设备号0, 1 2.....)

设备号能唯一表示一个设备,所以不可以重复

fs4412_led_drv.c 驱动文件

【如何实现一个字符设备驱动】

1 因为字符设备驱动属于一个内核模块,所以也使用内核模块模板

2 字符设备驱动使用cdev架构

【cdev中重要的宏】

设备编号:

MKDEV(major, minor);

//功能:构造设备编号

major 主设备号, minor 此设备号

执行完此函数,返回一个32位的设备号,其中前12位是主设备号,后20位是次设备号

500 1

00011111 0100 000000000000000000001

#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

MAJOR(dev_t);

//功能:取主设备号

从32位的设备号中取出主设备号

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))

MINOR(dev_t); //取次设备号

从32位的设备号中取出次设备号

申请设备编号:

int register_chrdev_region(dev_t from, unsigned count, const char *name)

功能:将模块与主次设备号关联

参数:

from,起始设备编号

count,次设备号个数

name,设备名

返回值:

成功返回0,失败返回错误码。

释放设备编号:

void unregister_chrdev_region(dev_t from, unsigned count)

功能:取消模块与主次设备号关联

参数:

from,起始设备编号

count,次设备号个数

驱动模块和250 0 设备关联

int hello_major = 250;

int hello_minor = 0;

int number_of_devices = 1;

static int __init hello_2_init (void)

{

int result;

dev_t dev = 0;

dev = MKDEV (hello_major, hello_minor);

result = register_chrdev_region (dev, number_of_devices, "hello");

if (result<0) {

printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);

return result;

}

printk (KERN_INFO "Registered character driver\n");

return 0;

}

static void __exit hello_2_exit (void)

{

dev_t devno = MKDEV (hello_major, hello_minor);

unregister_chrdev_region (devno, number_of_devices);

printk (KERN_INFO "Char driver cleaned up\n");

}

module_init (hello_2_init);

module_exit (hello_2_exit);

sudo insmod hello.ko

cat /proc/devices | grep hello //linux会将注册好的设备添加进/proc/devices文件中

sudo rmmod hello

struct cdev{

const struct file_operations *ops; //字符设备驱动结构体

dev_t dev; //主次设备号

unsigned int count; //设备数量

};

初始化字符设备:

void cdev_init(struct cdev *cdev, const struct file_operations *fops);

添加设备:

int cdev_add(struct cdev *p, dev_t dev, unsigned count)

删除设备:

void cdev_del(struct cdev *p)

下面的代码是完成一个简单的字符设备驱动程序,此程序没有实际功能,知识完成了open, close函数

//定义主设备号,次设备号

#include

#include

#include

#include

#include

#include

int hello_major = 250; //主设备号

int hello_minor = 0; //次设备号

struct cdev cdev; //c -> char dev->device 字符设备的主要结构体

static int hello_open (struct inode *inode, struct file *file) //应用成执行open函数会调用到它

{

printk ("11111111111111111111111111 device opened\n");

return 0;

}

struct file_operations hello_fops = { //将hello_open hello_close 与 open , close 关联

.owner = THIS_MODULE,

.open = hello_open,

};

static void char_reg_setup_cdev (void) //完成cdev结构体的初始化

{

dev_t devno;

devno = MKDEV (hello_major, hello_minor); //MKDEV宏能将主次设备号放在一个32位的变量中,变成一个编号

cdev_init (&cdev, &hello_fops); //将hello_fops 放到cdev结构体中

cdev.owner = THIS_MODULE;

cdev_add (&cdev, devno , 1); //将设备号再放到cdev结构体中, 1代表 子设备数量1个

}

static int __init hello_init (void) //注册模块时要执行此函数

{

int result;

dev_t devno;

devno = MKDEV (hello_major, hello_minor);

result = register_chrdev_region (devno, 1, "hello");

char_reg_setup_cdev ();

printk ("char device registered\n");

return 0;

}

static void __exit hello_exit (void)

{

dev_t devno = MKDEV (hello_major, hello_minor);

cdev_del (&cdev); //删除cdev

unregister_chrdev_region (devno, 1); //删除250, 0号设备

}

module_init (hello_init);

module_exit (hello_exit);

完成一个应用程序,测试驱动

#include

#include

#include

#include

#include

#include

#include

int main()

{

int fd;

fd = open("/dev/hello", O_RDWR);

if(fd > 0)

{

printf("file open success\n");

}

else

{

printf("file open failed\n");

}

}

制作字符设备的过程

1 制作驱动模块

1)将驱动代码 写到hello.c中

2)make (会生成hello.ko文件)

2 sudo insmod hello.ko

3 sudo mknod /dev/hello c 250 0 //生成一个设备,跟char-read.ko关联

4 gcc -o test test.c //将应用层的test.c 编译生成test可执行文件

5 sudo ./test

6 dmesg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值