【DM8168】Linux下控制GPIO实现LED流水灯
2014-11-27 20:32
316 查看
首先加载驱动模块,应用程序通过调用API实现GPIO控制功能。
驱动程序:
API函数:
应用程序:
驱动程序:
/* * fileName: led_gpio.c * just for LED GPIO test * GP1_14 -> HDD * GP1_15 -> REC * GP1_27 -> NC * GP1_28 -> IR */ #include <linux/device.h> #include <linux/fs.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/moduleparam.h> #include <linux/list.h> #include <linux/cdev.h> #include <linux/proc_fs.h> #include <linux/mm.h> #include <linux/seq_file.h> #include <linux/ioport.h> #include <linux/delay.h> #include <asm/io.h> #include <linux/io.h> #include <mach/gpio.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/ioctl.h> #define DRIVERNAME "led4" #define CTRL_MODULE_BASE_ADDR 0x48140000 // PANEL CON #define conf_gpio46 (CTRL_MODULE_BASE_ADDR + 0x0B04) #define conf_gpio47 (CTRL_MODULE_BASE_ADDR + 0x0B08) #define conf_gpio59 (CTRL_MODULE_BASE_ADDR + 0x0AB8) #define conf_gpio60 (CTRL_MODULE_BASE_ADDR + 0x0ABC) #define WR_MEM_32(addr, data) *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) = (unsigned int)(data) #define RD_MEM_32(addr) *(unsigned int*)OMAP2_L4_IO_ADDRESS(addr) static dev_t dev; static struct cdev cdev; static struct class *led_gpio_class = NULL; static int gpio[4]; static int led_gpio_open(struct inode *inode, struct file *file); static int led_gpio_close(struct inode *inode, struct file *file); static long led_gpio_ioctl(struct file *file, unsigned int val, unsigned long pin); //static int valid_check(unsigned int gpioNum); ////////////////////////////////////////////////////////////////////////////// /*- static int valid_check(unsigned int gpioNum) { if((gpioNum==46)||(gpioNum==47)||(gpioNum==59)||(gpioNum==60)) return 1; return -1; } -*/ static void store_gpio_pin(void) { // store gpio pinmux gpio[0] = RD_MEM_32(conf_gpio46); gpio[1] = RD_MEM_32(conf_gpio47); gpio[2] = RD_MEM_32(conf_gpio59); gpio[3] = RD_MEM_32(conf_gpio60); } static void recover_gpio_pin(void) { // recover gpio pinmux WR_MEM_32(conf_gpio46, gpio[0]); WR_MEM_32(conf_gpio47, gpio[1]); WR_MEM_32(conf_gpio59, gpio[2]); WR_MEM_32(conf_gpio60, gpio[3]); gpio_free(gpio[0]); gpio_free(gpio[1]); gpio_free(gpio[2]); gpio_free(gpio[3]); } static void config_gpio_pin(void) { WR_MEM_32(conf_gpio46, 2); gpio_request(46, "gpio46_en"); // request gpio46 gpio_direction_output(46, 0); WR_MEM_32(conf_gpio47, 2); gpio_request(47, "gpio47_en"); // request gpio47 gpio_direction_output(47, 0); WR_MEM_32(conf_gpio59, 1); gpio_request(59, "gpio59_en"); // request gpio59 gpio_direction_output(59, 0); WR_MEM_32(conf_gpio60, 1); gpio_request(60, "gpio60_en"); // request gpio60 gpio_direction_output(60, 0); } static int led_gpio_open(struct inode *inode, struct file *file) { // store gpio pin value store_gpio_pin(); // configure all used gpio config_gpio_pin(); return 0; } static int led_gpio_close(struct inode *inode, struct file *file) { // recover gpio pin mux; recover_gpio_pin(); return 0; } static long led_gpio_ioctl(struct file *file, unsigned int val, unsigned long pin) { if(valid_check(pin) < 0){ printk("GPIO:%d can't use!\n", (int)pin); return -1; } gpio_set_value(pin, val); return 0; } static struct file_operations led_gpio_fops = { .owner = THIS_MODULE, .open = led_gpio_open, .release = led_gpio_close, .unlocked_ioctl = led_gpio_ioctl, }; static int __init LED_init(void) { int result; result = alloc_chrdev_region(&dev, 0, 1, DRIVERNAME); if(result < 0){ printk("Error registering led_gpio character device\n"); return -ENODEV; } printk(KERN_INFO "led_gpio major#: %d, minor#: %d\n", MAJOR(dev), MINOR(dev)); cdev_init(&cdev, &led_gpio_fops); cdev.owner = THIS_MODULE; cdev.ops = &led_gpio_fops; result = cdev_add(&cdev, dev, 1); if(result){ unregister_chrdev_region(dev, 1); printk("Error adding led_gpio.. error no:%d\n",result); return -EINVAL; } led_gpio_class = class_create(THIS_MODULE, DRIVERNAME); device_create(led_gpio_class, NULL, dev, NULL, DRIVERNAME); printk(DRIVERNAME "initialized"); return 0; } static void __exit LED_exit(void) { printk("led chrdev exit!\n"); cdev_del(&cdev); unregister_chrdev_region(dev, 1); device_destroy(led_gpio_class, dev); class_destroy(led_gpio_class); } module_init(LED_init); module_exit(LED_exit); MODULE_LICENSE("GPL");
API函数:
#ifndef API_LED_H #define API_LED_H #include <stdio.h> #ifdef __cplusplus extern "C" { #endif int api_led_open(void); int api_led_close(int fd_led); int api_led_ioctl(int fd_led, unsigned int pin, unsigned int val); #ifdef __cplusplus } #endif #endif
#include "api_led.h" #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #define DEVICENAME "/dev/led4" int api_led_open(void) { int fd_led; if((fd_led=open(DEVICENAME,O_RDWR)) <= -1){ printf("open device error\n"); return -1; } return fd_led; } int api_led_close(int fd_led) { if(0 == close(fd_led)) return 0; else return -1; } int api_led_ioctl(int fd_led, unsigned int pin, unsigned int val) { if(ioctl(fd_led, val, pin) < 0){ printf("write error\n"); return -1; }else{ return 0; } }
应用程序:
/*- test for Lcd12864 -*/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "api_led.h" int main(void) { int fd_led; // int num; // int ret; int delay = 10; fd_led = api_led_open(); if(fd_led < 0){ printf("fd_led open failed!\n"); return -1; } api_led_ioctl(fd_led, 47, 1); api_led_ioctl(fd_led, 60, 1); printf("Hello, Water LEDs run!\n"); while(delay--){ api_led_ioctl(fd_led, 60, 1); // LED IR off api_led_ioctl(fd_led, 46, 0); // LED HDD on usleep(100000); api_led_ioctl(fd_led, 46, 1); // LED HDD off api_led_ioctl(fd_led, 47, 0); // LED REC on usleep(100000); api_led_ioctl(fd_led, 47, 1); // LED REC off api_led_ioctl(fd_led, 60, 0); // LED IR on usleep(100000); // if(count < 0) return -1; // printf("light LED HDD!\n ") } api_led_close(fd_led); return 0; }
相关文章推荐
- (一)GPIO 编程实验 LED 流水灯控制
- 如何实现DragonBoard 410c GPIO控制(基于linux环境)
- S3C24XX体系的Linux GPIO控制相关API实现
- Android下led控制(下)--Linux驱动部分--script与gpio(全志)
- Linux下实现流水灯等功能的LED驱动代码及测试实例
- 【DM8168】Linux下控制GPIO控制12864液晶屏(ST7565控制器)
- S3C24XX体系的Linux GPIO控制相关API实现
- JZ2440通过sysfs控制gpio实现板载LED的控制
- P1口外接8个LED,通过按键控制,实现左右移动的流水灯
- mx53 linux gpio控制led
- S3C24XX体系的Linux GPIO控制相关API实现-顶嵌嵌入式专家写
- 控制GPIO, 点亮led,实现跑马灯
- SylixOS下监控控制LED的GPIO电平的一种不规范实现方式
- GPIO编程(三)键盘控制led灯
- 用C#控制TQ2440开发板上的LED小灯(C# GPIO学习笔记)
- ARM Linux权限内存控制的实现
- s3c2440基于linux的gpio led字符设备驱动实践 [转]
- linux之gpio管理 之2 实现方法
- 6410寄存器控制GPIO点亮LED
- 混杂设备LED驱动程序(GPIO操作函数实现)