⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arm_can_b.c

📁 CAN在S3C2440下的驱动代码
💻 C
字号:
//中断设备程序的编写//1.编译开关://gcc -O2 -D__KERNEL__ -DMODULE -I/usr/src/linux/include -c example.c -o example.o//2.加载模快:// insmod  example.o//3.卸载模快://  rmmod /*************************  canb中断处理程序  *************************///设备名:canb,地址:D0000-D01FF//#define _debug  //编译调试代码开关#include <asm/io.h>#define canb_ADDR        0xfb000000#define canb_MEM_LEN     0x200  //#define INTERRUPT        0x04     //使用5号中断#define MODULE_VERSION   "1.0"#define MODULE_NAME      "can_b_for_arm"#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/proc_fs.h>#include <linux/string.h>#include <asm/io.h> #include <asm-arm/arch-s3c2410/irqs.h>#define INTERRUPT        IRQ_EINT1     //使用5号中断/***************************  can控制器   ***************************///1.错误代码定义#define    EVerify          12     // 写入回读不同#define    RESET_CAN_OK     13     // 复位成功#define    RESET_CAN_ERROR  14     // 复位错误#define    CAN_RESET        15     //#define    CAN_DEBUG        16     //0XFF#define    CAN_DEBUG_ERROR  17#define    CAN_OK           11#define    CAN_READ_NO_DATA  9     //无数据#define    CAN_WRITE_BUSY   10     //写数据忙      //2.控制寄存器#define    FlagRR          0x01   // 复位请求// 命令寄存器#define    FlagCOS         0x08   // 清除超载#define    FlagRRB         0x04   // 清除接收缓冲,允许接收#define    FlagAT          0x02   // 中止发送#define    FlagTR          0x01   // 发送请求//3.状态寄存器#define    FlagBS          0x80   // 总线脱离#define    FlagES          0x40   // 错误#define    FlagTS          0x20   // 正在发送#define    FlagRS          0x10   // 正在接收#define    FlagTCS         0x08   // 发送完成#define    FlagTBS         0x04   // 发送缓冲可用#define    FlagDO          0x02   // 数据超载#define    FlagRBS         0x01   // 接收缓冲有效//4.中断寄存器#define    FlagWUI         0x10   // 唤醒中断#define    FlagOI          0x08   // 超载中断#define    FlagEI          0x04   // 错误中断#define    FlagTI          0x02   // 发送中断#define    FlagRI          0x01   // 接收中断//5.速度#define    BTR0_125K       0x03   // 波特率=125Kbps(16MHZ),(3+1)*2=8#define    BTR1_125K       0x1C   // TSEG1=0x0C=>13,TSEG2=0x01=>2,1+13+2=16#define    BTR0_500K       0x01   // 波特率=500Kbps(16MHZ),(1+1)*2=4#define    BTR1_500K       0x14   // TSEG1=0x04=>5,TSEG2=0x01=>2,1+5+2=8#define    BTR0_1M         0x00   // 波特率=1Mbps(16MHZ),(1)*2=2#define    BTR1_1M         0x14   // TSEG1=0x04=>5,TSEG2=0x01=>2,1+5+2=8#define    BTR0_Data       BTR0_500K#define    BTR1_Data       BTR1_500K//6.其他#define    DLCMask         0x0F   // DLC屏蔽#define    IDLMask         0xE0   // D低字节高3位屏蔽#define    IDLShift        5      // ID低字节高3位右对齐移位计数#define    TimeReset       100    // 复位时间,毫秒char volatile *OUTP;#define outb(X,Y)    OUTP=(char *)(0xfb000000+Y);*OUTP=X;struct CanControl {   unsigned char CR; //控制寄存器   unsigned char CMR;//命令寄存器   unsigned char SR; //状态寄存器    unsigned char IR;//中断寄存器   unsigned char ACR;//验收寄存器   unsigned char AMR;//屏蔽寄存器   unsigned char BTR0;   unsigned char BTR1;   unsigned char OCR;   unsigned char TR; // 寄存器00..09   unsigned char TxDSCR[2],TxData[8];//发送ID,数据 10..19   unsigned char RxDSCR[2],RxData[8];//接收ID,数据 20..29   unsigned char XX30,CDR;//31 时钟驱动 30..31   // unsigned char XX32[0x0100-32],RST;   //复位控制 0x0100} volatile *pcanb;#define FRAME_DATA_SIZE   10   //每帧大小(包括TxDSCR[2]、TxData[8]或RxDSCR[2]、RxData[8])#define IN_BUFFER_LEN     FRAME_DATA_SIZE*200  //接受缓冲区大小:100帧static unsigned char canb_in_buffer[IN_BUFFER_LEN];   //接受缓冲区:指通过CAN接受的数据临时存放处,用户通过read函数读取该缓冲区static int canb_in_buf_head=0; //接受缓冲区头指针static int canb_in_buf_tail=0; //接受缓冲区尾指针static char canb_write_busy=0;//初始时置0,write后置1,发送中断产生时置0static unsigned long irqt_tx=0,irqt_rx=0;static unsigned char rcount;		   static struct proc_dir_entry *interrupt_canb_file;int canb_interruptcount = 0;char canb_flag=0;#include "filter.h"//中断处理函数void interrupt_interrupt_canb(int irq, void *dev_id, struct pt_regs *regs){    unsigned char ir;    static char into_flag=0;	int i;	    if(into_flag) return;    into_flag=1;    ir=pcanb->IR;    if((ir&FlagRI))    {//接受中断                canb_in_buffer[canb_in_buf_tail]=pcanb->RxDSCR[0];	canb_in_buffer[canb_in_buf_tail+1]=pcanb->RxDSCR[1];	//if(IsOk(canb_in_buffer[canb_in_buf_tail])&&	   //((canb_in_buffer[canb_in_buf_tail+1]&0x1f)<=8))	   if(1)	{//	   canb_in_buffer[canb_in_buf_tail+1]=pcanb->RxDSCR[1];           canb_in_buffer[canb_in_buf_tail+2]=pcanb->RxData[0];           canb_in_buffer[canb_in_buf_tail+3]=pcanb->RxData[1];           canb_in_buffer[canb_in_buf_tail+4]=pcanb->RxData[2];           canb_in_buffer[canb_in_buf_tail+5]=pcanb->RxData[3];           canb_in_buffer[canb_in_buf_tail+6]=pcanb->RxData[4];           canb_in_buffer[canb_in_buf_tail+7]=pcanb->RxData[5];           canb_in_buffer[canb_in_buf_tail+8]=pcanb->RxData[6];           canb_in_buffer[canb_in_buf_tail+9]=pcanb->RxData[7];		   		   // a little test , depends on the sender send the same 8 bytesa		   if(1)		   {		   static unsigned char lst;		   static int first=1;		   if(first)lst=pcanb->RxData[7];		   first=0;		   for(i=0;i<8;i++)if(lst+i!=pcanb->RxData[i])		   {			   printk("error last:%x,now:%x,%x,%x,%x,%x,%x,%x,%x\n",lst,			   pcanb->RxData[0],pcanb->RxData[1],pcanb->RxData[2],pcanb->RxData[3],			   pcanb->RxData[4],pcanb->RxData[5],pcanb->RxData[6],pcanb->RxData[7]);			   lst=pcanb->RxData[0];			   break;		   }		   lst++;		   lst&=0xf;		   rcount=lst;			irqt_rx++;		   }/*		              if(canb_in_buf_tail+FRAME_DATA_SIZE<IN_BUFFER_LEN)              canb_in_buf_tail=canb_in_buf_tail+FRAME_DATA_SIZE;	   else	      canb_in_buf_tail=0;		  */	}	pcanb->CMR=FlagRRB;//清除接受缓冲区//	i = pcanb->CMR;     }     else      if(ir&FlagTI)//发送中断	 {        canb_write_busy=0;		printk("send b");		irqt_tx++;	}     else       reset_interrupt_canb();     into_flag=0;     return;}//read响应函数//page和count分别对应调用函数read传递的参数buf和count//而且一次只返回一帧数据,故count和其他参数忽略//返回值为0表示无数据,否则page返回一帧数据static int proc_read_interrupt_canb(char *page, char **start, off_t off,                                       int count, int *eof, void *data){	printk("IRQ Times tx:%d,rx:%d , lastvalue rx:%x\n",irqt_tx,irqt_rx,rcount);	return 0;	    if(canb_flag==0)    {           if(canb_in_buf_head==canb_in_buf_tail)//无数据          return CAN_READ_NO_DATA;        page[0]=canb_in_buffer[canb_in_buf_head];               page[1]=canb_in_buffer[canb_in_buf_head+1];        page[2]=canb_in_buffer[canb_in_buf_head+2];        page[3]=canb_in_buffer[canb_in_buf_head+3];        page[4]=canb_in_buffer[canb_in_buf_head+4];        page[5]=canb_in_buffer[canb_in_buf_head+5];        page[6]=canb_in_buffer[canb_in_buf_head+6];        page[7]=canb_in_buffer[canb_in_buf_head+7];               page[8]=canb_in_buffer[canb_in_buf_head+8];               page[9]=canb_in_buffer[canb_in_buf_head+9];               if(canb_in_buf_head+FRAME_DATA_SIZE>=IN_BUFFER_LEN)  	   canb_in_buf_head=0;        else           canb_in_buf_head=canb_in_buf_head+FRAME_DATA_SIZE;        canb_flag=1;    }    else canb_flag=0;    return CAN_OK;}int __init reset_interrupt_canb(void){//复为can控制器   unsigned char b;   pcanb->CR=0x0f;//开放中断   pcanb->BTR0=BTR0_Data;   pcanb->BTR1=BTR1_Data;//置波特率   if((pcanb->BTR0!=BTR0_Data)|(pcanb->BTR1!=BTR1_Data))//写入回读不同      return RESET_CAN_ERROR;   pcanb->ACR=0x07;   pcanb->AMR=0xff;   pcanb->OCR=0xfa;   b=pcanb->CR;   pcanb->CR=b&0xfe;   canb_write_busy=0;   return RESET_CAN_OK;}//write响应函数//buffer和count分别对应调用函数write传递的参数buf和count//其他参数在can中断设备程序中忽略//如果输入参数buffer[0]==CAN_DEBUG进入调试//buffer[1]和buffer[2]分别为对应寄存器编号和将赋的值,并返回该寄存器旧值static char can_b_counts=0;static int proc_write_interrupt_canb(struct file *file,			const char *buffer,unsigned long count,void *data){    if(buffer[0]==CAN_RESET)        return reset_interrupt_canb();    if(canb_write_busy)     {	if(can_b_counts>3) { reset_interrupt_canb();can_b_counts=0;}	else can_b_counts++;        return CAN_WRITE_BUSY;    }	/*    pcanb->TxDSCR[0]=buffer[0];    pcanb->TxDSCR[1]=buffer[1];    pcanb->TxData[0]=buffer[2];    pcanb->TxData[1]=buffer[3];    pcanb->TxData[2]=buffer[4];    pcanb->TxData[3]=buffer[5];    pcanb->TxData[4]=buffer[6];    pcanb->TxData[5]=buffer[7];    pcanb->TxData[6]=buffer[8];    pcanb->TxData[7]=buffer[9];	*/		pcanb->TxDSCR[0]=0x50;	pcanb->TxDSCR[1]=0xe8;    pcanb->TxData[0]=1;    pcanb->TxData[1]=2;    pcanb->TxData[2]=3;    pcanb->TxData[3]=4;    pcanb->TxData[4]=5;    pcanb->TxData[5]=6;    pcanb->TxData[6]=7;    pcanb->TxData[7]=8;	    pcanb->CMR=FlagTR;    canb_write_busy=1;    return CAN_OK;}//初始化函数static int __init init_interrupt_canb(void){  int rv = 0;  unsigned char b;pcanb = canb_ADDR;  //  pcanb=(struct CanControl *)ioremap_nocache(0x29000000,canb_MEM_LEN);  pcanb->CR=0x0f;  pcanb->CMR=0x0;  pcanb->BTR0=BTR0_Data;  pcanb->BTR1=BTR1_Data;//置波特率  if((pcanb->BTR0!=BTR0_Data)|(pcanb->BTR1!=BTR1_Data))  {//写入回读不同      printk("What read is not what written  when canb initialize\n");      iounmap((void *)pcanb);      return EVerify;  }  pcanb->ACR=0x07;  pcanb->AMR=0xff;  pcanb->OCR=0xfa;  b=pcanb->IR;  interrupt_canb_file = create_proc_entry("canb", 0444, NULL);  if(interrupt_canb_file == NULL)  {      printk("create_proc_entry error....\n");      iounmap((void *)pcanb);        return -ENOMEM;  }  interrupt_canb_file->data = NULL;  interrupt_canb_file->read_proc = &proc_read_interrupt_canb;  interrupt_canb_file->write_proc = &proc_write_interrupt_canb;  interrupt_canb_file->owner = THIS_MODULE;  set_external_irq(INTERRUPT,EINT_FALLING_EDGE,0);  rv=request_irq(INTERRUPT, interrupt_interrupt_canb,SA_INTERRUPT,                 "canb",NULL);  if(rv)   {    printk("Can't get interrupt %d\n", INTERRUPT);    iounmap((void *)pcanb);    remove_proc_entry("canb", NULL);    return -1;  }  outb(0x0,0x21);//8259  b=pcanb->CR;  pcanb->CR=b&0xfe;  printk(KERN_INFO "%s %s initialized\n",MODULE_NAME, MODULE_VERSION);  return 0;}static void __exit cleanup_interrupt_canb(void){  free_irq(INTERRUPT,NULL);//释放所占用中断号  iounmap((void *)pcanb);  remove_proc_entry("canb", NULL);   printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERSION);}module_init(init_interrupt_canb);module_exit(cleanup_interrupt_canb);MODULE_AUTHOR("yh");MODULE_DESCRIPTION("interrupt_canb proc module");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -