📄 led_ioctl.c
字号:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/arch/hardware.h>
#include <asm/arch/at91sam9260.h>
#include "led_drv.h"
int led_open(struct inode *inode, struct file *file);
int led_release(struct inode *inode, struct file *file);
ssize_t led_read(struct file *filep, char *buffer, size_t length, loff_t *offset);
ssize_t led_write(struct file *filep, char *buffer, size_t len, loff_t *offset);
int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned int arg);
struct file_operations fops =
{
.read = led_read,
.write = led_write,
.open = led_open,
.ioctl = led_ioctl,
.release = led_release
};
int major_no;
char *msg_ptr;
char msg[20];
int init_module(void)
{
printk(KERN_INFO "hello LED driver\n");
if((major_no = register_chrdev(0, "LED", &fops)) < 0)
{
printk(KERN_INFO "Error \n");
}
else
{
printk(KERN_INFO "create device node by executing:\n");
printk(KERN_INFO "mknod /dev/LED c %d 0\n", major_no);
}
return 0;
}
void cleanup_module(void)
{
int ret;
printk(KERN_INFO "bye \n");
if((ret = unregister_chrdev(major_no, "LED")) < 0)
{
printk(KERN_INFO "Error\n");
}
}
#define PIOA_OER (AT91_PIOA + 0x10)
#define PIOA_SODR (AT91_PIOA + 0x30)
#define PIOA_CODR (AT91_PIOA + 0x34)
int led_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Open called\n");
at91_sys_write(PIOA_OER, 0xFC0);
msg_ptr = msg;
return 0;
}
int led_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Close called\n");
kfree(msg_ptr);
return 0;
}
ssize_t led_read(struct file *filep, char *buffer, size_t length, loff_t *offset)
{
if(__copy_to_user(buffer, "heLLO", 5) > 0)
{
printk(KERN_INFO "fail\n");
}
else
{
printk(KERN_INFO "Read not supported");
}
return 0;
}
ssize_t led_write(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
int err = 0;
printk(KERN_INFO "write called\n");
err = access_ok(VERIFY_WRITE, buffer, len);
if(err)
{
if(__copy_from_user(msg_ptr, buffer, len) > 0)
{
printk(KERN_INFO "fail\n");
return -EFAULT;
}
else
{
printk(KERN_INFO "success %s\n", msg_ptr);
}
}
else
{
printk(KERN_INFO "user space pointer not good \n");
}
return 0;
}
int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned int arg)
{
switch(cmd)
{
case LEDON_WDATA:
{
printk(KERN_INFO "IOCTL_LEDON = 0x%x \n", arg);
at91_sys_write(PIOA_SODR, arg);
}
break;
case LEDOFF_WDATA:
{
printk(KERN_INFO "IOCTL_LEDOFF = 0x%x \n", arg);
at91_sys_write(PIOA_CODR, arg);
}
break;
default:
printk(KERN_INFO "Invalid IOCTL command \n");
return -EFAULT;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -