python开发板卡驱动开发_IC卡驱动程序开发

该代码实现了一个嵌入式系统中针对IC卡的操作,包括读写、复位、中断处理等。通过配置GPIO引脚检测IC卡是否插入,并使用中断请求注册函数来处理中断。此外,提供了读写数据的函数,以及IC卡的初始化和复位功能。代码还包含了读取和写入数据的低级别操作,如移位和等待中断。
摘要由CSDN通过智能技术生成

/*调用ic_request_irqs注册中断处理程序

*配置引脚*/intic_open (structinode*inode,structfile*filp)

{intnum;intret=0;

unsignedlongflags;

ICDEBUG(KERN_ALERT"open ic card\n");//获取次设备号num=MINOR(inode->i_rdev);

ICDEBUG(KERN_ALERT"MINOR:%d\n",num);if(num>=ICCARD_NR_DEVS)return-ENODEV;

spin_lock_irqsave(&lock,flags);

filp->private_data=&ic_dev_info[num];//检测IC卡是否已插入设备s3c2410_gpio_cfgpin(S3C2410_GPG6,S3C2410_GPG6_INP);//ICCARD_INTEREPTif((__raw_readw(S3C2410_GPGDAT)&(1<<6))==0<<6)

{

ic_dev_info[num].ic_state=1;//代表卡已插入ic_dev_info[num].r_press=1;//设备可读ic_dev_info[num].w_press=1;//设备可写ICDEBUG(KERN_ALERT"has ic card device\n");

}else{

ic_dev_info[num].ic_state=0;//代表卡已插入ic_dev_info[num].r_press=0;//设备可读ic_dev_info[num].w_press=0;//设备可写ICDEBUG(KERN_ALERT"no found ic card device\n");

}

spin_unlock_irqrestore(&lock,flags);//初始化输入输出引脚init_gpio();

ICDEBUG(KERN_ALERT"open ic card success\n");returnret;

}intic_release(structinode*inode,structfile*filp)

{//ic_free_irqs();return0;

}/**从ic卡中读出一个字节的数据*/intic_card_read_byte(char*ch)

{intret=0;intii;for(ii=8; ii>0; ii--)

{

CLR_CARD_CLK();

udelay(5);*ch=(*ch)>>1;//从低位读起//if((__raw_readw(S3C2410_GPGDAT)&0x0008)==0x0008)if((__raw_readw(S3C2410_GPGDAT)&(1<<3))==1<<3)

{*ch|=0x80;

ICDEBUG(KERN_ALERT"\n");

}else{

ICDEBUG(KERN_ALERT"\n");

}

udelay(5);

SETB_CARD_CLK();

}

ICDEBUG(KERN_ALERT"ic_card_read_byte:ch is>>>>>(%c)\n",*ch);returnret;

}intic_card_write_byte(char*ch)

{intret=0;intii;

ICDEBUG(KERN_ALERT"enter ic_card_write_byte,ch is %c\n",*ch);for(ii=0; ii<8; ii++)

{

CLR_CARD_CLK();

udelay(5);if(*ch&0x01)

{

ICDEBUG(KERN_ALERT"[+++++$++++++++]\n");

SETB_CARD_IO();//输入1}else{

ICDEBUG(KERN_ALERT"[-----$--------]\n");

CLR_CARD_IO();//输入0}

udelay(5);

SETB_CARD_CLK();

udelay(10);*ch=*ch>>1;

}returnret;

}/**复位和复位应答*/staticintic_card_reset(void)

{

unsignedchartemp_ch;inttemp_i=4;

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_OUTP);//OUTudelay(5);

CLR_CARD_RESRT();

CLR_CARD_CLK();

SETB_CARD_IO();

udelay(5);

SETB_CARD_RESRT();

udelay(5);

SETB_CARD_CLK();

udelay(30);

CLR_CARD_CLK();

udelay(5);

CLR_CARD_RESRT();

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_INP);//INudelay(10);do{//temp_ch = ic_card_read_byte();ic_card_read_byte(&temp_ch);

ICDEBUG(KERN_ALERT"ic_card_reset:temp_ch is(%c)\n",temp_ch);

}while(--temp_i>0);

CLR_CARD_CLK();

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_OUTP);//INudelay(5);

