¡¾ÇóÖú¡¿Çë½ÌÒ»¸öÇý¶¯º¯ÊýÈë¿ÚµÄÎÊÌâ
[color=#555555]¸÷λÐֵܰïæ£¡ÒÔÏÂÊÇÎÒ×Ô¼ºÐ´µÄÒ»¸öÇý¶¯³ÌÐòµÄ.cÎļþ£¬open¡¢close¡¢read3¸öº¯ÊýÔËÐÐÕý³££¬¶Á³öÊý¾ÝÕýÈ·£¬Ö»ÓÐwrite²»¶Ô£¬ºÃÏóÊǸù±¾¾ÍûÓе÷Óã¬Ã»Óнøµ½º¯ÊýÀïÃæÈ¥£¬²»ÖªµÀΪʲô£¬ÇëÓоÑéµÄÐֵܰï°ï棡
/////////////´úÂ뿪ʼ////////////////////
/*********************************************************************
* ÔÚAT91RM9200ÉÏ×ÔÐÐÀ©Õ¹µÄ´úÌæpc104µÄ×ÜÏßµÄÇý¶¯³ÌÐò
*********************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <asm/io.h>
#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
#endif
static int AT91_PC104;
#define PC104_SIZE 1024
#define PC104_MAJOR 125
#define NR_PC104_DEVICES 1
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_handle = NULL;
static devfs_handle_t devfs_pc104[NR_PC104_DEVICES];
#endif
/*********************************************************************
* º¯ÊýÉùÃ÷
*********************************************************************/
static int at91_pc104_init(void);
static void at91_pc104_cleanup(void);
static void pc104_init(void);
static int pc104_open(struct inode *inode, struct file *filp);
static int pc104_close(struct inode *inode, struct file *filp);
static ssize_t pc104_read(struct file *filp, char *buf, size_t count, loff_t *offset);
static ssize_t pc104_write(struct file *filp, const char *buf, size_t count, loff_t *offset);
/*********************************************************************+
* È«¾Ö±äÁ¿¶¨Òå
**********************************************************************/
int pc104_param = 9;
static int pc104_initialized = 0;
static int pc104_reading=0;
static int pc104_writing=0;
static volatile int pc104_flag = 0;
static struct file_operations pc104_fops = {
owner: THIS_MODULE,
read: pc104_read,
write: pc104_write,
open: pc104_open,
release: pc104_close,
};
[b]static int at91_pc104_init(void)[/b]
{
int i = 0;
char name[2];
/*È·¶¨Ä£¿éÒÔǰδ³õʼ»¯*/
if(pc104_initialized == 1)
return 0;
/*·ÖÅä²¢³õʼ»¯ËùÓÐÊý¾Ý½á¹¹ÎªÈ±Ê¡×´Ì¬*/
#ifdef CONFIG_DEVFS_FS
if(devfs_register_chrdev(PC104_MAJOR, "pc104", &pc104_fops)){
#else
if(register_chrdev(PC104_MAJOR, "pc104", &pc104_fops)){
#endif
printk(KERN_CRIT"pc104:i = %d\n",i);
return -EIO;
}
printk(KERN_CRIT"pc104 registerred successfully!\n");
/*ÇëÇóÖжÏ*/
pc104_initialized = 1;
#ifdef CONFIG_DEVFS_FS
devfs_handle = devfs_mk_dir(NULL, "pc104", NULL);
for(i = 0; i < NR_PC104_DEVICES; i++)
{
sprintf(name, "%d", i);
devfs_pc104[i] = devfs_register(devfs_handle, name,
DEVFS_FL_DEFAULT, PC104_MAJOR, i, S_IFCHR|S_IRUSR|S_IWUSR,&pc104_fops, NULL);
}
#endif
return 0;
}
void pc104_init()
{
AT91_PC104 = (unsigned long) ioremap(0x80000000,SZ_1K);
AT91_SYS->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);
AT91_SYS->EBI_SMC2_CSR[7] = (AT91C_SMC2_NWS & 0x4) | AT91C_SMC2_WSEN |
(AT91C_SMC2_TDF & 0x200)| AT91C_SMC2_DBW_8;
}
[b]static int pc104_open(struct inode *inode, struct file *filp)[/b]
{
if(pc104_flag == 1)/*¼ì²éÇý¶¯ÊÇ·ñæ*/
{
return -1;
}
/*¿ÉÒÔ³õʼ»¯Ò»Ð©ÄÚ²¿Êý¾Ý½á¹¹*/
pc104_init();
MOD_INC_USE_COUNT;
pc104_flag = 1;
return 0;
}
[b]static int pc104_close(struct inode *inode, struct file *filp)[/b]
{
if(pc104_flag == 0)
{
return 0;
}
/*¿ÉÒÔɾ³ýһЩÄÚ²¿Êý¾Ý½á¹¹*/
MOD_DEC_USE_COUNT;
pc104_reading = 0;
pc104_writing = 0;
pc104_flag = 0;
return 0;
}
[b]static ssize_t pc104_read(struct file *filp, char *buf, size_t count, loff_t *offset)[/b]
{
size_t i;
ssize_t ret=0;
/*¼ì²éÊÇ·ñÓÐÏß³ÌÔÚ¶ÁÊý¾Ý£¬·µ»Ø error*/
if(pc104_reading)
return -1;
pc104_reading=1;//DEMO_RD_LOCK;
if(!count)
return ret;
if(*offset>=PC104_SIZE)
return -EINVAL;
if((*offset+count)>PC104_SIZE)
count=PC104_SIZE-*offset;
for(i = 0; i < count; i++)
{
buf[i] = readb(AT91_PC104+*offset+i);
}
buf[i] = '\0';
*offset +=count;
ret=count;
pc104_reading=0;//DEMO_RD_UNLOCK;
/*ͨ³£·µ»Ø³É¹¦¶Áµ½µÄÊý¾Ý*/
return ret;
}
[b]static ssize_t pc104_write(struct file *filp, const char *buf, size_t count, loff_t *offset)[/b]
{
ssize_t ret = 0;
printk("pc104 devices writing!\n");
return ret;
}
[b]static void at91_pc104_cleanup(void)[/b]
{
/*È·±£ÒªÇåµôµÄÄ£¿éÊÇ·ñÒѳõʼ»¯*/
if(pc104_initialized == 1)
{
unregister_chrdev(PC104_MAJOR,"pc104");
pc104_initialized = 0;
printk(KERN_CRIT"pc104 device is cleanup\n");
}
}
[b]module_init(at91_pc104_init);[/b]
[b]module_exit(at91_pc104_cleanup);[/b]
//////////´úÂë½áÊø///////////////////////////////[/color]
Ò³:
[1]