微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于uclinux 的CAN总线嵌入式驱动编程

基于uclinux 的CAN总线嵌入式驱动编程

时间:04-06 来源:互联网 点击:

  • 5 CAN总线的嵌入式系统硬件设计

      本设计选用Samsung公司的S3C4510B作为嵌入式系统的微处理器芯片,该处理器是16/32位RISC微处理控制器,内含由ARM公司设计的16/32位ARM7TDMI RISC处理器核,适用于价格及功耗敏感的场合.除内核外,该微处理器的片内外围功能模块包括:2个带缓冲描述符的HDLC通道;2个UART通道;2个GDMA通道;2个32位定时器及可编程I/O口.CAN控制器选用philips公司的SJA1000,该芯片与PCA82C200电气兼容,带64字节先进先出(FIFO)堆栈,兼容协议CAN2.0B,支持11位和29位识别码,位速率可达1Mbps,24MHZ时钟频率,芯片内含寄存器,可由用户配置CAN总线波特率,设置验收屏蔽标识码,可配置系统为PeliCAN 模式或BasicCAN模式,出错告警等.

      该系统采用82C250作为收发器,其硬件连线如图(1)所示.AD0~AD7与S3C4510B的p0~p7连线,/cs接p12,ALE接p13,/RD接p14,/wr接p15,/int接XINTREQ0.

    图1 SJA1000硬件连线

      6 驱动软件设计


    图2 CAN总线初始化框图

      本设计中,CAN总线驱动程序是作为一个模块放在linux/deriver/char/文件夹里面,软件流程如图(2)所示,其设计详细介绍如下.

      模块首先对引用的库函数进行申明,并且定义:
      #define IOPMOD (*(volatile unsigned *)0x3ff5000)
      #define IOPDATA (*(volatile unsigned *)0x3ff5008)
      #define IOPCON (*(volatile unsigned *)0x3ff5004)
      #define EXTDBWTH(*(volatile unsigned *)0x3ff5
      #define SYSCFG(*(volatile unsigned *)0x
      主要有以下几个模块:
      void can_init(void)
      {
      SYSCFG =SYSCFG 0x0fffffffd;
      EXTDBWTH =EXTDBWTH 0x00ff0ff;
      IOPMOD=0xf0ff;
      IOPDATA=0x6000; 寄存器地址0,MOD寄存器
      IOPDATA= IO_PDATA0xdfff; ALE=0 配置MOD寄存器
      IOPDATA= IO_PDATA|0x3f; ; 复位模式、使能
      IOPDATA=0x6006; ;寄存器地址6,总线定时器0寄存器
      IOPDATA=IO_PDATA0xdfff; ALE=0配置寄存器
      IOPDATA= IO_PDATA|0x3f; 跳转宽度、波特率设置
      ……;配置总线定时器1、验收代码寄存器等
      IOPDATA=0x6000; SJA1000 寄存器地址0,MOD寄存器
      IOPDATA=IO_PDATA0xdfff; ALE=0配置MOD寄存器
      IOPDATA= IO_PDATA0xfe;写复位位,进入工作模式
      result = register_chrdev(254,"can",can_fops);申请主设备号
      if (result0) {
      printk(KERN_WARNING "CAN:can’t getmajor ", result);
      return result;
      }
      在该驱动程序中,定义结构变量can_fops为应用程序访问内核的接口:
      static struct file_operations can_fops = {
      read: can_read,
      write: can_write,
      open: can_open,
      release: can_release,
      }; 
      static int can_release(struct inode *inode, struct file *file)
      {
      MOD_DEC_USE_COUNT; ;用户减计数
      Return 0;
      }
      static int can_open(struct inode *inode,struct file *file)
      {
      Scull_Dev *dev;
      Int num = NUM(inode->i_rdev); 设备号
      Int type = TYPE(inode->i_rdev); 设备类型
      If (num>=scull_nr_devs) return -ENODEV;
      dev = scull_devices[num];
      flip->private_data = dev;
      MOD_INC_USE_COUNT; 用户数人工计数
      IOPCON=0x16; //xIRQ0
      disable_irq(INT_can);
      if(request_irq(INT_can, can_rx,
      SA_INTERRUPT, "can rx isr","can")) {
      printk("s3c4510-can: Can't get irq %d",
      INT_sja1000);
      return -EAGAIN;
      }
      printk("can has get irq 0");
      enable_irq(INT_can);
      …… ; 配置SJA1000内部中断及屏蔽寄存器
      return 0;
      }

      7 结束语

      本文介绍了CAN总线在嵌入式系统中的驱动编程,对CAN总线技术在嵌入式系统中的应用进行了探索.本设计已在通信用逆变电源远程监控系统中应用.

    参考文献:

    [1].S3C4510Bdatasheethttp://www.dzsc.com/datasheet/S3C4510B_59.html.
    [2].RISCdatasheethttp://www.dzsc.com/datasheet/RISC_1189725.html.
    [3].SJA1000datasheethttp://www.dzsc.com/datasheet/SJA1000_609075.html.
    [4].PCA82C200datasheethttp://www.dzsc.com/datasheet/PCA82C200_554.html.
    [5].p12datasheethttp://www.dzsc.com/datasheet/p12_2043488.html.
    [6].p13datasheethttp://www.dzsc.com/datasheet/p13_2043489.html.
    [7].p15datasheethttp://www.dzsc.com/datasheet/p15_1204152.html.

  • Copyright © 2017-2020 微波EDA网 版权所有

    网站地图

    Top