微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 基于mini2440的LED灯的驱动程序

基于mini2440的LED灯的驱动程序

时间:10-02 整理:3721RD 点击:

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/cdev.h>
#include <linux/mm.h>

#define DEVICE_NAME "miniled"
#define LED_MAJOR 254

static int led_major = LED_MAJOR;

struct mini_led_dev
{
struct cdev cdev;

};

struct mini_led_dev *devp;

static unsigned long mini_led_table[] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};

static unsigned long mini_led_cfg_table[] = {
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};


int led_on(int arg)
{
s3c2410_gpio_setpin(mini_led_table[arg], 0);
return 0;
}

int led_off(int arg)
{
s3c2410_gpio_setpin(mini_led_table[arg], 1);
return 0;
}

static int mini_led_ioctl(struct inode *inode, structfile *file,
      unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
  case 0:
   led_off(arg);
   break;
  case 1:
   led_on(arg);
   break;
  default:
   return -1;
}
}

static int mini_led_open(struct inode *inode, struct file*filp)
{
struct mini_led_dev *devp;

devp = container_of(inode->i_cdev, struct mini_led_dev,cdev);
filp->private_data = devp;

return 0;
}

static int mini_led_release(struct inode *inode, structfile *filp)
{
return 0;
}

static struct file_operations mini_led_fops = {
.owner = THIS_MODULE,
.ioctl = mini_led_ioctl,
.open = mini_led_open,
.release = mini_led_release,
};

static void led_setup_cdev(struct mini_led_dev *dev, intindex)
{    (借助结构体成员名初始化结构体)
int err;
int devno = MKDEV(led_major, index);

cdev_init(&dev->cdev, &mini_led_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &mini_led_fops;
err = cdev_add(&dev->cdev, devno, 1);

if (err)
{
  printk(KERN_NOTICE "Error %d adding led %d", err, index);
}
}

int mini_led_init(void)(模块加载函数)
{
int result;
int i;

dev_t devno = MKDEV(led_major, 0);
if (led_major)
{
  result = register_chrdev_region(devno, 0, DEVICE_NAME);
}
else
{
  result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);
}
if (result < 0)
{
  return result;
}

devp = kmalloc(sizeof(struct mini_led_dev),GFP_KERNEL);
if (! devp)
{
  result = -1;
  goto fail_malloc;
}

for (i = 0; i < 4; i++)
{
  s3c2410_gpio_cfgpin(mini_led_table, mini_led_cfg_table);
  s3c2410_gpio_setpin(mini_led_table, 1);
}
memset(devp, 0, sizeof(struct mini_led_dev));

led_setup_cdev(devp, 0);

return 0;

fail_malloc:
  unregister_chrdev_region(devno, 1);
  return result;

}

void mini_led_exit(void)
{
cdev_del(&devp->cdev);
kfree(devp);
unregister_chrdev_region(MKDEV(led_major, 0), 1);
}

MODULE_AUTHOR("more&high");
MODULE_LICENSE("Dual BSD/GPL");

module_init(mini_led_init);
module_exit(mini_led_exit);

以下是Makefile:

obj-m := led.o

KDIR := /opt/friendlyarm/mini2440/kernel-2.6.13

PWD := $(shell pwd)

CC = arm-linux-gcc

default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
rm -rf *.o
rm -rf *.ko
rm -rf .*.cmd
rm -rf *.mod.*

make

成功

mknod /dev/testled c 254 0

insmod led.ko

以下是应用程序

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main()
{
int fd;
int num;
int ope;

fd = open("/dev/testled", 0);
if (fd < 0)
{
  perror("open miniled fail");
  exit(1);
}
for ( num = 0; num < 4; num++)
{
  ioctl(fd, 0, num);
}
printf("please print the led num\n");
scanf("%d", &num);
printf("please print the operation\n");
scanf("%d", &ope);
ioctl(fd, ope, num);

close(fd);

return 0;

}


lammbo-fly谢谢小编分享

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top