一个简单的LED驱动-不基于驱动框架

驱动:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/ioport.h>

#include <asm/uaccess.h>
#include <asm/io.h>

static int led_major = -1;
static struct class * led_Mark_class = NULL;
static struct device * led_Mark_device = NULL;
static struct resource * res_mark = NULL;
#define GPJ0CON (0xE0200240)
#define GPJ0DAT (0xE0200244)

typedef struct P_DATA_MARK
{
unsigned int con;
unsigned int dat;
}P_DATA_MARK;

unsigned int * p_data_test = NULL;
unsigned int * p_data_data = NULL;

static P_DATA_MARK * p_data_mark = NULL;
static char buf[4] = {0};

static int led_mark_open (struct inode * inode, struct file * file)
{
p_data_mark->con |= ((1<<12) | (1<<16) | (1<<20));
return 0;
}

static int led_mark_close (struct inode * inode, struct file * file)
{
p_data_mark->con &= ~((1<<12) | (1<<16) | (1<<20));
return 0;
}

static ssize_t led_mark_write(struct file * file, const char __user * in,
size_t size, loff_t * off)
{
int ret = 0;
ret = copy_from_user(buf, in, size);
if (ret)
{
printk(KERN_ERR “led_mark_write use\n”);
return -EBUSY;
}
// printk(KERN_ERR “buf = %s\n”, buf);
if (‘0’ == buf[0])
{
printk(KERN_ERR “off\n”);
p_data_mark->dat |= ((1<<3) | (1<<4) | (1<<5));
}
else
{
printk(KERN_ERR “on\n”);
p_data_mark->dat &= ~((1<<3) | (1<<4) | (1<<5));
}
return 0;
}

static struct file_operations led_operations_mark =
{
.owner = THIS_MODULE,
.open = led_mark_open,
.release = led_mark_close,
.write = led_mark_write,
};

static int __init s5pv210_led_init(void)
{
led_major = register_chrdev(0, “led_driver”, &led_operations_mark);
if (led_major < 0)
{
printk(KERN_ERR “register_chrdev\n”);
goto err_register_chrdev;
}
led_Mark_class = class_create(THIS_MODULE, “LED_MARK”);
if (!led_Mark_class)
{
printk(KERN_ERR “class_create error\n”);
goto err_class_create;
}
led_Mark_device = device_create(led_Mark_class,
NULL, MKDEV(led_major, 0), NULL, “LED-MARK”);
if (!led_Mark_device)
{
printk(KERN_ERR “device_create error\n”);
goto err_device_create;
}

res_mark = request_mem_region(GPJ0CON, sizeof(P_DATA_MARK), "p_data");
if (!res_mark)
{
	printk(KERN_ERR "request_mem_region error\n");
	goto err_request_mem_region;
}
p_data_mark = ioremap(GPJ0CON, sizeof(P_DATA_MARK));
if (!p_data_mark)
{
	printk(KERN_ERR "ioremap error\n");
	goto err_ioremap;
}
printk(KERN_ERR "%p \n", p_data_mark);
p_data_mark->con |= ((1<<12) | (1<<16) | (1<<20));
p_data_mark->dat &= ~((1<<3) | (1<<4) | (1<<5));
	
return 0;

err_ioremap:
release_mem_region(GPJ0CON, sizeof(P_DATA_MARK));
err_request_mem_region:
device_destroy(led_Mark_class, MKDEV(led_major, 0));
err_device_create:
class_destroy(led_Mark_class);
err_class_create:
unregister_chrdev(led_major, “led_driver”);
err_register_chrdev:
return -1;
}

static void __exit s5pv210_led_exit(void)
{
p_data_mark->dat |= ((1<<3) | (1<<4) | (1<<5));
p_data_mark->con &= ~((1<<12) | (1<<16) | (1<<20));
iounmap(p_data_test);
release_mem_region(GPJ0CON, sizeof(P_DATA_MARK));
device_destroy(led_Mark_class, MKDEV(led_major, 0));
class_destroy(led_Mark_class);
unregister_chrdev(led_major, “led_driver”);
}

module_init(s5pv210_led_init);
module_exit(s5pv210_led_exit);

// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE(“GPL”); // 描述模块的许可证
MODULE_AUTHOR(“Mark 867439374@qq.com”); // 描述模块的作者
MODULE_DESCRIPTION(“s5pv210 led driver”); // 描述模块的介绍信息
MODULE_ALIAS(“s5pv210_led”); // 描述模块的别名信息


应用程序:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define PATHNAME “/dev/LED-MARK”

int main(void)
{
int fd = -1;
fd = open(PATHNAME, O_RDWR);
if (fd < 0)
{
perror("");
return -1;
}
write(fd, “1”, 1);
sleep(1);
write(fd, “0”, 1);
sleep(1);
write(fd, “1”, 1);
sleep(1);
write(fd, “0”, 1);
sleep(1);
close(fd);
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值