2837|1

9

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

2410并行接口驱动,虚拟地址和实际地址映射问题。 [复制链接]

使用S3C2410DATA0~DATA15,扩展2个并行接口,原理图如下所示。
通过一个CPLD扩展I/O驱动修改成驱动程序,编译没有出错,但是在板子上insmod时出现段错误。
         怀疑是使用的物理地址和虚拟地址不对。
#define pEXTERNAL_IO_Addr 0x080000c0
#define EXTERNAL_BaseAddr_IO (*(volatile unsigned char*)(0xd02000c0))
加载模块时出错信息:
[root@(none) tmp]# insmod DIGIO2.ko                                             
Using DIGIO2.ko                                                                 
Unable to handle kernel paging request at virtual address 56000000              
pgd = c2604000                                                                  
[56000000] *pgd=00000000                                                        
Internal error: Oops: 5 [#1]                                                   
Modules linked in: DIGIO ov511 usbvideo usb_storage sd_mod                     
CPU: 0                                                                          
PC is at digio_init+0x50/0xc0 [DIGIO]                                          
LR is at 0x56000004                                                            
pc : []    lr : [<56000004>]    Not tainted                           
sp : c2e55f6c  ip : 56000000  fp : c2e55f84                                    
r10: 00000000  r9 : c2e54000  r8 : c002c5c4                                    
r7 : 00000000  r6 : 56000014  r5 : 56000010  r4 : 00000000                     
r3 : c0270284  r2 : 0000efff  r1 : 000007fe  r0 : bf03010c                     
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user                        
Control: C000717F  Table: 32604000  DAC: 00000015                              
Process insmod (pid: 337, stack limit = 0xc2e54190)                             
Stack: (0xc2e55f6c to 0xc2e56000)                                               
5f60:                            c026f44c bf030520 c026f434 c2e55fa4 c2e55f88   
5f80: c0055fbc bf032010 00000004 00000000 00000000 00000080 00000000 c2e55fa8   
5fa0: c002c440 c0055e20 00000000 00000000 00900080 40015000 00000b79 001cb028   
5fc0: 00000004 00000000 00000000 befffd74 001cb018 001cb008 00000000 00000000   
5fe0: beffd8c4 beffd8b8 000444e0 40199ac0 60000010 00900080 e586000c e596201c   
Backtrace:                                                                     
[] (digio_init+0x0/0xc0 [DIGIO]) from [] (sys_init_module+0)
r6 = C026F434  r5 = BF030520  r4 = C026F44C                                    
[] (sys_init_module+0x0/0x314) from [] (ret_fast_syscall+0x)
r7 = 00000080  r6 = 00000000  r5 = 00000000  r4 = 00000004                     
Code: aa000002 eb403843 e1a00004 e91ba870 (e59c3000)                           
Segmentation fault




并行接口原理图


附上驱动程序代码:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include //包含可装载模块需要的大量符号和函数的定义
#include
#include //定义了LINUX内核的版本,用于版本检查
#include
#include //指定初始化和清除函数
#include
//#include
//
//#include //LINUX内核编译时的配置文件,文件里面指向另一个由make menuconfig自动生成的文件autoconfig.h
#include
#include //最重要的头文件之一。该文件包含驱动程序使用的大部分内核API的定义,包含睡眠函数以及各种变量声明。
#include
#include
#include
#include
//#include
#include
#include
//
#define DEVICE_NAME "digio" //设备名
#define DIGIO_MAJOR 232   //主设备号
//unsigned short buffer,dio_value;
#define pEXTERNAL_IO_Addr 0x080000c0
#define EXTERNAL_BaseAddr_IO (*(volatile unsigned char*)(0xd02000c0))
/*
static void dig_io_read()
{
(void *)(digital_in)=ioremap(0x0800b800,0x2);   //映射74HC574,16位
buffer=*(volatile unsigned short *)(digital_in); //读数字输入
copy_to_user(buffer,&dio_value,sizeof(dio_value));//数据送入用户空间
}
static void dig_io_write()
{
(void *)(digital_out)=ioremap(0x10000000,0x2);   //映射74HC574,16位
copy_form_user(&dio_value,buffer,sizeof(dio_value));//数据送入内核空间
*(volatile unsigned short *)=buffer;        //写数字输出
}
*/
static ssize_t dig_io_read(struct file *filp,char *buf,size_t count,loff_t *f_pos) //读函数
{
unsigned char val;
val=inb(EXTERNAL_BaseAddr_IO); //读取数据
copy_to_user(buf,&val,1); //数据送入用户空间
return 1;
}
static ssize_t dig_io_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos)
{
unsigned char val;
copy_from_user(&val,buf,1); //数据送入内核空间
outb(val,EXTERNAL_BaseAddr_IO); //写数据
return 1;
}
static struct file_operations digio_fops={
owner:THIS_MODULE,
write:dig_io_write,
read:dig_io_read,
};
//static devfs_handle_t devfs_handle;
/*
static int digio_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
  case 0:dig_io_read();
  case 1:dig_io_write();
  default:
   return -EINVAL;
}
}
static struct file_operations digio_fops={
owner:THIS_MODULE,
ioctl:digio_ioctl,
};
*/
static int __init digio_init(void) //设备驱动初始化函数
{
int ret;
int i;
ret=register_chrdev(DIGIO_MAJOR,DEVICE_NAME,&digio_fops);
if(ret<0)
{
  printk(DEVICE_NAME"can't regsiter major number");
  return ret;
}
// devfs_handle=devfs_register(NULL,DEVICE_NAME,DEVFS_FL_DEFAULT,DIGIO_MAJOR,S_IFCHR|S_IRUSR|S_IWUSR,&digio_fops,NULL);
// EXTERNAL_BaseAddr_IO=ioremap(pEXTERNAL_IO_Addr,1);
rGPACON=rGPACON&0x7effff;
rGPADAT=rGPADAT&0xefff;
rGPBCON=rGPBCON&0x3ffffc|0x000001;
rGPBDAT=rGPBDAT&0x7fe;
printk(DEVICE_NAME"initialized\n");
return 0;
}
static void __exit digio_exit(void) //模块退出函数
{
// iounmap(EXTERNAL_BaseAddr_IO);
// devfs_unregister(devfs_handle);
unregister_chrdev(DIGIO_MAJOR,DEVICE_NAME);
}
module_init(digio_init);
module_exit(digio_exit);
MODULE_LICENSE("GPL");


此帖出自Linux开发论坛
点赞 关注

回复
举报

9

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
丢虚拟地址和实际地址不太明白,求指导。
此帖出自Linux开发论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表