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

📄 led_module.c

📁 LINUX+9200基础实验 :点亮板子上的LED 驱动程序部分led_module.c 说明:程序默认PBO,PB1,PB2,PB3接LED灯,主设备号43,可根据实际情况修改参数.
💻 C
字号:
/***********************************************************************
 * www.csugds.cn
 ***********************************************************************/
#include <linux/kernel.h>	/* 	*/
#include <linux/module.h>	/* Specifically, a module	*/
#include <linux/init.h>		/* for __initfunc		*/
#include <asm/uaccess.h>	/* for put_user			*/
#include <asm/io.h>        	/* for ioremap                  */
#include <asm/arch/hardware.h>	/* atmel RM9200           	*/      
#include <asm/arch/pio.h>

#define	DEBUG   1
#ifdef	DEBUG
# define debugk(fmt,args...)	printk(fmt ,##args)
#else
# define debugk(fmt,args...)
#endif

#if CONFIG_MODVERSIONS==1
/* # define MODVERSIONS */
# include <linux/modversions.h>
#endif

MODULE_LICENSE("GPL");
/*
 * For character devices
 */
#include <linux/fs.h>		/* character device definitions	*/
#include <linux/wrapper.h>	/* wrapper for compatibility with future versions */
#ifndef KERNEL_VERSION
# define KERNEL_VERSION(a,b,c)	((a)*65536+(b)*256+(c))
#endif
#define 	SUCCESS 	0
#define		LED_MAJOR	43	/* 定义主设备号	*/
/* 根据板子的具体情况设置 */
#define  	SYS_LED 	AT91C_PIO_PB0 
#define		ACT_LED		AT91C_PIO_PB1
#define 	TEL_LED		AT91C_PIO_PB2
#define		PCM_LED		AT91C_PIO_PB3
#define 	DEVICE_NAME	 "sys_led"

AT91PS_SYS va_sys = (AT91PS_SYS) AT91C_VA_BASE_SYS;
static int Device_Open = 0;
static int __init led_init (void );
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);

struct file_operations led_ops = 
{
    read:       	device_read,
    write:      	device_write,
    open:       	device_open,
    release:    	device_release,
};
static int Major;
static int __init led_init(void)
{
	va_sys -> PMC_PCER = (1 << AT91C_ID_PIOB);  
	va_sys -> PIOB_PER = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
	va_sys -> PIOB_OER = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
	va_sys -> PIOB_PPUDR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
	va_sys -> PIOB_OWDR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
    va_sys -> PIOB_CODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;

	 Major = register_chrdev (LED_MAJOR, DEVICE_NAME, &led_ops);
	/* Negative values signify an error */
	if (Major < 0) 
	{
		printk ("SYS_LED init_module: failed with %d\n", Major);
		return Major;
	}
	Major = LED_MAJOR;
	debugk ("SYS_LED registred: major = %d\n", Major);
	return 0;
}

static int device_open (struct inode *inode, struct file *file)
{
	debugk ("device_open(%p,%p)\n", inode, file);
	debugk ("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
	if (Device_Open) 
	{
		return -EBUSY;
	}
	Device_Open++;
	MOD_INC_USE_COUNT;
	return SUCCESS;
}

static int device_release (struct inode *inode, struct file *file)
{
	
	debugk ("device_release(%p,%p)\n", inode, file);
	Device_Open--;
	MOD_DEC_USE_COUNT;

	va_sys -> PIOB_SODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;

	return 0;
}

static ssize_t device_read (struct file *file,
			    char *buffer,	/* The buffer to fill with data */
			    size_t length,	/* The length of the buffer */
			    loff_t * offset)	/* Our offset in the file */
{
	unsigned int i;

 	i = va_sys -> PIOB_ODSR;
    i &= SYS_LED;
    i &= ACT_LED;
    i &= TEL_LED;
    i &= PCM_LED;

	copy_to_user (buffer, (void *) &i, 4);
	debugk ("Read: value = 0x%08X\n", i);
	return (4);		/* read() always returns exactly 4 bytes */
}

static ssize_t device_write (struct file *file,
			     const char *buffer,	/* buffer */
			     size_t length,		/* length of buffer */
			     loff_t * offset)		/* offset in the file */
{
	int 	i;
	int  	err;        
	if(length > 4)
		return -9;

	err = copy_from_user ( (void *) &i, buffer, length);

 	if (i=0xffffffff)
    {
		va_sys -> PIOB_SODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
    }
    else
    {
    	va_sys -> PIOB_CODR = AT91C_PIO_PB4|AT91C_PIO_PB5|AT91C_PIO_PB6|AT91C_PIO_PB7;
    }

	debugk ("Write: value = 0x%08X\n", i);
 	return (length);
}

/******************************
 **** Module Declarations *****
 **************************** */

#ifdef MODULE
static void __exit cleanup_led_module (void)
{
	int ret;
	ret = unregister_chrdev (Major, DEVICE_NAME);
	if (ret < 0) {
		printk ("unregister_chrdev: error %d\n", ret);
	}
}

module_init(led_init);
module_exit(cleanup_led_module);

MODULE_AUTHOR("Wang longfeng");
MODULE_DESCRIPTION("led driver for AT9200");
 
#endif	/* MODULE */

⌨️ 快捷键说明

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