linux字符驱动之初见
来源:互联网 发布:录制声音的软件 编辑:程序博客网 时间:2024/05/22 01:34
转自:http://blog.csdn.net/lwj103862095/article/details/17468587
学习驱动也有长达一年多的时间了,受益最深的就是看韦东山老师的视频,如今已经几乎将二期三期的视频全部看完,甚至已经将二期视频看过好几遍,为了再次加深印象,我将韦老师的源码自己全部编写一遍。将所有遇到的问题,记录在此。觉得看了韦老师的视频,再看其他视频都是弱爆了。由于是文章记录,不可能写的非常详细,只摘录关键点,想具体详细的深入,还请去看韦老大的视频吧。
这篇文章是主要是讲解字符驱动的框架,并没有涉及高级字符驱动。
一、字符驱动框架
------------------------------------------------------------------------
APP: open read write
------------------------------------------------------------------------
C 库
------------------------------------------------------------------------
system_open system_read system_write
------------------------------------------------------------------------
KERNEL:
led_open led_read led_wirte
------------------------------------------------------------------------
问:应用程序open如何找到驱动程序的open函数
答:应用程序的open通过C库的open函数,通过系统调用的system_open函数,进而通过swi val指令,进入内核,通过一定的办法来找到驱动程序的open函数。
问:通过什么样的方法来找到驱动程序的open函数
答:通过一个注册函数+设备节点
注册函数如下(旧的注册函数,新的以后再说):
register_chrdev(unsigned int major, const char * name, const struct file_operations * fops)
参数1:主设备号(重要)
参数2:名字(不重要)
参数3:file_operations结构体(重要)
设备节点:
可以手工创建也可以自动创建,这里暂且只说手工创建
mknod /dev/xxx c 252 0
具体什么含义,我就不多说了,看视频吧,很简单。
问:应用程序一般是由main函数开始执行,那么驱动程序一般是先执行什么?
答:通过一个宏,指定驱动程序的入口函数,当装载驱动时就会执行入口函数。
例如:module_init(first_drv_init); //用于修饰入口函数
自然地,驱动程序的出口函数,则是在卸载驱动时就会执行出口函数。
例如:module_exit(first_drv_exit); //用于修饰出口函数
驱动源程序如下:
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <asm/uaccess.h>
- #include <asm/irq.h>
- #include <asm/io.h>
- #include <linux/module.h>
- int major;
- static int first_drv_open(struct inode * inode, struct file * filp)
- {
- printk("first_drv_open\n");
- return 0;
- }
- static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
- {
- printk("first_drv_write\n");
- return 0;
- }
- /* File operations struct for character device */
- static const struct file_operations first_drv_fops = {
- .owner = THIS_MODULE,
- .open = first_drv_open,
- .write = first_drv_write,
- };
- /* 驱动入口函数 */
- static int first_drv_init(void)
- {
- /* 主设备号设置为0表示由系统自动分配主设备号 */
- major = register_chrdev(0, "first_drv", &first_drv_fops);
- return 0;
- }
- /* 驱动出口函数 */
- static void first_drv_exit(void)
- {
- unregister_chrdev(major, "first_drv");
- }
- module_init(first_drv_init); //用于修饰入口函数
- module_exit(first_drv_exit); //用于修饰出口函数
- MODULE_AUTHOR("LWJ");
- MODULE_DESCRIPTION("Just for Demon");
- MODULE_LICENSE("GPL"); //遵循GPL协议
Makefile源码如下:
- ifneq ($(KERNELRELEASE),)
- obj-m := first_drv.o
- else
- KDIR := /home/opt/EmbedSky/linux-2.6.30.4
- all:
- make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
- clean:
- rm -f *.ko *.o *.mod.o *.mod.c *.symvers
- endif
测试程序如下:
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- int main(void)
- {
- int fd;
- int val = 1;
- fd = open("/dev/xxx",O_RDWR);
- if(fd < 0)
- {
- printf("open error\n");
- }
- write(fd,&val,4);
- return 0;
- }
开发板上的测试步骤如下:
- [WJ2440]# insmod first_drv.ko
- [WJ2440]# ./first_test
- open error
- [WJ2440]# cat proc/devices
- Character devices:
- 1 mem
- 4 /dev/vc/0
- 4 tty
- 5 /dev/tty
- 5 /dev/console
- 5 /dev/ptmx
- 7 vcs
- 10 misc
- 13 input
- 14 sound
- 29 fb
- 81 video4linux
- 89 i2c
- 90 mtd
- 116 alsa
- 128 ptm
- 136 pts
- 180 usb
- 188 ttyUSB
- 189 usb_device
- 204 tq2440_serial
- <span style="color:#ff0000;">252 first_drv</span>
- 253 usb_endpoint
- 254 rtc
- Block devices:
- 259 blkext
- 7 loop
- 8 sd
- 31 mtdblock
- 65 sd
- 66 sd
- 67 sd
- 68 sd
- 69 sd
- 70 sd
- 71 sd
- 128 sd
- 129 sd
- 130 sd
- 131 sd
- 132 sd
- 133 sd
- 134 sd
- 135 sd
- 179 mmc
- [WJ2440]# mknod /dev/xxx c 252 0
- [WJ2440]# ls -l /dev/xxx
- crw-r--r-- 1 root root 252, 0 Jan 1 20:49 /dev/xxx
- [WJ2440]# ./first_test
- first_drv_open
- first_drv_write
- [WJ2440]#
驱动环境的搭建详情请参考:
http://blog.csdn.net/lwj103862095/article/details/17465835
- linux字符驱动之初见
- linux字符驱动之初见
- linux字符驱动之初见
- linux字符驱动之初见
- linux字符驱动之初见
- Linux 之Awk 初见
- Linux驱动之字符设备
- linux内核之字符驱动
- linux驱动之字符设备
- Linux设备驱动之《字符设备驱动》
- LINUX驱动之字符设备驱动1
- Linux字符设备驱动之LED驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- linux设备驱动之字符设备驱动
- iOS UIDocumentInteractionController 设置第三方打开方式的 参数详解
- jquery获取input的值
- android在图片上添加文字
- iOS开发UI篇—核心动画(UIView封装动画)
- Linux用户态和内核态
- linux字符驱动之初见
- 人月神话-外科手术队伍 解析
- iOS SEL
- maven中如何将所有引用的jar包打包到一个jar中
- IoGetDeviceObjectPointer和ObReferenceObjectByName得到设备对象指针
- 汇编指令b 和 bl
- Java中==和equals的区别
- eclipse tomcat热部署问题相关
- Yii调试时,Undefined offset:xxx解决方法