LED驱动的简单功能实现
时间:10-02
整理:3721RD
点击:
调试了好几天的GPIO驱动,发现无法申请动态的驱动,只能用光盘自带的程序加以修改来实现以前我实现过的功能了。
驱动分为三个部分:驱动程序、Makefile、应用程序。
驱动程序的编译需要在Linux环境下进行编译,之后将生成的.ko文件通过NFS服务拷贝至开发板,安装驱动即可使用。
驱动程序:
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/sched.h>
- #include <linux/init.h>
- #include <linux/fs.h>
- #include <linux/ioctl.h>
- #include <linux/delay.h>
- #include <linux/bcd.h>
- #include <linux/capability.h>
- #include <linux/rtc.h>
- #include <linux/cdev.h>
- #include <linux/miscdevice.h>
- #include <linux/gpio.h>
- #include <../arch/arm/mach-mx28/mx28_pins.h>
- #define DEVICE_NAME "imx28x_led"
- #define LED_GPIO MXS_PIN_TO_GPIO(PINID_SAIF0_MCLK)
- #define LED_GPIO1 MXS_PIN_TO_GPIO(PINID_SSP0_DATA7)
- static int gpio_open(struct inode *inode, struct file *filp)
- {
- gpio_request(LED_GPIO, "led");
- gpio_request(LED_GPIO1, "led1");
- return 0;
- }
- static int gpio_release(struct inode *inode, struct file *filp)
- {
- gpio_free(LED_GPIO);
- gpio_free(LED_GPIO1);
- return 0;
- }
- static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
- {
- switch (command){
- case 0:
- switch (arg) {
- case 0:
- gpio_direction_output(LED_GPIO, 0);
- break;
- case 1:
- gpio_direction_output(LED_GPIO, 1);
- break;
- }
- break;
- case 1:
- switch (arg) {
- case 0:
- gpio_direction_output(LED_GPIO1, 0);
- break;
- case 1:
- gpio_direction_output(LED_GPIO1, 1);
- break;
- }
- break;
- }
- return 0;
- }
- static struct file_operations gpio_fops={
- .owner = THIS_MODULE,
- .open = gpio_open,
- .write = gpio_write,
- .release = gpio_release,
- .ioctl = gpio_ioctl,
- };
- static struct miscdevice gpio_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = DEVICE_NAME,
- .fops = &gpio_fops,
- };
- static int __init gpio_init(void)
- {
- misc_register(&gpio_miscdev);
- printk(DEVICE_NAME" up. \n");
- return 0;
- }
- static void __exit gpio_exit(void)
- {
- misc_deregister(&gpio_miscdev);
- printk(DEVICE_NAME " down.\n");
- }
- module_init(gpio_init);
- module_exit(gpio_exit);
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("zhuguojun, ZhiYuan Electronics Co, Ltd.");
- MODULE_DESCRIPTION("GPIO DRIVER FOR EasyARM-i.MX28xx");
Makefile:
- ARCH=arm
- CROSS_COMPILE=/opt/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/arm-fsl-linux-gnueabi-
- obj-m := led.o
- KDIR := /usr/linux-2.6.35.3
- PWD := $(shell pwd)
- default:
- make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
- clean: clean:
- $(MAKE) -C $(KDIR) M=$(PWD) clean
应用程序:
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <errno.h>
- #include <limits.h>
- #include <asm/ioctls.h>
- #include <time.h>
- #include <pthread.h>
- int main(int argc, char **argv)
- {
- int fd;
- int a,b;
- fd = open("/dev/imx28x_led", O_RDWR);
- if (fd < 0) {
- perror("open /dev/imx28x_led");
- }
- a = atoi(argv[1]);
- b = atoi(argv[2]);
- ioctl(fd,a,b);
- return 0;
- }
下面是实物图: