驱动代码如下:

#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. C栈stack

    栈是一种  特殊的线性表 栈仅能在线性表的一端进行操作 栈顶(Top):允许操作的一端 栈底(Bottom):不允许操作的一端 Stack的常用操作 创建栈 销毁栈 清空栈 进栈 出栈 获取栈顶元素 ...

  2. php开发环境以及插件的配置安装

    目前网上提供的常用的PHP集成环境主要有AppServ.phpStudy.WAMP和XAMPP等软件

  3. 如何去除掉inline-block元素之间的默认间距

    前几天写一个页面 div{width:900px;} div li{ display:inline-block; width:300px;} <ul> <li></li& ...

  4. JavaScript学习总结二(Date对象的用法)

    javascript Date对象的常用API 1:创建日期 Date 对象用于处理日期和时间. 可以通过 new 关键词来定义 Date 对象.以下代码定义了名为 myDate 的 Date 对象: ...

  5. 关于SQL语言分类

    从功能上划分,SQL语言可以分为DDL,DML和DCL三大类. 事务:可以作用在DML(update.insert.delete)语句上. 1. DDL(Data Definition Languag ...

  6. js事件监听机制(事件捕获)总结

    在前端开发过程中我们经常会遇到给页面元素添加事件的问题,添加事件的js方法也很多,有直接加到页面结构上的,有使用一些js事件监听的方法,由于各个浏览器对事件冒泡事件监听的机制不同,le浏览器只有事件冒 ...

  7. Python(2.7.6) glob - 匹配指定模式的文件

    Python 标准库的 glob 模块支持查询匹配指定模式的文件或目录.这里的模式使用的并不是正则表达式,而是通过通配符来匹配的 Unix 风格的路径名扩展. 支持的通配符: 通配符 说明 *  匹配 ...

  8. Rabbit MQ安装配置及常见问题

    Window安装 1:RabbitMQ安装 1.1:安装Erlang:http://www.erlang.org/ 1.2:安装RabbitMQ:http://www.rabbitmq.com/dow ...

  9. SecureCRT 7 注册码

    Name: Sherrill Ray Company:  空 Serial Number:03-40-084141 License Key: ABWGUE ZPPZ6X XHTN2S 1N7PER A ...

  10. VS打包

    同学让帮忙打包个VC的程序,程序比较简单,是带access数据库的统计查询软件,之前用Visual Studio 6.0自带的Package & Deployment Wizard 工具打包过 ...