SETB_CARD_IO();

udelay(5);

CLR_CARD_CLK();

udelay(5);return0;

}/**命令开始条件*/voidic_card_start_cmd(void)

{

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_OUTP);//outCLR_CARD_CLK();

SETB_CARD_IO();

udelay(5);

SETB_CARD_CLK();

udelay(5);

CLR_CARD_IO();

udelay(5);

}/**命令结束条件*/voidic_card_end_cmd(void)

{

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_OUTP);

CLR_CARD_CLK();

CLR_CARD_IO();

udelay(5);

SETB_CARD_CLK();

udelay(5);

SETB_CARD_IO();

udelay(5);

}/*发送命令*/voidic_card_send_cmd(constcharcmd,constcharaddr,constcharcount)

{

ICDEBUG(KERN_ALERT"enter ic_card_read:cmd is %c,addr is %c,count is %c\n",cmd,addr,count);

ic_card_start_cmd();

ic_card_write_byte(&cmd);

ic_card_write_byte(&addr);

ic_card_write_byte(&count);

ic_card_end_cmd();

}voidic_card_breakoperator(void)

{

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_OUTP);

CLR_CARD_CLK();

CLR_CARD_RESRT();

CLR_CARD_IO();

udelay(5);

SETB_CARD_RESRT();

SETB_CARD_IO();

udelay(5);

CLR_CARD_RESRT();

udelay(5);

}/*从设备中读取指定长度的数据*/ssize_t ic_dev_read(structfile*filep,constchar*buf, size_t count, loff_t*offset)

{intret=0;//wait_event_interruptible();//char *kbuf;intistate;intsizetmp;char*pbuf;//unsigned char ch=0;ic_card_dev*icdev=(ic_card_dev*)filep->private_data;

ICDEBUG(KERN_ALERT"enter ic_dev_read\n");

istate=icdev->ic_state;

ICDEBUG(KERN_ALERT"ic_dev_istate:%d\n",istate);

pbuf=buf;if(!istate)

{return-ENODEV;

}if(!pbuf)

{return-1;

}

sizetmp=count;

s3c2410_gpio_cfgpin(S3C2410_GPG3,S3C2410_GPG3_INP);//将GPG3配置成输入引脚CLR_CARD_CLK();

udelay(5);do{

ic_card_read_byte(pbuf++);//*buf++ = ic_card_read_byte();ret++;

ICDEBUG(KERN_ALERT"[ic_card_read:buf is (%c) ret:%d]\n",*(pbuf-1),ret);

}while(--sizetmp);returnret;

}/*往设备中写入数据*/ssize_t ic_dev_wrtie(structfile*filep,char*buf, size_t count, loff_t*offset)

{intret=0;intistate;

unsignedlongflags;intsizetmp;

ICDEBUG(KERN_ALERT"enter ic_dev_wrtie\n");

spin_lock_irqsave(&lock,flags);

istate=((ic_card_dev*)(filep->private_data))->ic_state;

spin_unlock_irqrestore(&lock,flags);if(!istate)

{return-ENODEV;

}if(!buf)return-1;//wait_event_interruptible();s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_OUTP);//将GPG3配置成输出引脚sizetmp=count;do{

ic_card_write_byte(buf++);//按字节发送至ic卡}while(--sizetmp);returnret;

}/*file_operations read*/ssize_t ic_card_read(structfile*filep,char__user*buf, size_t count, loff_t*offset)

