⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testdrv_led.c

📁 一个LED的简单驱动程序 与测试程序。
💻 C
字号:
#include <linux/module.h>

#if defined(CONFIG_SMP)
#define __SMP__
#endif

#if defined(CONFIG_MODVERSIONS)
#define MODVERSIONS
#include <linux/modversions.h>
#endif


#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/timer.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/immap_8260.h>
#include <asm/delay.h>
#include <linux/ioctl.h>

#define TEST_LEDDRV_MAJOR 150 
#define TEST_LED_NAME  "test_leddrv" 

MODULE_DESCRIPTION("Test led drvier");
MODULE_AUTHOR("grd");
MODULE_LICENSE("GPL");

#define LED_IOCTL_BASE	0xbb
#define LED_LIGHT		_IOR(LED_IOCTL_BASE, 1, unsigned long)
#define LED_UNLIGHT	_IOR(LED_IOCTL_BASE, 2, unsigned long)
#define LED_WINK		_IOR(LED_IOCTL_BASE, 3, unsigned long)

static ssize_t led_read(struct file *file, char *buf, size_t count,
			  loff_t * offset);
static ssize_t led_write(struct file *file, const char *buf,
			   size_t count, loff_t * offset);
static int led_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg);
static int led_open(struct inode *inode, struct file *file);
static int led_release(struct inode *inode, struct file *file);

static struct file_operations led_fops = {
      read:led_read,
      write:led_write,
      ioctl:led_ioctl,
      open:led_open,
      release:led_release,
      owner:THIS_MODULE,
};

static int led_open(struct inode *inode, struct file *file)
{
  volatile immap_t *immr = (immap_t *) IMAP_ADDR;
  
  immr->im_ioport.iop_pparc  &=  ~0x00000020;    // GPIO pin
  immr->im_ioport.iop_pdirc  |=   0x00000020;     // output	
  
	printk(KERN_INFO "Led opening...\n");
	MOD_INC_USE_COUNT;
	return 0;
}

static int led_release(struct inode *inode, struct file *file)
{
	MOD_DEC_USE_COUNT;
	printk(KERN_INFO "Led closing...\n");
	return 0;
}

static ssize_t led_read(struct file *file, char *buf, size_t count,
			  loff_t * offset)
{
  return 0;
}

static ssize_t led_write(struct file *file, const char *buf,
			   size_t count, loff_t * offset)
{
	return 0;
}

static int led_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	if (_IOC_TYPE(cmd) != LED_IOCTL_BASE)
	{
		return -ENOTTY;
	}
	switch(cmd)
  {
	  case LED_LIGHT:
      if((immr->im_ioport.iop_pdatc & 0x00000020) == 0x0)
        immr->im_ioport.iop_pdatc  |= 0x00000020; //high
		  break;
	  case LED_UNLIGHT:
      if((immr->im_ioport.iop_pdatc & 0x00000020) == 0x020)
        immr->im_ioport.iop_pdatc  &= ~0x00000020; //low
		  break;
	  case LED_WINK:
      if((immr->im_ioport.iop_pdatc & 0x00000020) == 0x020)
          immr->im_ioport.iop_pdatc  &= ~0x00000020; //low
      else
          immr->im_ioport.iop_pdatc  |= 0x00000020; //high
		  break;
    default:
        printk("\narg2 ERROR ");
  }
  return 0;
}

int led_init(void)
{
	int result;
	printk(KERN_INFO"Led initing... ");
	result=register_chrdev(TEST_LEDDRV_MAJOR,TEST_LED_NAME,&led_fops);
	if(result<0)
	{
		printk(KERN_INFO"Led: Couldn't register led driver\n");
		goto fail;
	}
	return result;
	fail:
		printk(KERN_INFO"Sorry to say that:led device register failed");
		return -EBUSY;
}

void led_cleanup(void)
{
	unregister_chrdev(TEST_LEDDRV_MAJOR, TEST_LED_NAME);
	printk(KERN_INFO"Led unloading...");
}

module_init(led_init);
module_exit(led_cleanup);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -