#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#define DEVICE_NAME "leds"
#define GPIOCFG1 (*(volatile unsigned long*) 0xbfd010C4)
#define GPIOOE1 (*(volatile unsigned long*)0xbfd010D4)
#define GPIOOUT1 (*(volatile unsigned long*)0xbfd010F4)
static struct led_dev {
dev_t devno;
struct cdev cdev;
};
struct led_dev *leds = NULL;
static int leds_open(struct inode *inode, struct file *file)
{
printk(KERN_WARNING "open led linght\n");
GPIOCFG1 |= 0x000000C0;
GPIOOE1 &= ~(0x000000C0);
GPIOOUT1 &= ~(0x000000C0);
return 0;
}
/*static int leds_close(struct inode *inode, struct file *file)
{
printk(KERN_WARNING "close\n");
return 0;
}*/
static int leds_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = leds_open,
.unlocked_ioctl = leds_ioctl,
/* .release = leds_close,*/
};
static int __init dev_init(void)/*驱动的初始化*/
{
int ret;
dev_t devno=MKDEV(252,0);
ret = register_chrdev_region(devno,1,"leds");/*静态注册设备号*/
if(ret < 0){
printk(KERN_WARNING "leds:can't get major.\n");
goto fail;
}
leds = kmalloc(sizeof(struct led_dev), GFP_KERNEL); /*设备节点分配内存空间*/
if(!leds){
ret = -ENOMEM;
goto fail;
}
memset(leds, 0, sizeof(struct led_dev));
leds->devno = devno;
cdev_init(&leds->cdev, &dev_fops);/*关联操作集*/
leds->cdev.owner = THIS_MODULE;
ret = cdev_add(&leds->cdev, devno, 1);/*将设备加入到系统中*/
if(ret){
printk(KERN_NOTICE "Error %d.\n", ret);
goto fail;
}
printk ("led driver initialized.\n");
return 0;
fail:
if(devno != 0){
unregister_chrdev_region(&devno, 1);
}
if(leds){
kfree(leds);
}
return ret;
}
static void __exit dev_exit(void)/*释放设备节点*/
{
dev_t devno = leds->devno;
cdev_del(&leds->cdev);
if(leds){
kfree(leds);
}
unregister_chrdev_region(devno, 1);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
字符设备驱动之led灯的控制实验
最新推荐文章于 2023-05-08 22:03:04 发布
本文深入探讨了Linux设备驱动开发的全过程,从初始化到退出,包括注册设备、内存分配、设备节点创建、文件操作集关联及设备添加到系统中等关键步骤。详细展示了如何通过宏定义和函数实现GPIO配置、打开和关闭LED灯的功能。
摘要由CSDN通过智能技术生成