驱动程序
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/slab.h>
struct s5pv210_led_dev{
unsigned int major;
struct device * led_dev;
struct class * led_class;
volatile unsigned long * GPC0_CON;
volatile unsigned long * GPC0_DAT;
};
struct s5pv210_led_dev * s5pv210_dev;
int led_open (struct inode * node, struct file * filp)
{
printk("----------%s------------\n",__FUNCTION__);
return 0;
}
int led_release (struct inode *node, struct file * filp)
{
printk("----------%s------------\n",__FUNCTION__);
return 0;
}
ssize_t led_write(struct file * filp, const char __user * buff, size_t count, loff_t * offset)
{
ssize_t ret;
int led_cmd;
unsigned int value;
printk("----------%s------------\n",__FUNCTION__);
ret = copy_from_user(&led_cmd, buff, count);
if(ret > 0)
{
printk("copy_from_user error\n");
return ret;
}
if(led_cmd == 0)
{
value = __raw_readl(s5pv210_dev->GPC0_DAT);
value &= ~(0x03 << 3);
__raw_writel(value, s5pv210_dev->GPC0_DAT);
}
else
{
value = __raw_readl(s5pv210_dev->GPC0_DAT);
value |= (0x03 << 3);
__raw_writel(value, s5pv210_dev->GPC0_DAT);
}
return 0;
}
const struct file_operations fops ={
.owner = THIS_MODULE,
.open = led_open,
.write = led_write,
.release = led_release,
};
static int __init drv_led_init(void)
{
int ret;
unsigned int value;
s5pv210_dev = (struct s5pv210_led_dev *)kzalloc(sizeof(struct s5pv210_led_dev), GFP_KERNEL);
if(s5pv210_dev == NULL)
{
printk("kzalloc error\n");
return -ENOMEM;
}
s5pv210_dev->major = register_chrdev(0, "drv_led", &fops);
if(s5pv210_dev->major < 0)
{
printk("register_chrdev error\n");
ret = s5pv210_dev->major;
goto err_register_chrdev;
}
s5pv210_dev->led_class = class_create(THIS_MODULE, "led_class");
if(IS_ERR(s5pv210_dev->led_class))
{
printk("class_create error\n");
ret = PTR_ERR(s5pv210_dev->led_class);
goto err_class_create;
}
s5pv210_dev->led_dev = device_create(s5pv210_dev->led_class, NULL, MKDEV(s5pv210_dev->major, 0), NULL, "drv_led");
if(IS_ERR(s5pv210_dev->led_dev))
{
printk("device_create error\n");
ret = PTR_ERR(s5pv210_dev->led_dev);
goto err_device_create;
}
s5pv210_dev->GPC0_CON = ioremap(0xE0200060,8);
s5pv210_dev->GPC0_DAT = s5pv210_dev->GPC0_CON + 1;
value = __raw_readl(s5pv210_dev->GPC0_CON);
value &= ~(0xff << 12);
value |= (0x11 << 12);
__raw_writel(value, s5pv210_dev->GPC0_CON);
value = __raw_readl(s5pv210_dev->GPC0_DAT);
value &= ~(0x03 << 3);
__raw_writel(value, s5pv210_dev->GPC0_DAT);
return 0;
err_device_create:
class_destroy(s5pv210_dev->led_class);
err_class_create:
unregister_chrdev(s5pv210_dev->major, "drv_led");
err_register_chrdev:
kfree(s5pv210_dev);
return ret;
}
static void __exit drv_led_exit(void)
{
iounmap(s5pv210_dev->GPC0_CON);
device_destroy(s5pv210_dev->led_class, MKDEV(s5pv210_dev->major, 0));
class_destroy(s5pv210_dev->led_class);
unregister_chrdev(s5pv210_dev->major, "drv_led");
kfree(s5pv210_dev);
}
module_init(drv_led_init);
module_exit(drv_led_exit);
MODULE_LICENSE("GPL");
应用程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd;
int on;
int count = 5;
fd = open("/dev/drv_led",O_RDWR);
if(fd < 0)
{
perror("open");
exit(1);
}
while(count--)
{
on = 1;
write(fd, &on, sizeof(on));
sleep(2);
on = 0;
write(fd, &on, sizeof(on));
sleep(2);
}
close(fd);
return 0;
}