新闻中心

EEPW首页>嵌入式系统>设计应用> 嵌入式uClinux下的CAN总线设备驱动程序设计

嵌入式uClinux下的CAN总线设备驱动程序设计

作者: 时间:2013-03-30 来源:网络 收藏

3)定义驱动程序的文件结构

  在LINUX系统中,对硬件设备的访问也是被当作文件来操作的。这里定义的文件接口将可以在外部的应用程序中被调用。在CAN驱动程序中,只定义了读CAN信息(CAN接收)、向CAN节点写信息(CAN发送)、打开CAN设备、关闭CAN设备等4个文件接口。定义信息如下面的程序所示。在sja1000_fops中所定义的函数都必须在驱动程序中编写。

  static struct file_operations sja1000_fops = {

  read: sja1000_read, //CAN接收数据

  write: sja1000_write,//CAN发送

  open: sja1000_open, //打开设备S3C2410开发板II(B)+3.5寸带触摸TFT液晶屏

  release: sja1000_release, };//关闭设备

4)定义sja1000_write :CAN发送函数(写函数)

  static int sja1000_write(struct file *filp, const char *buf, size_t size,

  loff_t *offp){ }

  在控制器Sja1000初始化完成后,即可设置CAN发送,具体对sja1000寄存器的相关操作的相关程序可参阅SJA1000器件的数据手册。

5)定义sja1000_read :CAN接收函数(读函数)

  static int sja1000_read(struct file *filp, char *buf, size_t size,

  loff_t *offp) { }

  该函数完成对网络上相应信息的接收。在本系统中CAN接收采用的是查询方式。

6)编写sja1000_open:文件打开函数

  static int sja1000_open(struct inode *inode,struct file *file) { }S3C2410 开发板II(B)+3.5寸带触摸TFT液晶屏

  进程调用该函数表示对设备的占用。如果返回为-1,表示设备已被其他进程占用,打开非法。如果采用中断方式,对中断的注册也可放在本函数中。

7)编写sja1000_release:文件关闭函数

  static int sja1000_release(struct inode *inode, struct file *file) { }

  该函数进程完成对设备占有权的释放,释放后,其他的进程就可以访问这个设备了。

8)编写sja1000_init(void):void sja1000_init(void) { } CAN设备初始化函数

  该函数完成设备在LINUX内核中的登记。并完成对sja1000初始化。

  Sja1000寄存器配置通过调用上面已写好的sja_write()函数完成。驱动函数登记我们采用的是静态加载的方式,通过调用register_chrdev()完成,程序如下:

  if(result = register_chrdev(254,"sja1000",sja1000_fops)) S3C2410 开发板II(B)+3.5寸带触摸TFT液晶屏

  printk("S3C4510-sja1000: Error %d registering device sja1000", result);

  其中,254是为sja1000设备分配的主设备号,“sja1000”是显示在/dev中的设备名,sja1000_fops为对应的文件系统指针。返回值小于0表示失败,大于或等于0表示成功。

9)将驱动程序加到内核中

  当驱动程序sja1000.c编写完成后,下面的工作就是将它加到内核中了。这需要修改的源代码,然后重新编译uClinux内核。

  ①将程序文件sja1000.c复制到/uClinux-dist/linux/drivers/char目录下。该目录保存了uClinux字符设备的程序。修改该目录下mem.c文件,在Init chrdev_init()函数中增加如下代码:

  #ifdef CONFIG_SJA1000_DRIVER device_init() #endifS3C2410 开发板II(B)+3.5寸带触摸TFT液晶屏

  其中CONFIG_SJA1000_DRIVER是在配置uClinux内核时赋值的。

  ②在uClinux/linux/drivers/char目录下 Makefile中增加如下代码:

  ifeq($(CONFIG_SJA1000_DRIVER,y) L_OBJS+=sja1000.c endif

  如果在配置uClinux内核的时候选择了支持我们定义的设备,则在编译内核的时候会编译sja1000.c,生成 sja1000.o文件。

  ③修改 /uClinux-dist/linux/arch/m68knonunu目录下 config.in文件,在 comment' Character devices’语句下面加上

  bool 'support for sja1000 driver'CONFIG_SJA1000_DRIVERS3C2410 开发板II(B)+3.5寸带触摸TFT液晶屏

  这样,在编译内核,运行make menuconfig的时候,且在配置字符设备时就会有选项:

  support for sja1000 driver 当选中这个选项的时候,就加到内核中了。

  ④在romfs中加上设备驱动程序对应的设备文件。设备文件都被包含在/dev目录下。uClinux中使用的根文件系统是romfs文件系统。这个文件系统是一个只读文件系统,所以设备文件必须在编译内核的时候加到romfs文件系统的image中。

  不同的硬件系统对应不同的设备文件,在/uClinux-dist/vendors目录下,分别定义了它们的Makefile文件。在uClinux-dist/Vendors里S3C4510对应的目录下找到它的Makefile文件,并找到区域DEVICES= tty,c,5,0 console,c,5,1 cua0,c,5,64 cual,c,5,65,在后面再加上设备项 sja1000,c,254,1就行了。

  ③重新编译内核;在shell中将当前目录cd到uClinux-dist目录下,然后:S3C2410 开发板II(B)+3.5寸带触摸TFT液晶屏

  #make menuconfig #make dep #make

  当驱动程序和uClinux内核一起编译链接并生成映像下载到目标板运行以后,可以通过查看/proc/devices,如果已经显示有sja1000,则表明设备加载成功。如果使用了中断,也可以查看/proc/interrupts,该文件记录了当时已经完成的所有系统中断情况。

4、结束语

  实时性方面,可以使用进程间通信如管道、消息队列、共享内存等方法将的接收中断与应用程序直接关联,加快系统对CAN总线事件的响应速度。进一步可以通过RTLinux和RTAI(Real Time Application Interface)这两种方案增强uClinux的实时性。

  本文作者创新点:有效地解决了在没有MMU的CPU之上开发一些简单任务操作系统或控制程序效率低、程序简单的缺点。通过使用嵌入式uClinux,它既保存了原先Linux操作系统稳定性、功能强大等优点,又对内核的代码重新编写,减少了内核容量,提高了效率。同时也提出了在CAN总线设备下设计驱动程序的方法。


上一页 1 2 下一页

评论


相关推荐

技术专区

关闭