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

linux驱动--LED驱动

2016-07-08 11:14 399 查看

linux驱动–LED驱动

配置介绍

前面已经详细的介绍了关于设备注册、驱动注册以及设备节点的生成的相关问题,本文主要介绍如何写LED驱动程序。

主要介绍GPIO的 调用、赋值以及配置的函数

(1)使用一个GPIO前必须对其进行申请,申请GPIO的函数在linux头文件include/linux/gpio.h下



GPIO_request函数有两个参数,第一个gpio为所需要申请的gpio,*label为gpio编号,是为了便于阅读。若该gpio被占用,则返回错误表示被占用。

与GPIO_request对应的是gpio_free函数,操作方法只需要传入gpio端口号即可。



(2)配置完GPIO后,需要对其设置值,就需要使用gpio_set_value函数了



两个参数分别为

unsigned gpio,GPIO

int value,高电平 1 和低电平 0

(3)GPIO输出方式配置

在平台文件中arch/arm/plat-samsung/include/plat/gpio-cfg.h中使用函数extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to)

参数 unsigned int pin,管脚

参数 unsigned int to,配置参数。

to参数可以取值如下

arch/arm/plat-samsung/include/plat/gpio-cfg.h中定义的to取值

#define S3C_GPIO_INPUT    (S3C_GPIO_SPECIAL(0))
#define S3C_GPIO_OUTPUT   (S3C_GPIO_SPECIAL(1))
#define S3C_GPIO_SFN(x)    (S3C_GPIO_SPECIAL(x))


LED驱动例程

#include <linux/module.h>//与module相关的信息
#include <linux/kernel.h>
#include <linux/init.h>      //与init相关的函数
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
/***gpio申请和释放***/
#include <linux/gpio.h>
/*******************/
#include <plat/gpio-cfg.h>
/*********************/
#include <mach/gpio-exynos4.h>
#include <mach/gpio.h>
/***************用到的函数与结构体******************
extern int platform_driver_register(struct platform_driver *);
extern void platform_driver_unregister(struct platform_driver *);

int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
杂项设备结构体
struct miscdevice  {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};

extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice *misc);

struct file_operations {
struct module *owner;
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
static inline int gpio_request(unsigned gpio, const char *label)
static inline void gpio_free(unsigned gpio)
static inline void gpio_set_value(unsigned gpio, int value)
EXYNOS4_GPIO_L2
s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
S3C_GPIO_OUTPUT
**********************************/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangsan");

#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl"

static long hello_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk(KERN_INFO "The cmd is %d,arg is %d\n",cmd,arg);
if(cmd>1)
{
printk(KERN_INFO "cmd should be 0 or 1\n");
}
if(arg>1)
printk(KERN_INFO "arg must be 1\n");
gpio_set_value(EXYNOS4_GPL2(0), cmd);//关闭
return 0;
}
static int hello_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "hello_release\n");
return 0;
}
static int hello_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "hello_open\n");
return 0;
}

static struct file_operations hello_ops={

.owner=THIS_MODULE,
.open=hello_open,
.release=hello_release,
.unlocked_ioctl=hello_ioctl,
};

static struct miscdevice hello_dev={
.minor=MISC_DYNAMIC_MINOR,
.name=DEVICE_NAME,
.fops=&hello_ops,
};

static int hello_probe(struct platform_device *pdv)
{
int ret;
printk(KERN_INFO "program inited!\n");
ret=gpio_request(EXYNOS4_GPL2(0),"LED1");
if(ret<0)
{
printk(KERN_INFO "request gpio failed\n");
return ret;
}
s3c_gpio_cfgpin(EXYNOS4_GPL2(0),S3C_GPIO_OUTPUT);
gpio_set_value(EXYNOS4_GPL2(0), 0);//关闭
misc_register(&hello_dev);

return 0;
}
static int hello_remove(struct platform_device *pdv)
{
gpio_free(EXYNOS4_GPL2(0));
misc_deregister(&hello_dev);
return 0;
}
static void hello_shutdown(struct platform_device *pdv)
{
printk(KERN_INFO "hello_shutdown\n");
}
static int hello_suspend(struct platform_device *pdv)
{
printk(KERN_INFO "Hello_suspend\n");
return 0;
}
static int hello_resume(struct platform_device *pdv)
{
printk(KERN_INFO "Hello_resume\n");
return 0;
}

struct  platform_driver hello_driver={
.probe=hello_probe,
.remove=hello_remove,
.shutdown=hello_shutdown,
.suspend=hello_suspend,
.resume=hello_resume,
.driver={
.name=DRIVER_NAME,
.owner=THIS_MODULE,
}
};

static int hellodriver_init()
{
int Driverstate;
//printk(KERN_INFO "Hello_init\n");
Driverstate=platform_driver_register(&hello_driver);
printk(KERN_INFO "Driverstate is %d\n",Driverstate);
return 0;
}

static void hellodriver_exit()
{

printk(KERN_INFO "Hello_exit\n");
platform_driver_unregister(&hello_driver);
}

module_init(hellodriver_init);
module_exit(hellodriver_exit);


驱动调用程序

写简单的驱动调用程序测试驱动

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main()
{
int fd;
char *hellonode="/dev/hello_ctl";
if((fd=open(hellonode,O_RDWR|O_NOCTTY|O_NDELAY))<0)
{
printf("open %s.failed",hellonode);
}
else
{
printf("APP open %s sucess!",hellonode);
ioctl(fd,0,1);
sleep(2);
ioctl(fd,1,1);
sleep(2);
ioctl(fd,0,1);
sleep(2);
ioctl(fd,1,1);
sleep(2);
}

close(fd);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux驱动