比原来的好,结构体指针指向更细致了 还涉及内存管理,留下有时间好好学习研究一下
转自:
http://blog.sina.com.cn/s/blog_5f8665e70100pjtz.html
这段是mini2440的led Linux驱动程序代码
- #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 <linux/interrupt.h>
-
#include <asm/uaccess.h>
-
#include <mach/regs-gpio.h>
-
#include <mach/hardware.h>
-
#include <linux/platform_device.h>
-
#include <linux/cdev.h>
-
#include <linux/miscdevice.h>
-
#include <linux/sched.h>
-
#include <linux/gpio.h>
-
#include <linux/slab.h>
-
#define LED_MAJOR 0
-
#define LED_ON 1
-
#define LED_OFF 0
-
struct led_dev {
-
struct cdev cdev;
-
unsigned char value;
-
};
-
struct led_dev *led_devp;
-
static unsigned long led_table [] = {
-
S3C2410_GPB(5),
-
S3C2410_GPB(6),
-
S3C2410_GPB(7),
-
S3C2410_GPB(8),
-
};
-
static unsigned int led_cfg_table [] = {
-
S3C2410_GPIO_OUTPUT,
-
S3C2410_GPIO_OUTPUT,
-
S3C2410_GPIO_OUTPUT,
-
S3C2410_GPIO_OUTPUT,
-
};
-
int led_major = LED_MAJOR;
-
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;
-
-
return 0;
-
}
-
int led_release(struct inode *inode, struct file *filp)
-
{
-
return 0;
-
}
-
ssize_t led_read(struct file *filp, char __user *buff, size_t count, loff_t *f_pos)
-
{
-
struct led_dev *dev = filp->private_data;
-
-
if(copy_to_user(buff, &(dev->value), 1))
-
return -EFAULT;
-
-
return 1;
-
}
-
ssize_t led_write(struct file *filp, const char __user *buff, size_t count, loff_t *f_pos)
-
{
-
struct led_dev *dev = filp->private_data;
-
if(copy_from_user(&(dev->value), buff, 1))
-
return -EFAULT;
-
if(dev->value == 1)
-
s3c2410_gpio_setpin(led_table[1], 0);
-
else
-
s3c2410_gpio_setpin(led_table[1], 1);
-
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 LED_ON:
-
dev->value = 1;
-
s3c2410_gpio_setpin(led_table[arg], 0);
-
break;
-
case LED_OFF:
-
dev->value = 0;
-
s3c2410_gpio_setpin(led_table[arg], 1);
-
break;
-
default:
-
return -ENOTTY;
-
}
-
-
return 0;
-
}
-
struct file_operations led_fops = {
-
.owner = THIS_MODULE,
-
.read = led_read,
-
.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, index);
-
-
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 %d adding LED %d\n", err, index);
-
}
-
int led_init(void)
-
{
-
int result;
-
int i;
-
for (i = 0; i < 4; i++) {
-
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
-
s3c2410_gpio_setpin(led_table[i], 0);
-
}
-
dev_t dev = MKDEV(led_major, 0);
-
-
if(led_major)
-
result = register_chrdev_region(dev, 1, "leds");
-
else {
-
result = alloc_chrdev_region(&dev, 0, 1, "leds");
-
led_major = MAJOR(dev);
-
}
-
if(result < 0)
-
return result;
-
led_devp = kmalloc(sizeof(struct led_dev), GFP_KERNEL);
-
if(!led_devp) {
-
result = -ENOMEM;
-
goto fail_malloc;
-
}
-
memset(led_devp, 0, sizeof(struct led_dev));
-
led_setup_cdev(led_devp, 0);
-
return 0;
-
fail_malloc:
-
unregister_chrdev_region(dev, 1);
-
return result;
-
}
-
void led_exit(void)
-
{
-
cdev_del(&led_devp->cdev);
-
kfree(led_devp);
-
unregister_chrdev_region(MKDEV(led_major, 0), 1);
-
}
-
module_init(led_init);
-
module_exit(led_exit);
-
MODULE_AUTHOR("Jackie");
-
MODULE_LICENSE("Dual BSD/GPL");
============================================================================================
以下是测试程序:
- #include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <sys/ioctl.h>
-
int main(int argc, char **argv)
-
{
-
int on;
-
int led_no;
-
int fd;
-
if(argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2], "%d", &on) != 1
-
|| on < 0 || on >1 || led_no < 0 || led_no >3) {
-
fprintf(stderr, "Usage: leds led_no 0|1\n");
-
exit(1);
-
}
-
fd = open("/dev/leds0", 0);
-
if(fd < 0) {
-
fd = open("/dev/leds", 0);
-
}
-
if(fd < 0) {
-
perror("open device leds");
-
exit(1);
-
}
-
ioctl(fd, on, led_no);
-
close(fd);
-
return 0;
-
}
阅读(1174) | 评论(0) | 转发(0) |