- #include <linux/module.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/fs.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <asm/uaccess.h>
- #define HELLO_MAJOR 250
- #define HELLO_MINOR 0
- #define NUMBER_OF_DEVICES 2
- struct class *hello_class;
- static struct cdev cdev;
- dev_t devno;
- static ssize_t hello_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
- {
- char *str = "hello world";
- copy_to_user(buf,str,strlen(str));
- *(buf + strlen(str)) = '\n';
- return count;
- }
- static ssize_t hello_open(struct inode *inode,struct file *file)
- {
- return 0;
- }
- static const struct file_operations hello_fops = {
- .open = hello_open,
- .read = hello_read,
- .owner = THIS_MODULE,
- };
- static int __init hello_init(void)
- {
- int ret;
- devno = MKDEV(HELLO_MAJOR,HELLO_MINOR);
- if(HELLO_MAJOR){
- ret = register_chrdev_region(devno,NUMBER_OF_DEVICES,"chrdev");
- }else{
- ret = alloc_chrdev_region(&devno, 0, NUMBER_OF_DEVICES, "chrdev");
- }
- if(ret < 0){
- printk("%s register chrdev error\n",__func__);
- return ret;
- }
- hello_class = class_create(THIS_MODULE,"hello_char_calss");
- if(IS_ERR(hello_class)){
- printk("%s create class error\n",__func__);
- return -1;
- }
- device_create(hello_class, NULL, devno, NULL, "chrdev");
- cdev_init(&cdev, &hello_fops);
- cdev.owner = THIS_MODULE;
- cdev_add(&cdev, devno, NUMBER_OF_DEVICES);
- return 0;
- }
- static void __exit hello_exit(void)
- {
- printk("%s",__func__);
- cdev_del(&cdev);
- device_destroy(hello_class,devno);
- class_destroy(hello_class);
- unregister_chrdev_region(devno,NUMBER_OF_DEVICES);
- }
- module_init(hello_init);
- module_exit(hello_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("oracleloyal@gmail.com");
- Makefile 内容
- 1 ifeq ($(KERNELRELEASE),)
2 #KERNEL_DIR:=/home/archermind/zhaoxi/bsw_ww02_2016/kernel/cht
3 KERNEL_DIR:=/usr/src/linux-headers-3.13.0-32-generic
4 PWD:=$(shell pwd)
5 modules:
6 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
7 modules_install:
8 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
9 clean:
10 rm -rf .*.cmd *.ko *.o modules.order Module.symvers *mod.c
11 .PHONY: modules modules_install clean
12 else
13 modules-objs := my.o
14 obj-m := my.o
15 endif编译模块安装之后会在/sys/class/看到hello_char_class 以及目录内的chrdev,同时也会在/dev下看到udev为我们建立的节点chrdev.
测试程序
- #include <stdio.h>
- #include <fcntl.h>
- int main(void)
- {
- int fd;
- int i;
- char buf[50];
- fd = open("/dev/chrdev",O_RDWR);
- if(fd < 0){
- printf("can't open dev\n");
- return -1;
- }
- read(fd,buf,11);
- printf("%s",buf);
- return 0;
- }
- 测试程序执行后会输出hello world.,
相关文章
- Linux 关机 休眠, 关闭移动设备自动挂载 命令
- linux磁盘分区,创建文件系统,挂载,卸载,自动挂载
- Linux:--bash 无法为立即文档创建临时空间:设备上没有空间
- 迅为4418/6818开发板实现最小Linux系统自动挂载SD/TF卡/U盘等存储设备
- Linux Kernel C语言编程范式 内部DSL是嵌入到开发语言内部,与开发语言混合使用的DSL,它可以是一个接口,如printf,也可以是一个宏,如下示例。UNUSUAL_DEV呈现了2种信息,一种是设备id_table信息,用于驱动匹配,一种是unusual_dev_list,用于标示非标准设备。具体设计和实现细节可以参考《Linux设备驱动框架设计》一文中的“USB块设备驱动框架设计”小节,不再赘述。
- Linux网络之设备接口层:发送数据包流程dev_queue_xmit
- Linux ALSA声卡驱动之三:PCM设备的创建
- 在linux上创建slave节点
- linux 设备树及节点引用【转】
- Android udev /dev 设备节点权限