驱动代码如下:

#include <linux/kernel.h>//内核头文件
#include <linux/init.h>//__init等
#include <linux/module.h>//模块加载的头文件
#include <linux/fs.h>//file_operations
#include <linux/errno.h>//错误状态常数
#include <linux/types.h>//size_t,ssize_t等 //--------------cdev----------------
#include <linux/cdev.h> //-------------class_create,device_create------
#include <linux/device.h> //--------------GPIO-----------------
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h> //-------CMD COMMAND----------------
#define LED1_ON 0x1
#define LED1_OFF 0x0 #define DEVICE_NAME "LED1" static int led1_gpios[]=
{
S5PV210_MP04(),
S5PV210_MP04(),
S5PV210_MP04(),
S5PV210_MP04()
}; #define LED1_NUM ARRAY_SIZE(led1_gpios) /*用udev机制自动添加设备节点*/
struct class *led1_class; /*设备结构体*/
struct led1_dev_t
{
struct cdev cdev;
}led1_dev; /*
// ------------------- READ ------------------------
ssize_t led1_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)
{
return count;
} // ------------------- WRITE -----------------------
ssize_t led1_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)
{
return count;
}
// ------------------- OPEN ------------------------
ssize_t led1_open (struct inode * inode ,struct file * file)
{
return 0;
}
// ------------------- RELEASE/CLOSE ---------------
ssize_t led1_release (struct inode * inode ,struct file * file)
{
return 0;
}
// -------------------------------------------------
*/ // ------------------- IOCTL -----------------------
static int led1_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, unsigned long arg)
{
if(arg > LED1_NUM)
{
printk("arg is %u ,led num is %d\n",arg,LED1_NUM);
printk("num is err!!\n");
return - EINVAL;
}
switch (cmd)
{
case LED1_ON:
{
/*code*/
gpio_set_value(led1_gpios[arg],);
printk("led1 is on!!\n");
break;
}
case LED1_OFF:
{
/*code*/
gpio_set_value(led1_gpios[arg],);
printk("led1 is off!!\n");
break;
}
default :
{
printk ("CMD err!!\n");
return - EINVAL;
}
}
return ; } struct file_operations led1_fops ={ .owner = THIS_MODULE,
// .open = led1_open,
// .read = led1_read,
// .write = led1_write,
.ioctl = led1_ioctl,
// .release = led1_release,
}; // ------------------- INIT ------------------------
static int __init led1_init(void)
{
printk("led num is : %d\n",LED1_NUM);
int i,ret;
for (i = ; i < LED1_NUM; i++)
{ /*
ret=gpio_request(led1_gpios[i],"LED1");
if(ret)//注意,是ret
{
printk("%s:request GPIO %d for LED1 failed,ret= %d\n",DEVICE_NAME,led1_gpios[i],ret);
return ret;
}
*/
s3c_gpio_cfgpin(led1_gpios[i],S3C_GPIO_SFN());
gpio_set_value(led1_gpios[i],);
} /*init cdev*/
cdev_init(&led1_dev.cdev,&led1_fops);
led1_dev.cdev.owner=THIS_MODULE; /*向系统动态申请未被占用的设备号*/
ret = alloc_chrdev_region(&led1_dev.cdev.dev,,,DEVICE_NAME);//int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name) if (ret)
{
printk("register failed\n");
return ret;
} /*添加字符设备*/
ret = cdev_add(&led1_dev.cdev, led1_dev.cdev.dev, );
if (ret)
{
printk("cdev add failed\n");
goto fail1;
}
/*udev机制可以自动添加设备节点,只需要添加xxx_class这个类,以及device_create()*/
led1_class = class_create(THIS_MODULE, "led1_class");/*在sys目录下创建xx_class这个类,/sys/class/~*/
if (IS_ERR(led1_class))
{
printk("class create failed\n");
goto fail2;
}
device_create(led1_class, NULL, led1_dev.cdev.dev, DEVICE_NAME, DEVICE_NAME);/*自动创建设备/dev/$DEVICE_NAME*/
return ret; fail2:
cdev_del(&led1_dev.cdev);
fail1:
unregister_chrdev_region(led1_dev.cdev.dev, );
return ret;
} static void __exit led1_exit(void)
{
int i;
/*
for (i = 0; i < LED1_NUM; i++)
{ gpio_free(led1_gpios[i]);
}
*/
device_destroy(led1_class, led1_dev.cdev.dev);
class_destroy(led1_class);
cdev_del(&led1_dev.cdev);
unregister_chrdev_region(led1_dev.cdev.dev, );
} module_init(led1_init);
module_exit(led1_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("mhb@seu");

测试代码如下:

#include <stdio.h>
//#include "sys/types.h"
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
//#include "termios.h"
//#include "sys/stat.h"
#include <fcntl.h> #define LED1_ON 0x1
#define LED1_OFF 0x0 main(int argc,char *argv[])
{
int fd; if ((fd=open("/dev/LED1",O_RDWR /*| O_NDELAY | O_NOCTTY*/)) < )
{
printf("Open Device failed.\r\n");
exit();
}
else
{
printf("Open Device successed.\r\n");
}
if (argc<)
{
/* code */
printf("Usage: %s <on|off num>\n",argv[]);
exit();
}
if(!strcmp(argv[],"on"))
{
printf("led1 will on!!\n");
printf("argv[2]=%d\n",atoi(argv[]));
if(ioctl(fd,LED1_ON,atoi(argv[]))<)
{
printf("ioctl err!!\n");
} }
if(!strcmp(argv[],"off"))
{
printf("led1 will off!!\n");
if(ioctl(fd,LED1_OFF,atoi(argv[]))<)
{
printf("ioctl err!!\n");
}
}
close(fd);
}

LED字符设备驱动实例及测试代码的更多相关文章

  1. fl2440 platform总线led字符设备驱动

    首先需要知道的是,设备跟驱动是分开的.设备通过struct device来定义,也可以自己将结构体封装到自己定义的device结构体中: 例如:struct platform_device: 在inc ...

  2. Tiny6410 LED字符设备驱动

    1.查看用户手册 led1.led2.led3.led4 连接的分别是 GPK4.GPK5.GPK6.GPK7 2.查询6410芯片手册 下面还需要3个步骤: 1.设置GPIO为OUTPUT. 将GP ...

  3. Linux字符设备驱动实例—globalmem驱动

    1.globalmem虚拟设备实例 globalmem为“全局内存”的意思,在globalmem字符设备中会分配一片大小为GLOBALMEM_SIZE(4KB)的内存空间,并在驱动中提供对这片内存的读 ...

  4. Linux_2.6字符设备驱动实例

    第一步:my74hc595.c #include <linux/module.h> //模块所需的大量符号和函数定义#include <linux/init.h> //指定初始 ...

  5. Linux LED字符设备驱动

    // 申请IO资源 int gpio_request(unsigned gpio, const char *label); // 释放IO资源 void gpio_free(unsigned gpio ...

  6. 【转】linux设备驱动程序之简单字符设备驱动

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/03/2272869.html 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用 ...

  7. 【Linux驱动】字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

  8. arm-linux字符设备驱动开发之---简单字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

  9. 谈谈Linux字符设备驱动的实现

    @ 目录 字符设备驱动基础 申请设备号 创建设备节点 在驱动中实现操作方法 文件IO调用驱动中的操作 应用程序与驱动的数据交互 内核驱动如何控制外设 控制LED的简单驱动实例 驱动程序的改进 框架复盘 ...

随机推荐

  1. Unix 网络编程(2)——TCP API

    TCP C/S套接口函数一般调用过程及基本函数 如上图所示的TCP连接的基本过程.一般来说,服务器先于客户端运行,服务器程序运行的基本过程是: socket()函数创建服务器段socket. bind ...

  2. mysql:通用查询日志general_log

    1.通用查询日志:记录建立的客户端连接和执行的语句,通用查询日志默认情况下不是开启的,通用查询日志是以文本方式存放的 当需要采样分析的时候手工开启: SET Global general_log=1; ...

  3. Unicode 编码解码

    1. Regex.Unescape(str);返回Unicode解码,非Unicode直接返回 /// <summary>      /// 2.转为Unicode编码      /// ...

  4. JS常用正则(转)

    作者:zxin出处:http://zxin.cnblogs.com/ 一.校验数字的表达式 1 数字:^[0-9]*$ 2 n位的数字:^\d{n}$ 3 至少n位的数字:^\d{n,}$ 4 m-n ...

  5. aggregation 详解3(bucket aggregation)

    概述 桶分聚合不进行权值的计算,他们对文档根据聚合请求中提供的判断条件(比如:{"from":0,  "to":100})来进行分组(桶分). 桶分聚合还会额外 ...

  6. Elasticsearch 查询与过滤

    今天在给上级汇报工作的时候,被问到了这个问题,一时也没回到上来. 英文原文: https://www.elastic.co/guide/en/elasticsearch/guide/current/_ ...

  7. 【Objective-C】2.自定义构造方法和description方法

    1.Student.h 1 #import <Foundation/Foundation.h> 2 3 @interface Student : NSObject { 4 int _age ...

  8. MySQL索引详解

    导读:大家都知道,一个MySQL数据库能够储存大量的数据,如果要查找那一个数据,就得费好大劲从一大堆的数据中找到,即费时间又费力气,这时,索引的出现就大大减轻了数据库管理员的工作.本文介绍了数据库索引 ...

  9. 用gd库画矩形和椭圆

    画矩形:bool imagerectangle ( resource $image画布资源 , int $x1左上角的坐标 , int $y1 , int $x2 右下角坐标, int $y2 , i ...

  10. Java事务处理总结

    http://lavasoft.blog.51cto.com/62575/53815/ 一.什么是Java事务   通常的观念认为,事务仅与数据库相关.   事务必须服从ISO/IEC所制定的ACID ...