ku_ice5202008-06-01 19:24
兄台你好,我是嵌入式的爱好者,毕业设计选择了arm控制微型打印机的实验,现在硬件已经没有问题,只是在微型打印机的驱动程序上出现了若干问题,想得到兄台的帮助。在我把zImage,rootfs.cramfs烧写到2410后,按reset重新启动后,cd /usr/sbin,然后执行:./print 就出现了一系列问题 unable handle kernel paging request at virtual address 0xd2800600
下面是我的驱动程序的代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "math.h" //微型打印机程序需要
#define INPUT (*(volatile unsigned char *)(0xd2800004))
#define OUTPUT (*(volatile unsigned char *)(0xd2800004))
#define CS244 (*(volatile unsigned char *)(0xd2800800))
#define CS273 (*(volatile unsigned char *)(0xd2800600))
#define MYGSM_MAJOR 254
static int gsm_Ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned
long arg);
static int gsm_Close(struct inode * inode, struct file * file);
static int gsm_Open(struct inode * inode, struct file * file);
static int gsm_Read(struct file *fp, char *buf, size_t count);
static int gsm_Write(struct file *fp, char *buf, size_t count);
struct file_operations gsm_fops =
{
write: gsm_Write,
open: gsm_Open, //打开设备文件
ioctl: gsm_Ioctl, //设备文件其他操作
release: gsm_Close, //关闭设备文件
read: gsm_Read, //读取设备文件
};
static void Timer3(short dat1,short dat2)
{
static char time3 = 0;
if(!dat2) dat2 = dat1/2;
if(dat1) //启动定时器3
{
if(time3) return;
INTMSK |= (0x1<<13);
GPBCON = (GPBCON & ~(0x0c0)) | 0x80;
//Dead zone=0,Prescaler1=15(0x0f), Prescaler0=15(0x0f)
GPBUP &= 0x0; //disable poll-up function
TCFG0 = (TCFG0 & ~(0xffffff)) | 0x00080f;
TCFG1 = (TCFG1 & ~(0x00f000)) | 0x003000;
TCNTB3 = dat1;
TCMPB3 = dat2; //pwm
TCON = (TCON & ~(0x0f0000)) | 0x0a0000;
TCON = (TCON & ~(0x0f0000)) | 0x090000;
INTMSK &= ~(0x1<<13);
time3 = 1;
}
else //关闭定时器3
{
if(!time3) return;
INTMSK |= (0x1<<13);
TCON &= ~0x10000;
GPBDAT |=0x10;
time3 = 0;
}
printk("\r\nGPBUP = %x\r\n",GPBUP);
}
static int gsm_Close(struct inode * inode, struct file * file)
{
printk("GSM Device Closed\n");
return 0;
}
static int gsm_Open(struct inode * inode, struct file * file)
{
printk("GSM Device opened\n");
return 0;
}
/*下面是微型打印机的程序,不要轻易改动,否则会烧毁微打头*/
void dellay(unsigned int t)
{
for(;t>0;t--);
}
void PrnPowerOff(void) //关闭微打的电源
{
CS273 = 0xfe;
}
void PrnPowerOn(void) //打开微打的电源
{
CS273 = 0xdf;
}
void PrnWait(void) //检测定时信号的变化,收到后开始下一针头的打印
{
if((CS244&0x2)==0) while((CS244&0x2)==0);
else while((CS244&0x2)!=0);
}
void PrnReset(void) //检测复位信号,收到后开始一行的打印
{
while((CS244&0x01) != 0x00);
while((CS244&0x01) == 0x00);
}
void PrnDot(unsigned char PrnNo,unsigned char data)
{
if(data!=0) CS273 = 0xdf&(~(0x1<<(PrnNo+1)));
PrnWait();
CS273 = 0xdf;
}
void PrnTranLine(unsigned char *prndata)
{
unsigned char i,j;
for(i=0;i<24;i++) //每个打印头一行打印24个点
{
for(j=0;j<4;j++) //4个打印头轮流打点
{
PrnDot(j,prndata[24*j+i]);
}
}
}
void PrnTran(unsigned char line,unsigned int *pdata)
{ //横向打印波形
unsigned char i,j;
unsigned char predata[100]; //保存在本行中各个数据点的状态
unsigned char nosdata[100]={0};
unsigned char prndata[100];
PrnPowerOn();
dellay(50000);
for(i=0;i((0xfff/line)*(line-
(i+1)))))
{
predata[j] = 0x1;
if(predata[j-1]==0x0)
nosdata[j]=~nosdata[j]&0x1;
else nosdata[j]=0;
}
else
{
predata[j] = 0;
if(predata[j-1]==0x1)
nosdata[j]=~nosdata[j]&0x1;
}
prndata[j]= predata[j]|nosdata[j];
}
PrnReset(); //等待一行打印的开始信号
PrnTranLine(prndata); //打印一行
}
dellay(50000);
PrnPowerOff(); //关闭打印机电源
}
void StartPrint(void)
{
unsigned int adbuff[128],i;
PrnPowerOff();
for(i=0;i<128;i++) //产生方波
{
if((i%32)<16) adbuff[i] =4080;
else adbuff[i] =10;
//adbuff[i] =(unsigned int)(2040*(sin(6.28*(i+8)/32)+1));
}
PrnTran(40,adbuff);
//PrnTran(4,Zero);
//PrnTran(40,pz);
//PrnTran(4,Zero);
}
/*微型打印机程序结束*/
static int gsm_Ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned
long arg)
{
if(cmd==0) Call_Out((char *)arg); //拨打电话
if(cmd==1) WriteCmdToGSM((char*)arg); //Write Command to GSM
if(cmd==2) Message((char *)arg); //发送短信内容
if(cmd==3) Timer3((short)arg,0); //启动定时器3
if(cmd==4) Timer3(0,0); //关闭定时器3
if(cmd==5) Set1();
if(cmd==6) Set0();
if(cmd==7) return getad();
if(cmd==8) return RunDS1820();
if(cmd==9) return wirelesssend((char)(arg&0xf));
if(cmd==10) return (int)wirelessrece();
if(cmd==11) return GetHall();
if(cmd==12) return RunSonic();
if(cmd==13) RunModem();
if(cmd==14) ModemRec(readback);
if(cmd==15) return gps();
if(cmd==16) ICCARDW((unsigned char) (arg>>16)&0xff,(unsigned char)arg&0xff);
if(cmd==17) return (int)ICCARDR((unsigned char)(0xff&arg));
if(cmd==18) cmd7279(arg);
if(cmd==19) return (int)read7279();
if(cmd==20) return icl7135();
if(cmd==21) return speed();
if(cmd==22) rs232((unsigned char)(0xff&arg));
if(cmd==23) pwm(); //Start Timer3
if(cmd==24) stepmotor(( int)(arg));
if(cmd==25) SetUart1();
if(cmd==26) SendUart1(arg);
if(cmd==27) pwm_set((arg>>16) & 0xffff, arg&0xffff); //Generate PWM control
signal
if(cmd==28) Adc_Init(0); //Initial ADC on 2410chip
if(cmd==29) return Adc_Sample(0); //Sample temperature in pid_temp
if(cmd==30) iocontrol(); //
if(cmd==31) Gsm_Cmd((char *)arg); //接听或挂断
if(cmd==32) WriteToRtl16c450((char *)arg); //直接向450写入数据,不等回应
if(cmd==33) ReadFromRrl16c450((char *)arg); //直接从450读出数据
if(cmd==34) StartPrint(); //驱动微型打印机开始打印
if(cmd==35) return WirelessRev(); //无线收发实验接收数据
return 0;
}
int __init gsm_Init(void)
{
int result;
int i;
printk("Registering GSM Device\n");
result = register_chrdev(MYGSM_MAJOR, "myGSM", &gsm_fops);//注册设备
BWSCON = (BWSCON & ~(BWSCON_ST4 | BWSCON_WS4 | BWSCON_DW4)) |
(BWSCON_ST4 | BWSCON_WS4 | BWSCON_DW(4, BWSCON_DW_8));
BANKCON4= BANKCON_Tacs4 | BANKCON_Tcos4 | BANKCON_Tacc4 |
BANKCON_Toch4 | BANKCON_Tcah4 | BANKCON_Tacp6 | BANKCON_PMC4;
if (result<0)
{
printk(KERN_INFO"[FALLED: Cannot register gsm_driver!]\n");
return result;
}
set_gpio_ctrl(GPIO_F0|GPIO_MODE_EINT);
//set EINT MODE
set_external_irq(IRQ_EINT0,2,0); //set falling edge triger
for(i=0;i<100;i++);
if (request_irq(IRQ_EINT0,Exint0_ISR,0,"myGSM","external INT"))
{
printk(KERN_INFO"[FALLED: Cannot register myGSM_Interrupt!]\n");
return -EBUSY;
}
if (request_irq(13,timer3_ISR,0,"myGSM","timer3"))
{
printk(KERN_INFO"[FALLED: Cannot register myGSM timer3!]\n");
}
printk("GSM Driver Installed.\n");
pt=0;
return 0;
}
void __exit gsm_Exit(void)
{
unregister_chrdev(MYGSM_MAJOR, "myGSM");
printk("You have uninstall The myGSM Driver succesfully,\n if you want to
install again,please use the insmod command \n");
}
module_init(gsm_Init);
module_exit(gsm_Exit);
MODULE_LICENSE("GPL");