led驱动模块编译、加载和测试
2014-08-06 09:39
495 查看
转:/article/2058265.html
第一步:在Linux下编写驱动程序
1、在Linux3.0/driver/
->mkdir hello_me
2、在hello_me目录下,新建编写makefiel和Kconfig
makefile 如下:
Kconfig 如下:
3、leds.c 如下:
4、在Linux3.0/driver/makefile 的修改,如下:
..............
...............略
5、在Linux3.0/driver/Kconfig 的修改,如下:
......................................
...........................略
6、在Linux3.0下执行make ARCH=arm menuconfig
选择进入 device driver,会看到:
在【M】HELLO_ME LEDS Driver,按M,编译成leds.ko即可
第二步,加载leds.ko驱动
1、用adb push D:\lins\leds.ko /system/vendor/modules/
-> 这个会有一个小问题:
解决办法如下:
执行命令:
2、adb shell & insmod /system/vendor/modules/leds.ko
3、cd dev & ls
如图:
4、出现一个jiangdou_led的IO设备,是不是很奇特:
5、输入命令:echo 1 > jiangdou_led
6、打开led
第一步:在Linux下编写驱动程序
1、在Linux3.0/driver/
->mkdir hello_me
2、在hello_me目录下,新建编写makefiel和Kconfig
makefile 如下:
# # Makefile for HELLO_ME_LEDS # # SPI testing only for (using spidev driver) # \file -> spi_test.c # \version 1.0.0 # \date 2014年04月23日 # \author jiangdou <jiangdouu88@126.com> # Copyright (c) 2014 jiangdou. All Rights Reserved. obj-$(CONFIG_HELLO_ME_LEDS) += leds.o
Kconfig 如下:
# # HSI driver configuration # config HELLO_ME_LEDS tristate "HELLO_ME LEDS Driver" help Say Y here if you want to support the LEDS device
3、leds.c 如下:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/device.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #if 1 #define GPIO_BASE 0x01C20800 #define GPE_CFG0 (GPIO_BASE + 0x90) //PE CFG0 #define GPE06_CFG (1 << 24) //配置PE06为输出模式 #define GPE_DATA (GPIO_BASE + 0xA0) #endif /*自动创建设备节点结构体*/ static struct class *leddrv_class; /*cfg0里面有PE06*/ volatile unsigned long *gpe_cfg0 = NULL; volatile unsigned long *gpe_date = NULL; /*设备打开函数,当你在应用程序里面对led执行open函数这个函数就会被执行*/ static int led_drv_open(struct inode *inode, struct file *file) { /*将PE06_CFG位清零*/ *gpe_cfg0 &= ~(GPE06_CFG); /*将PE06_CFG位置1,即设置为输出模式*/ *gpe_cfg0 |= GPE06_CFG; /*在内核里面打印要用printk*/ //printk(KERN_ALERT"led openi\n"); printk("led openi\n"); return 0; } /*设备写函数,当你在应用程序里面对led执行write函数这个函数就会被执行*/ static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { //printk(KERN_ALERT"led write\n"); int val ; /*内核空间和用户空间相互独立,两者之间数据交换要用这个函数*/ copy_from_user(&val,buf,count); if(val == 1) { /*置0,相当pin_write写0*/ //*gph_date &= ~(0×03<<15); //写PH15,PH16 *gpe_date &= ~(0x01<<6); //写PE06 } else { /*置1,相当pin_write写1*/ // *gph_date |= (0×03<<15); *gpe_date |= (0x01<<6); } return 0; } /*linux设备驱动里面每个设备都得要一个设备描述符,其实就可以结构体,有兴趣的可以看看他的原型*/ static struct file_operations led_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = led_drv_open, /*函数指针赋值*/ .write = led_drv_write, /*函数指针赋值*/ }; /*主设备号变量*/ int major; /*当执行insmod命令的时候这个函数会被执行 */ static int led_drv_init(void) { pr_err("leds_init by jiangdou 20140420\n"); /*注册一个LED设备,参数0表示让操作系统分配主设备号,分配好了之后返回给major */ major = register_chrdev(0, "jiangdou_led", &led_drv_fops); /*创建设备节点,有了这两个函数,我们在文件系统里面就会看到/dev/led */ leddrv_class = class_create(THIS_MODULE,"jiangdou_led"); device_create(leddrv_class,NULL,MKDEV(major,0),NULL,"jiangdou_led"); /*linux系统里面都是虚拟地址 ioremap就是将虚拟地址转换为物理地址,然后我们可以对寄存器进行操作 *第一个参数表示需要映射的基地址,第二个参数表示长度,即基地址+0×10*/ gpe_cfg0 = (volatile unsigned long *)ioremap(GPE_CFG0,20);//20表示20 byte,5个32 // /*0×A0 = 0×90 +4*4*/ gpe_date = gpe_cfg0 + 4; return 0; } /*当执行rmmod的时候会被执行*/ static void led_drv_exit(void) { /*注销LED设备*/ unregister_chrdev(major, "led"); // 卸载 /*释放申请的地址*/ iounmap(gpe_cfg0); /*销毁创建的设备节点*/ device_destroy(leddrv_class,MKDEV(major,0)); class_destroy(leddrv_class); printk(KERN_ALERT"leds unregister\n"); } /*linux设备驱动的两个修饰符*/ module_init(led_drv_init); module_exit(led_drv_exit); /*遵循GPL协议*/ MODULE_AUTHOR("by jiangdou"); MODULE_LICENSE("GPL");
4、在Linux3.0/driver/makefile 的修改,如下:
# # Makefile for the Linux kernel device drivers. # # 15 Sep 2000, Christoph Hellwig <hch@infradead.org> # Rewritten to use lists instead of if-statements. # obj-y += gpio/ obj-$(CONFIG_HELLO_ME_LEDS) += hello_me/ obj-$(CONFIG_PCI) += pci/
..............
...............略
5、在Linux3.0/driver/Kconfig 的修改,如下:
menu "Device Drivers" source "drivers/base/Kconfig" source "drivers/hello_me/Kconfig" source "drivers/connector/Kconfig" source "drivers/mtd/Kconfig"
......................................
...........................略
6、在Linux3.0下执行make ARCH=arm menuconfig
选择进入 device driver,会看到:
在【M】HELLO_ME LEDS Driver,按M,编译成leds.ko即可
第二步,加载leds.ko驱动
1、用adb push D:\lins\leds.ko /system/vendor/modules/
-> 这个会有一个小问题:
解决办法如下:
执行命令:
2、adb shell & insmod /system/vendor/modules/leds.ko
3、cd dev & ls
如图:
4、出现一个jiangdou_led的IO设备,是不是很奇特:
5、输入命令:echo 1 > jiangdou_led
6、打开led
相关文章推荐
- 编译加载mini2440_led驱动后,测试 该驱动是否有用
- Code maturity level options 代码成熟度选项 [*]Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完成的代码与驱动.除非你是测试人员或者开发者,否则请勿选择 我是开发者,所以选[*] Loadable module support 可加载模块支持 [*]Enable loadable module support 内核编译配置选项简介 (2.4.20-8
- 在OK6410 android开发板上添加led驱动模块,并通过NDK测试驱动
- OK6410 linux 内核模块加载--LED内核模块编译加载
- linux启动时对编译进内核驱动模块的加载
- linux启动时对编译进内核驱动模块的加载
- 编译第一个驱动,加载点亮LED
- 转:linux启动时对编译进内核驱动模块的加载
- 编译时向内核添加新设备 模块的方式动态的将驱动加入内核,但这种方式加入的驱动程序,当系统重新启动时, 还需要重新用模块的方式进行插入,如果是系统内常用的设备驱动采用这种方式进行加载, 就会很不方便。
- LED驱动测试程序以及静态加载驱动过程
- Android新编译的内核驱动模块不能被init加载原因解决
- Linux 2.6 内核驱动模块的编译和加载
- mini2440驱动奇谭——LED驱动与测试(动态加载)
- 2440平台,LED驱动模块,成功加载,rmmod可以卸载,但是总是报错
- 【设计分享】linux硬件驱动实例及编译模块加载
- 将LED驱动模块编译到Linux3.10.17内核
- 6410led驱动模块及测试程序(独立控制四个led)
- ti8148内核编译驱动模块-手动加载mmc驱动
- 编译LED驱动,在device上测试
- 基于mini2440的linux驱动程序模块编译测试笔记