|
学习Linux的累计时间已经有两年多了,工作关系,学习的过程总是断断续续的,现在整理一下,
下面要分享的是一个简单的linux驱动程序,将内存当作一个虚拟的设备去读写,没有什么实际的
用处,像hello wold!程序一样,我们简单体会一下linux驱动程序的特点,Linux设备驱动程序开
发第三版是一本不错的参考书,讲的比较详细,值得入手,话不多说了,简单讲一下步骤:
1、我电脑上的Linux系统是Ubuntu14.04。
2、 新建一个duxie.c文件作为驱动程序源文件,一个ce.c作为应用层的测试程序,一个Makefile文
件用来编译驱动程序产生*.ko文件。
3、下面贴出代码:
- /**************************************************************
- duxie.c
- It can be compiled for x86 PC #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/kernel.h> /* printk() */
- author:
- date:
- ***************************************************************/
-
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/kernel.h> /* printk() */
-
- #include <linux/errno.h> /* error codes */
- #include <linux/poll.h> /* COPY_TO_USER */
-
-
- #define DEVICE_NAME "rwd"
-
- static int rwdMajor = 0;
- static int MAX_BUF_LEN=1024;
- static char drv_buf[1024];
- static int WRI_LENGTH=0;
-
-
-
- /*************************************************************************************/
- static ssize_t dx_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
- {
- if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;
- copy_from_user(drv_buf , buffer, count);
- WRI_LENGTH = count;
- printk("user write data to driver\n");
- return count;
- }
- /*************************************************************************************/
- static ssize_t dx_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
- {
- if(count > MAX_BUF_LEN)
- count=MAX_BUF_LEN;
- copy_to_user(buffer, drv_buf,count);
- printk("user read data from driver\n");
- return count;
- }
-
- static int dx_open(struct inode *inode, struct file *filp)
- {
- printk("device open sucess!\n");
- return 0;
- }
- /*************************************************************************************/
- static int dx_release(struct inode *inode, struct file *filp)
- {
- printk("device release\n");
- return 0;
- }
-
- /*************************************************************************************/
- static struct file_operations pxa270_fops = {
- owner: THIS_MODULE,
- write: dx_write,
- read: dx_read,
- open: dx_open,
- release:dx_release,
- };
- /*************************************************************************************/
-
- static int __init dx_init(void)
- {
- int ret;
- ret = register_chrdev(0, DEVICE_NAME, &pxa270_fops);
- if (ret < 0) {
- printk(DEVICE_NAME " can't get major number\n");
- return ret;
- }
- rwdMajor=ret;
-
- printk("dx module major number is %d\n", ret);
- return 0;
- }
-
- /*************************************************************************************/
-
- void __exit dx_exit(void)
- {
- unregister_chrdev(rwdMajor, DEVICE_NAME);
- }
- module_exit(dx_exit);
- module_init(dx_init);
- MODULE_LICENSE("GPL");
- Makefile的源代码如下:
- [html] view plain copy
- ifneq ($(KERNELRELEASE),)
- obj-m := duxie.o
- else
- KDIR := /usr/src/linux-headers-3.19.0-31-generic
- all:
- make -C $(KDIR) M=$(PWD) modules
- clean:
- rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*
- endif
- 应用层的测试程序ce.c源代码如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include<string.h>
- void showbuf(char *buf);
- int MAX_LEN=32;
- int main()
- {
- int fd;
- int i;
- char buf1[255];
- char buf2[255];
-
- printf("please input a string:\n");
- scanf("%s",buf1);
- MAX_LEN=strlen(buf1);
- fd=open("/dev/rwd",O_RDWR);
- if(fd < 0){
- printf("####rwd device open fail####\n");
- return (-1);
- }
- printf("write %d bytes data to /dev/rwd \n",MAX_LEN);
- printf("%s\n",buf1);
- write(fd,buf1,MAX_LEN);
- printf("Read %d bytes data from /dev/rwd \n",MAX_LEN);
- read(fd,buf2,MAX_LEN);
- printf("%s\n",buf2);
-
- close(fd);
- return 0;
- }
复制代码 具体实现的功能可以自己看一下。
4、 编译生成duxie.ko文件,用insmod duxie.ko加载驱动程序。
5、查看主设备号,可以用cat /proc/devices | grep rwd 查看主设备号。
6、该驱动程序需要手动注册,可以用mknod /dev/rwd 设备类型 主设备号 次设备号 (例如
mknod /dev/rwd c 248 0)来实现。
7,编译运行ce.c,输入一串字符串,输入什么就输出什么,这样就完成了整个驱动程序的编写、
编译、安装及测试工作。
|
|