📄 testdrv_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 + -