您的位置:首页 > 运维架构 > Linux

【DM8168】Linux下控制GPIO实现LED流水灯

2014-11-27 20:32 316 查看
首先加载驱动模块,应用程序通过调用API实现GPIO控制功能。

驱动程序:

/*
* 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: