- 论坛徽章:
- 0
|
开发板:扬创s3c2440,
内核:utulinux2.6.24
本人写了一个控制IO口的驱动,功能是控制IO口的高低电平输出,用了PORTC的GPC15,GPC14,GPC13,GPC12这四个管脚(查了下芯片手册这四个管脚均可以配置成输入和输出管脚,并且开发板将这四个管脚通过排针引出了,感觉测试时比较容易控制)。
其中:
PORTC的控制寄存器地址GPCCON地址为0x56000020
PORTC的数据寄存器地址GPCDAT地址为0x56000024
驱动程序如下所示:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/cdev.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-irq.h>
MODULE_LICENSE("GPL");
#define DEVNAME "IOPORT"
#define IOPORTSIZE 4
#define IOPORTREG 0x56000020
#define IOPORTADDR 0x56000024
static volatile unsigned long* IoRegBase;
static volatile unsigned long* IoPortBase;
static int io_major_no = 0;
static int IOPORT_Remap()
{
int io_err;
io_err = check_region( IOPORTREG,IOPORTSIZE );
if( io_err < 0 )
{
printk( "io register check error!" );
return 1;
}
io_err = check_region( IOPORTADDR,IOPORTSIZE );
if( io_err < 0 )
{
printk( "io base address check error!" );
return 1;
}
request_region( IOPORTREG,IOPORTSIZE * 2, DEVNAME );
IoRegBase = ioremap( IOPORTREG,IOPORTSIZE );
IoPortBase = ioremap( IOPORTADDR,IOPORTSIZE );
return 0;
}
static int io_open( struct inode* inode,struct file* flip );
static int io_release( struct inode* inode,struct file* flip );
static ssize_t io_write( struct file* ,const char*,size_t,loff_t* );
static ssize_t io_read( struct file*,const char*,size_t,loff_t* );
struct file_operations io_fops =
{
.open = io_open,
.release = io_release,
.write = io_write,
.read = io_read,
};
static int io_open( struct inode* inode,struct file* flip )
{
int i;
for( i = 0; i < 4; i++ )
{
*( IoRegBase + i ) = 0x00;
}
*( IoRegBase + 3 ) = 0x55;
*( IoPortBase ) = 0x0000;
return 0;
}
static int io_release( struct inode* inode,struct file* flip )
{
int i;
for( i = 0; i < 4; i++ )
{
*( IoRegBase + i ) = 0x00;
}
return 0;
}
static ssize_t io_write( struct file* flip,const char* buffer,size_t len,loff_t* off )
{
char *buf,t;
buf = buffer;
t = buf[0];
switch( t )
{
case 'a': *( IoPortBase ) = 0xf000;break;
case 'b': *( IoPortBase ) = 0x7000;break;
case 'c': *( IoPortBase ) = 0xb000;break;
default : printk( "error" );
}
return 0;
}
static ssize_t io_read( struct file* flip,const char* buffer,size_t len,loff_t* off )
{
return 0;
}
static int __init io_module_init( void )
{
int result;
result = register_chrdev( 212,DEVNAME,&io_fops );
io_major_no = 212;
}
static void __exit io_module_release( void )
{
iounmap( IoRegBase );
iounmap( IoPortBase );
release_region( IOPORTREG,IOPORTSIZE );
release_region( IOPORTADDR,IOPORTSIZE );
unregister_chrdev( io_major_no,DEVNAME );
}
module_init( io_module_init );
module_exit( io_module_release );
测试程序:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#define DEVICE_FILENAME "/dev/IOPORT"
int main()
{
int fileHandle,i;
char buff[10] = "bcd";
fileHandle = open( DEVICE_FILENAME,O_RDWR|O_NDELAY);
if ( fileHandle >= 0 )
{
printf( "the device added already" );
}
for( i = 0; i < 10000; i++ )
write (fileHandle,buff,1);
}
编译可以动过加载也没有问题但是当用如上测试程序测试时就出现了一大堆的oop错误不知什么原因希望大家能够给予一些指点。。。 |
|