LED驱动,自动创建设备节点 - 嵌入…
2014-01-26 16:01
295 查看
http://lttian1068.blog.163.com/blog/static/132150608200911863225866/?fromdm&isFromSearchEngine=yes
下面是我写的LED简单驱动代码,Arm平台(lpc3250)如下实现功能:
1>把代码编译后,添加到内核模块使LED灭10秒,然后亮10秒
2>在/dev目录自动挂载LED设备节点,可以“Echo "1"
>/dev/led”控制LED
3>再实现在开机自动运行,自动添加到内核中。当然是修改启动代码实现的。
4>最后我编译进内核中,下面我先把代码贴出来。
* @:0xf4028004和0xf4028008是GPIO端口3输出与输出寄存器虚拟地址
* 地址是我直接算出来的,可以用io_p2v()函数实现
* @: __raw_writel()向地址写数据
* @: class_create()创建总线,class_destroy()删除
* @:
device_create()创建设备节点,device_destroy()删除
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include
<linux/platform_device.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/irq.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include <mach/lpc32xx_gpio.h>
#define DEVNAME "LED"
#define LED_MAJOR 251
#define P3_SET ((volatile unsigned int) 0xf4028004)
#define P3_CLR ((volatile unsigned int) 0xf4028008)
struct led_dev
{
struct cdev cdev;
unsigned int value;
};
struct led_dev *led_dev;
int led_open(struct inode *inode, struct file *filp)
{
struct led_dev *dev;
dev
= container_of(inode->i_cdev, struct led_dev,
cdev);
filp->private_data
= dev;
try_module_get(THIS_MODULE);
return 0;
}
int led_release(struct inode *inode, struct file *filp)
{
module_put(THIS_MODULE);
return 0;
}
static int led_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
struct led_dev *dev =
filp->private_data;
if(copy_from_user(&(dev->value), buf
, 1))
{
return -EFAULT;
}
if(dev->value == 1)
__raw_writel(1
<< 5, P3_SET);
else
__raw_writel(1
<< 5, P3_CLR);
return 1;
}
int led_ioctl(struct inode *inode, struct file *filp, unsigned int
cmd, unsigned long arg)
{
struct led_dev *dev =
filp->private_data;
switch (cmd)
{
case 0:
dev->value
= 0;
__raw_writel(1
<< 5, P3_CLR);
break;
case 1:
dev->value
= 1;
__raw_writel(1
<< 5, P3_SET);
break;
default :
dev->value
= 1;
__raw_writel(1
<< 5, P3_SET);
break;
}
return 0;
}
struct file_operations led_fops =
{
.owner = THIS_MODULE,
.write = led_write,
.ioctl = led_ioctl,
.open = led_open,
.release = led_release,
};
static void led_setup_cdev(struct led_dev *dev, int index)
{
int err, devno = MKDEV(LED_MAJOR, 0);
cdev_init(&dev->cdev,
&led_fops);
dev->cdev.owner
= THIS_MODULE;
dev->cdev.ops
= &led_fops;
err
= cdev_add(&dev->cdev, devno,
1);
if(err)
printk(KERN_NOTICE
"Error adding LED");
}
struct class *led_class;
static int __init led_init(void)
{
int i,result;
dev_t
dev = MKDEV(LED_MAJOR, 0);
result
= register_chrdev_region(dev, 1, DEVNAME);
if(result < 0)
return result;
led_dev
= kmalloc(sizeof(struct led_dev), GFP_KERNEL);
if(!led_dev)
{
result
= ~ENOMEM;
goto fail;
}
memset(led_dev, 0, sizeof(struct led_dev));
led_setup_cdev(led_dev,
0);
led_class
= class_create(THIS_MODULE, "led_class");
device_create(led_class,
NULL, MKDEV(LED_MAJOR, 0), "LED","LED%d", 0);
__raw_writel(1
<< 5, P3_SET);
for(i = 0; i< 5; i++)
{
msleep(1000);
}
__raw_writel(1
<< 5, P3_CLR);
for(i = 0; i < 10; i++)
{
msleep(1000);
}
__raw_writel(1
<< 5, P3_SET);
return 0;
fail:
unregister_chrdev_region(dev,
1);
return result;
}
static void __exit led_exit(void)
{
cdev_del(&led_dev->cdev);
device_destroy(led_class,
MKDEV(LED_MAJOR, 0));
class_destroy(led_class);
kfree(led_dev);
unregister_chrdev_region(MKDEV(LED_MAJOR,
0), 1);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
内核模块在开机自动添加到内核中:
在/etc/rc.d/rc.local文件中,添加插入内核模块的命令就行了
insmod led.ko
内核模块编译进内核中,下面以LED驱动为例子:
第一:将您写的led.c 文档添加到/driver/mtd/maps/ 目录下。
第二:修改/driver/mtd/maps目录下的kconfig文档:
第三:修改该目录下makefile文档。
添加如下内容:obj-$(CONFIG_MTD_LED)
+= led.o
然后make menuconfig,在device
drivers该选项下面找到LED驱动模块,选中M直接编译成内核模块。
相关文章推荐
- 自动创建设备节点 ,手动创建…
- TQ2440 LINUX 2.6.30.4 LED驱动感言,从最初的打印字符,到自动分配设备号,到自动创建设备节点,到此设备号分控led
- Linux驱动开发之四-----LED改进测试(增加自动创建设备节点)
- TQ2440 LINUX 2.6.30.4 LED驱动感言,从最初的打印字符,到自动分配设备号,到自动创建设备节点,到次设备号分控led
- LED驱动,自动创建设备节点
- led驱动_自动创建设备节点
- linux字符设备驱动总结之:全自动创建设备及节点
- linux驱动入门之自动分配主设备号/创建设备节点
- 6410之驱动的一些优化(自动创建/dev设备节点)
- Linux设备驱动第四天(自动创建设备节点、LED驱动程序)
- Linux字符设备驱动自动创建设备节点
- Linux驱动开发--自动创建设备文件节点
- 驱动中使用class_device_create()报错的原因,自动创建设备节点
- 一步一步学习 Linux 驱动之自动创建设备节点
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- linux驱动开发之自动创建设备节点的方法
- Linux内核驱动自动创建设备节点文件
- linux字符驱动之自动创建设备节点
- Linux内核驱动自动创建设备节点文件
- Tiny6410_LED驱动程序_自动分配主设备号+手动创建设备节点