led驱动
驱动步骤:
1、驱动框架:一般读驱动代码需要module_init一层层找代码
2、硬件配置
代码中led_ioctl函数设置引脚的电平高低,该函数是驱动程序对设备的通道进行统一设置/控制的函数
一、 在用户空间,使用ioctl系统调用来控制设备,原型如下:
int ioctl(int fd,unsigned long cmd,...);
fd:文件描述符
cmd:控制命令
...:可选参数:插入*argp,具体内容依赖于cmd
用户程序所作的只是通过命令码告诉驱动程序它想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要做的事情。
二、驱动ioctl方法:
int (*ioctl) (struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);
/*
inode与filp两个指针对应于应用程序传递的文件描述符fd,这和传递open方法的参数一样。
cmd 由用户空间直接不经修改的传递给驱动程序
arg 可选。
*/
在驱动程序中实现的ioctl函数体内,实际上是有一个switch {case}结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程序员自己的事情,因为设备都是特定的。关键在于怎么样组织命令码,因为在ioctl中命令码是唯一联系用户程序命令和驱动程序支持的途径。
用户使用 int ioctl(int fd,unsinged long cmd,...) 时,...就是要传递的参数;
再通过 int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 中的arg传递;不同颜色代表对应的参数
现阶段能够理解成每一个用户程序的ioctl对应其内核中的一个ioctl函数,且参数需要用户层传递给驱动层 (该例中)
代码很简单 :
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#define DEVICE_NAME "myled" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
static struct class *leds_class;
static struct class *led_dev_class;
int major; /* 用来指定LED所用的GPIO引脚 */
static unsigned long led_table[]={ S3C2410_GPF5,
S3C2410_GPF6, }; /* 用来指定GPIO引脚的功能:输出 */
static unsigned int led_cfg_table [] = { S3C2410_GPF5_OUTP,
S3C2410_GPF6_OUTP,
}; /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define LED_ON 0
#define LED_OFF 1
/* 应用程序对设备文件/dev/leds执行open(...)时,
* 就会调用s3c24xx_leds_open函数
*/
static int led_open (struct inode *inode, struct file *filep)
{
int i;
// 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能
for (i = ; i <; i++) {
// 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
}
return ;
}
static int led_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
{ if (arg > ) {
return -EINVAL;
}
switch(cmd) {
case LED_ON:
// 设置指定引脚的输出电平为0
s3c2410_gpio_setpin(led_table[arg], );
return ;
case LED_OFF:
// 设置指定引脚的输出电平为1
s3c2410_gpio_setpin(led_table[arg], );
return ;
default:
return -EINVAL;
}
}
/* 这个结构是字符设备驱动程序的核心
* 当应用程序操作设备文件时所调用的open、read、write等函数,
* 最终会调用这个结构中指定的对应函数
*/
static struct file_operations led_ops=
{
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = led_open,
.ioctl = led_ioctl , }; /*
* 执行insmod命令时就会调用这个函数
*/ static int led_init(void)
{
int ret;
/* 注册字符设备
* 参数为主设备号、设备名字、file_operations结构;
* 这样,主设备号就和具体的file_operations结构联系起来了,
* 操作主设备为LED_MAJOR的设备文件时,就会调用s3c24xx_leds_fops中的相关成员函数
* LED_MAJOR可以设为0,表示由内核自动分配主设备号
*/
major = register_chrdev(, DEVICE_NAME, &led_ops);
if (major < )
{
printk(DEVICE_NAME " can't register major number number::%d\n",major);
return ret;
}
printk(DEVICE_NAME " initialized1\n");
leds_class = class_create(THIS_MODULE, "leds");
if (IS_ERR(leds_class))
return PTR_ERR(leds_class);
led_dev_class = class_device_create(leds_class, NULL, MKDEV(major, ), NULL, "perled"); /* /dev/leds */
return ; } /*
* 执行rmmod命令时就会调用这个函数
*/
static void led_exit(void)
{
class_device_unregister(led_dev_class, MKDEV(major, ));
class_destroy(leds_class);
/* 卸载驱动程序 */
unregister_chrdev(major, DEVICE_NAME); } module_init(led_init);
module_exit(led_exit); MODULE_AUTHOR("http://www.100ask.net");
MODULE_DESCRIPTION("S3C2410/S3C2440 LED Driver");
MODULE_LICENSE("GPL");
make
insmod XXX.ko
测试代码(应用程序代码):
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1
/*
* ledtest <dev> <on|off>
*/ void print_usage(char *file)
{
printf("Usage:\n");
printf("./a.out 1 on\n");
} int main(int argc,char**argv)
{
int fd;
int ret;
int led_NO;
char val;
if(argc!=)
{ printf("error USAGE\n");
exit();
}
//1、打开设备
fd = open("/dev/perled",O_RDWR);
led_NO=strtoul(argv[],,)-;//确定LED
if(fd<)
{
perror("open fail \n");
return -;
}
if (!strcmp("on", argv[]))
{
// 亮灯
ioctl(fd,IOCTL_LED_ON,led_NO);// 设备 亮灭 那个led、
}
else if (!strcmp("off", argv[]))
{
// 灭灯
ioctl(fd,IOCTL_LED_OFF,led_NO);
}
else
{
print_usage(argv[]);
return ;
} close(fd);
return ;
}
/// // // / //./a.out 1 on
驱动程序中的ioctl也可以用write函数但是需要用到copy_from_user
将数据由其用户 空间上传到内核空间了
static ssize_t led_write(struct file *file, const char __user *data,
size_t len, loff_t * ppos)
{
int val;
copy_from_user(&val, data, ); // copy_to_user();
s3c2410_gpio_setpin(S3C2410_GPF5, (val & 0x1));//避免使用if语句 return ; }
ioctl:http://www.cnblogs.com/geneil/archive/2011/12/04/2275372.html
led驱动的更多相关文章
- 兼容可控硅调光的一款LED驱动电路记录
1.该款电路为兼容可控硅调光的LED驱动电路,采用OB3332为开关控制IC,拓扑方案为Buck: 2.FB1:磁珠的单位是欧姆,而不是亨利,这一点要特别注意.因为磁珠的单位是按照它在某一频率 产生的 ...
- FL2440驱动添加(4)LED 驱动添加
硬件信息:FL2440板子,s3c2440CPU带四个LED,分别在链接GPB5,GPB6,GPB8,GPB10 内核版本:linux-3.8.0 led驱动代码如下: 值得注意地方地方: 1,定时器 ...
- linux设备驱动归纳总结(五):4.写个简单的LED驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-84693.html linux设备驱动归纳总结(五):4.写个简单的LED驱动 xxxxxxxxxxx ...
- uTenux——LED驱动讲解
LED驱动讲解,对于一个嵌入式的工程师还是一个刚开是学习相关电子设计的朋友,对于LED的驱动问题应该不甚陌生.我所说的LED驱动并不是类似大功率LED照明的那个驱动,而是简单的控制器对LED的控制驱动 ...
- Android系统移植与驱动开发——第七章——LED驱动
LED驱动的实现原理 编写LED驱动: 测试LED驱动之前需要用USB数据线连接开发板,然后打开电源,成功启动之后,执行build.sh脚本文件编译和安装LED驱动,顺利则会自动连接 如果有多个设备文 ...
- 全志A33 linux led驱动编程(附实测参考代码)
开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 开发平台 * 芯灵思Sinl ...
- Linux驱动之LED驱动编写
从上到下,一个软件系统可以分为:应用程序.操作系统(内核).驱动程序.结构图如下:我们需要做的就是写出open.read.write等驱动层的函数.一个LED驱动的步骤如下: 1.查看原理图,确定需要 ...
- (笔记)linux设备驱动--LED驱动
linux设备驱动--LED驱动 最近正在学习设备驱动开发,因此打算写一个系列博客,即是对自己学习的一个总结,也是对自己的一个督促,有不对,不足,需要改正的地方还望大家指出,而且希望结识志同道合的朋友 ...
- JZ2440 启动NFS网络文件系统_初试led驱动
http://blog.csdn.net/emdfans/article/details/12260969 u-boot ---> q 修改bootargs变量 默认: bootargs=noi ...
- 基于sys文件系统的LED驱动的移植【原创】
基于RK3188平台LED驱动程序的移植的移植.如有不正确之处,欢迎大家指点. 本文的LED驱动程序不是通过打开设备节点来访问和控制LED的,是通过sys文件系统来控制LED. 板子上有四盏灯以及对应 ...
随机推荐
- 前端开发week1
1.前端开发前期相关工具 photoshop:主要学习运用与前端相关工具,了解UI与前端的关联. axure:原型设计,通过设计原型了解网页基本结构,结合ps对UI有更好的理解. webs ...
- 帝国cms怎么调用栏目的别名呢?
在世界买家网新模板制作过程中,由于栏目名称比较长,用在标题上没有问题,对seo有利,但是在页面上不希望这么长,简单即可,提过提供了栏目别名,如果能调用就方便了, 请留意下面的修改方法 修改后栏目别名使 ...
- break continue 区别 以及实例
不论是MATLAB.c/c++.c#还是其他类型的编程语言,我们总是避免不了和for循环以及switch语句打交道,而对循环进行优化的时候,又总是避免不了用到break以及continue来控制循环, ...
- 基于Jenkins + Git的PHP项目编译脚本
本文针对的是了解或已经在使用Jenkins和Git的开发者或团队. 本团队使用了Jenkins作为持续集成平台,Git作为版本管理工具,而本人负责的项目是PHP项目,所谓发布项目就是复制文件. 通常有 ...
- Python开发入门与实战18-Windows Azure 虚拟机部署
18. 微软云虚拟机部署 上一章节我们介绍了如何在新浪云部署我们的在python django应用,本章我们来介绍如何Windows Azure上部署我们的应用. 18.1. 注册Windows Az ...
- Python的平凡之路(19)
一.Django请求生命周期 对于所有的web框架来说本质就是一个socket服务端,浏览器是socket客户端 ...
- Scrum领取任务
这次主要讨论了产品的构造流程,怎么将任务分配到个人,讨论什么功能具体怎么实现,然后各自选取了任务. 在团队项目“广商百货”的SCRUM项目中我认领的任务是对登录功能的实现.现在还没正式开始,还在看书和 ...
- 【搬砖】【Python数据分析】Pycharm中plot绘图不能显示出来
最近在看<Python数据分析>这本书,而自己写代码一直用的是Pycharm,在练习的时候就碰到了plot()绘图不能显示出来的问题.网上翻了一下找到知乎上一篇回答,试了一下好像不行,而且 ...
- dwr和spring的整合
1.dwr在spring配置文件的配置: <!-- 注意这里新增加的dwr tag, 为使其生效,文件头中要声明namespace --> <dwr:configuration /& ...
- NPOI 格式设置2—时间,千分位,繁体,小数位
在Excel中我们经常要设置格式,比如说日期格式(yyyymmdd).小数点格式(1.20).货币格式($2000).百分比格式(99.99%)等等,这些东西在过去我们恐怕只能在服务器端生成好,不但增 ...