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

📄 led_ioctl.c

📁 Linux device driver sample code
💻 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 + -