首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于Linux操作系统的ARM/DSP多机I2C通信设计方案(2)

基于Linux操作系统的ARM/DSP多机I2C通信设计方案(2)

Linux的I2C总线驱动框架中的主要数据结构包括: i2c_driver、i2c_client、i2c_adapter和 i2c_algorithm,它们被定义在内核中的i2c. h头文件中。i2c_adapter对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法,用来为适配器提供通信函数。i2c_algorithm中的关键函数master_xfer()用于产生I2C总线访问周期需要的信号,以i2c_msg(即I2C总线消息)为单位。该结构体原型如下:  struct i2c_msg{
  _ _u16 addr;/*设备地址*/
  _ _u16 flags;/*标志*/
  _ _u16 len;/*消息长度*/
  _ _u8 *buf;/*消息数据*/
  };
  i2c_driver对应一套驱动方法,是用于辅助作用的数据结构。i2c_client对应于真实的物理设备,每个I2C总线设备都需要一个i2c_client来描述。i2c_adapter和i2c_client的关系与I2C总线硬件体系中适配器和设备关系一致,即i2c_client依附于i2c_adapter.


图6 设备驱动模块加载流程

  在Linux内核源代码中drivers目录下的i2c_dev.c文件,是通用的I2C总线设备驱动文件,为应用程序提供open()、write()、read )、ioctl()和close()等操作接口来访问设备。应用层可以借用这些接口访问挂接在适配器上的I2C总线设备的存储空间或寄存器,并控制I2C总线设备的工作方式。
  2.1.3 S3C2440的I2C总线驱动
  设备驱动S3C2440内部的I2C总线控制器通过4个寄存器实现对通信的控制,分别是I2C控制寄存器(I2CCON)、I2C状态寄存器(I2CSTAT)、I2C收发数据移位寄存器(I2CDS)、I2C地址寄存器(I2CADD)。
  按照Linux中I2C总线框架要求,S3C2440的I2C总线驱动设计主要完成以下工作:设计i2c_adapter_s3c_init()模板加载函数和对应于i2c_adapter_s3c_exit()模板卸载函数;设计i2c_adapter_s3c_xfer()模板S3C2440适配器通信方法函数。
  i2c_adapter_s3c_init()通过注册s3c2440_i2c_driver结构体实现总线驱动的平台注册,s3c2440_i2c_driver结构体包含了具体适配器的probe()函数、remove()函数、resume()函数指针等信息。代码如下:
  static int _ _init i2c_adap_s3c_init(){
  int ret;
  ret=platform_driver_regisiter(&s3c2440_i2c_driver);//注册platform_driver结构体
  if(ret==0){//注册失败
  ret=platform_driver_regisiter(&s3c2440_i2c_driver);
  if(ret)
  platform_driver_unregisiter (&s3c2440_i2c_driver);
  }
  return ret;
  }
  static struct platform_driver s3c2440_i2c_driver={
  .probe=s3c24xx_i2c_probe,
  .remove=s3c24xx_i2c_remove,
  .resume=s3c24xx_i2c_resume,
  .driver={
  .owner=THIS MODULE,
  .name=“s3c2440i2c”,
  },
  } ;
  完成了S3C2440的I2C总线适配器驱动注册后,就可以将具体设备驱动注册到该总线平台上,实现I2C总线数据通信。i2c_dev.c文件是内核源码提供的通用I2C总线设备驱动文件,针对每个I2C总线适配器生成一个主设备号为89的设备文件,设备驱动模块加载流程如图6所示。完成加载后,驱动提供i2cdev_read()、i2cdev_write()、i2cdev_ioctl()函数来对应用户空间的read()、write()、ioctl()函数,供用户使用。用户通过这些接口函数实现I2C总线数据的读写功能。
  2.2 DSP数据接收中断程序设计


图7 I2C总线中断服务程序流程

  通过配置F28015的I2C模块寄存器,设置I2C模块为从工作方式,同时利用I2C总线中断响应程序实现对总线上数据的接收和发送,进而完成数据通信。F28015产生了I2C总线中断后,就执行中断服务程序,图7为I2C总线中断服务程序流程。
  中断服务程序通过查询状态寄存器(I2CSTR)标志位,得出中断类型码,然后调用相应的子程序,完成数据接收发送。代码如下:
  interrupt void i2c_int1a_isr(void) {//I2CA的中断响应函数
  Uint16 IntSource;// 读取中断码
  IntSource=I2caRegs.I2CISRC.bit.INTCODE & 0x7;//I2CA中断源,读后3位
  switch(IntSource){//依中断源而确定相关接收和发送策略
  case I2C_NO_ISRC://=0
  case I2C_ARB_ISRC://=1
  case I2C_NACK_ISRC: //=2
  case I2C_ARDY_ISRC: //=3
  case I2C_SCD_ISRC://=6
  case I2C_AAS_ISRC://=7
  break;
  case I2C_RX_ISRC://=4,接收数据已准备好
  DataReceive();//调用数据接收子函数接收数据
  break;
  case I2C_TX_ISRC://=5,发送数据已准备好
  DataTransmit();//调用数据发送子函数接收数据
  break;
  default:
  asm(“ESTOP0”); //无效数据,则停止
  }
  PieCtrlRegs.PIEACK.all=PIEACK_GROUP8;
  }
  F28015中的数据接收子程序和数据发送子程序是在I2C总线的中断服务程序中根据不同的状态码进行调用,它们是整个通信程序的核心部分。数据接收子程序和数据发送子程序的流程如图8所示。


图8 数据接收和发送子程序

  3 测试结果
  通过NFS文件系统将编译成模块的I2C的总线驱动和设备驱动加载到运行Linux操作系统的S3C2440平台上(先加载总线驱动),再将F28015的测试程序烧写到RAM中。运行F28015等待I2C总线上的数据,再执行Linux系统中的I2C总线测试程序。测试结果显示,芯片通过I2C总线接口完成了数据通信,具有良好的实时性和可靠性。
  4 结论
  该设计利用I2C总线实现了ARM9微控制器与DSP芯片间实时可靠的数据通信。ARM9微控制器结合Linux操作系统作为上层控制核心,DSP芯片实现下层控制算法,可充分发挥ARM9微控制器在数据采集和任务管理等方面的优势以及DSP芯片在算法实现和底层控制的长处。
继承事业,薪火相传
返回列表