{//int ii;intret;char*kbuf;

unsignedlongflags;intr_press;

ICDEBUG(KERN_ALERT"enter ic_card_read\n");

spin_lock_irqsave(&lock,flags);

r_press=((ic_card_dev*)filep->private_data)->r_press;

spin_unlock_irqrestore(&lock,flags);

ICDEBUG(KERN_ALERT"ic_card_read:r_press is:%d\n",r_press);

wait_event_interruptible(r_wait, r_press!=0);

kbuf=kmalloc(count,GFP_KERNEL);if(!kbuf)

{return-ENOMEM;

}

spin_lock_irqsave(&lock,flags);

((ic_card_dev*)filep->private_data)->w_press=0;

spin_unlock_irqrestore(&lock,flags);

ic_card_reset();

ic_card_send_cmd((constchar)IC_RMM_CMD,(constchar)((ic_card_dev*)(filep->private_data))->readbufstart,0xff);

ret=ic_dev_read(filep, kbuf, count, offset);

ICDEBUG(KERN_ALERT"[ic_card_read kbuf is:%s]\n",kbuf);if(ret>=0)

{

ret=copy_to_user(buf,kbuf,count);

}

ICDEBUG(KERN_ALERT"\n",kbuf,buf,ret,count);

ic_card_breakoperator();

spin_lock_irqsave(&lock,flags);

((ic_card_dev*)filep->private_data)->w_press=1;

spin_unlock_irqrestore(&lock,flags);

kfree(kbuf);returnret;

}/*file_operations write*/ssize_t ic_card_wrtie(structfile*filep,char__user*buf, size_t count, loff_t*offset)

{intret;char*kbuf;

unsignedlongflags;intw_press;

ICDEBUG(KERN_ALERT"enter ic_card_wrtie\n");

spin_lock_irqsave(&lock,flags);

w_press=((ic_card_dev*)filep->private_data)->w_press;

spin_unlock_irqrestore(&lock,flags);

kbuf=kmalloc(count,GFP_KERNEL);if(!kbuf)

{return-ENOMEM;

}

wait_event_interruptible(r_wait, w_press!=0);//if(w_press)//{spin_lock_irqsave(&lock,flags);

((ic_card_dev*)filep->private_data)->r_press=0;

spin_unlock_irqrestore(&lock,flags);

ic_card_reset();

ic_card_send_cmd((constchar)IC_WMM_CMD,(constchar)((ic_card_dev*)(filep->private_data))->writebufstart,count);if(copy_from_user(kbuf, buf, count))

{

kfree(kbuf);return-EFAULT;

}

ICDEBUG(KERN_ALERT"copy_from_user kbuf------------->:%s\n",kbuf);

ret=ic_dev_wrtie(filep, kbuf, count, offset);

printk(KERN_ALERT"ic_dev_wrtie ret : %d\n",ret);

ic_card_breakoperator();

spin_lock_irqsave(&lock,flags);

((ic_card_dev*)filep->private_data)->w_press=1;

spin_unlock_irqrestore(&lock,flags);

kfree(kbuf);

ICDEBUG(KERN_ALERT"ic_card_wrtie success\n");returnret;

}intic_ioctl(structinode*inode,structfile*filep, unsignedintcmd, unsignedlongarg)

{

unsignedinticount;

unsignedlongflags;

spin_lock_irqsave(&lock,flags);switch(cmd)

{caseCFG_RD_COUNT:

icount=(unsignedint)arg;

((ic_card_dev*)filep->private_data)->readcount=icount;break;caseCFG_WR_COUNT:

icount=(unsignedint)arg;

((ic_card_dev*)filep->private_data)->writecount=icount;break;default:break;

}

spin_unlock_irqrestore(&lock,flags);return0;

}/*#define POLLIN 0x0001 //有数据可以读入,read不会阻塞,注意:select的请情况下,即使到EOF也是ready的.

#define POLLPRI 0x0002 //紧急数据,比如TCP,或者packet模式的peseudo-terminal发现slave的状态有变化.

#define POLLOUT 0x0004 //写入不会阻塞.

#define POLLERR 0x0008 //输出出错

#define POLLHUP 0x0010 //Hang up (output only).

#define POLLNVAL 0x0020 //Invalid request: fd not open (output only).

The rest seem to be more-or-less nonstandard. Check them!

#define POLLRDNORM 0x0040 //POLLIN.

#define POLLRDBAND 0x0080 //高优先级的数据read for read (generally unused on Linux).

#define POLLWRNORM 0x0100 //Equivalent to POLLOUT.

#define POLLWRBAND 0x0200 //Priority data may be written.

#define POLLMSG 0x0400

#define POLLREMOVE 0x1000*/unsignedintic_poll (structfile*filep,structpoll_table_struct*wait)

{intic_num=0;//testunsignedintmask=0;

unsignedlongflags;//加入这句话是为了在读写状态发生变化的时候,通知核心层,让核心层重新调用poll函数查询信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值