linux驱动之LED驱动_1
2014-12-19 16:25
246 查看
步骤:
1、框架
2、完善硬件的操作:
a.看原理图、引脚
b.看2440手册
c.写代码: IO口需要用ioremap映射
我的板子电路如下所示
1、配置GPBCON 寄存器,配置输出 在open函数中去配置
2、配置GPBDAT 寄存器 在write函数中去配置
#########################################################################
手册资料:
GPBCON 寄存器的物理地址为:0x56000010
GPBDAT 寄存器的物理地址为:0x56000014
#########################################################################
1、首先声明全局变量:
2、在入口函数中对引脚进行映射
4、在open函数中将引脚设置为输出
5、在写函数中对用户空间数据进行简单处理
完整的驱动代码如下:
完整的测试代码如下:
1、框架
2、完善硬件的操作:
a.看原理图、引脚
b.看2440手册
c.写代码: IO口需要用ioremap映射
我的板子电路如下所示
1、配置GPBCON 寄存器,配置输出 在open函数中去配置
2、配置GPBDAT 寄存器 在write函数中去配置
#########################################################################
手册资料:
GPBCON 寄存器的物理地址为:0x56000010
GPBDAT 寄存器的物理地址为:0x56000014
#########################################################################
1、首先声明全局变量:
volatile unsigned long *gpbcon = NULL; volatile unsigned long *gpbdat = NULL;
2、在入口函数中对引脚进行映射
/*映射物理地址*/ gpbcon = (volatile unsigned long *) ioremap(0x56000010,16); gpbdat = gpbcon + 1;3、在出口函数中取消映射
iounmap(gpbcon);
4、在open函数中将引脚设置为输出
/*配置 GPB 5 6 7 8为输出*/ *gpbcon &=~((0x3<<(5*2))|(0x3<<(6*2))|(0x3<<(7*2))|(0x3<<(8*2)));//先清零 *gpbcon |=((0x1<<(5*2))|(0x1<<(6*2))|(0x1<<(7*2))|(0x1<<(8*2)));// 配置为1 (输出)
5、在写函数中对用户空间数据进行简单处理
int val; copy_from_user(&val,buf,count);//从用户空间向内核空间拷贝数据 if(val == 1) { //点灯 *gpbdat &=~((1<<5)|(1<<6)|(1<<7)|(1<<8)); } else { //灭灯 *gpbdat|=(1<<5)|(1<<6)|(1<<7)|(1<<8); }
完整的驱动代码如下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h>
static struct class *firstdrv_class;
static struct class_devices *firstdrv_class_dev;
volatile unsigned long *gpbcon = NULL; volatile unsigned long *gpbdat = NULL;
MODULE_LICENSE("Dual BSD/GPL");
static int first_dev_open(struct inode *inode,struct file *file)
{
/*配置 GPB 5 6 7 8为输出*/
*gpbcon &=~((0x3<<(5*2))|(0x3<<(6*2))|(0x3<<(7*2))|(0x3<<(8*2)));//先清零
*gpbcon |=((0x1<<(5*2))|(0x1<<(6*2))|(0x1<<(7*2))|(0x1<<(8*2)));// 配置为1 (输出)
//printk("first dev open\n");
return 0;
}
static ssize_t first_dev_write(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
int val;
copy_from_user(&val,buf,count);//从用户空间向内核空间拷贝数据
if(val == 1)
{
//点灯
*gpbdat &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));
}
else
{
//灭灯
*gpbdat|=(1<<5)|(1<<6)|(1<<7)|(1<<8);
}
//printk("first dev write\n");
return 0;
}
static struct file_operations first_sdv_fops =
{
.owner = THIS_MODULE,
.open = first_dev_open,
.write = first_dev_write,
};
int major;
int first_drv_init(void)
{
major = register_chrdev(0,"first_drv",&first_sdv_fops);//注册
firstdrv_class = class_create(THIS_MODULE,"first_drv");
if(IS_ERR(firstdrv_class))
return PTR_ERR(firstdrv_class);
firstdrv_class_dev = device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"wq_device");
if(unlikely(IS_ERR(firstdrv_class_dev)))
return PTR_ERR(firstdrv_class_dev);
/*映射物理地址*/ gpbcon = (volatile unsigned long *) ioremap(0x56000010,16); gpbdat = gpbcon + 1;
//printk("init major= %d\n",major);
return 0;
}
void first_dev_exit(void)
{
//printk("exit\n");
unregister_chrdev(major,"first_drv");//卸载
device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);
iounmap(gpbcon);
}
module_init(first_drv_init);
module_exit(first_dev_exit);
完整的测试代码如下:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> /*wq_device on 打开 *wq_device off 关闭 */ int main(int argc, char **argv) { int fd; int val = 1; fd = open("/dev/wq_device", O_RDWR); if(fd < 0) { printf("can't open \n"); } if(argc != 2) { printf("Usage :\n"); printf("%s <on|off>\n",argv[0]); return 0; } if(strcmp(argv[1],"on") == 0) { val =1; } else { val =0; } write(fd,&val,4); return 0; }
相关文章推荐
- ARM+Linux驱动----点亮开发板的LED
- Linux驱动开发之S3C2440按键点亮LED
- “手把手教你学linux驱动开发”OK6410系列之02---LED字符设备驱动 .
- 【转】嵌入式Linux之我行——LED驱动在2440上的实例开发
- linux设备驱动之led子系统<一>
- LED灯显示字符驱动程序-linux2.6LED显示驱动
- 特别详细好懂的一篇文章:s3c2440 -linux-LED驱动
- 嵌入式Linux字符设备入门之--LED驱动详解
- linux驱动学习笔记(S3C2440的LED驱动)
- s3c2440基于linux的gpio led字符设备驱动实践
- s3c2440基于linux的gpio led字符设备驱动实践 [转]
- Linux嵌入式驱动初体验(六)--- LED驱动测试程序
- linux led驱动详解【转】
- s3c2440基于linux的button和led字符设备驱动
- Linux驱动开发之S3C2440按键点亮LED
- LED灯显示字符驱动程序-linux2.6LED显示驱动
- linux驱动之--led驱动
- 慢慢学Linux驱动开发,第九篇,tiny6410_LED驱动
- arm+linux完整Led驱动
- 和菜鸟一起学linux:第六篇:将LED驱动编译到内核