嵌入式Linux下CAN控制器的驱动程序设计.doc_第1页
嵌入式Linux下CAN控制器的驱动程序设计.doc_第2页
嵌入式Linux下CAN控制器的驱动程序设计.doc_第3页
嵌入式Linux下CAN控制器的驱动程序设计.doc_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第 27 卷 第 21 期计 算机 工 程 与设 计2006 年 11 月V ol . 27 N o. 21 Computer Engineering and DesignNov. 2006嵌入式 Linux 下 CAN 控制器的驱动程序设计陈 祖爵, 周明( 江苏大学 计算 机与通信工程学院,江苏 镇江 212013)摘 要 :嵌 入 式操 作系 统 uClinux 下 扩 展各 类 CAN 总 线设 备 ,需 设计 相应 的驱 动 程序 。MCP2510 为常 用 的 CAN 总 线控 制器 , 以 它为 例,详 细研 究分 析了 嵌 入式 操作 系统 中 设备 管理 和驱 动 程序 的特 点 ,以 及 uClinux 下 CAN 设备 驱动 程序 的 开发 流程 和 技 巧,并结 合 CAN 总 线 技术 的特 点,设 计了 相关 的重 要 数据 结构 和操 作 代码 。最 后介 绍了 把 驱动 程序 编 译添 加进 uClinux 内 核 的方 法,实 现了 CAN 设备 的驱 动。关 键词 :嵌 入 式系 统; CAN 总线 ; uClinux; 设 备驱 动; MCP2510中 图法 分类 号 :TP368.1 文献 标识 码 :A 文章 编 号:1000-7024 (2006) 21-4097-04Driver design of CAN controller in embedded LinuxCHEN Zu-jue,ZHOU Ming(Institute of Computer and Communication Engineering, Jiangsu University, Zhenjiang 212013, China) Abstract:To expand all kinds of CAN devices in the embedded operation system of uClinux should design the corresponding driver. MCP2510 is commonly used CAN controller, taking it for example, the management of the device and characteristic of the driver in the embedded operation system are researched and analyzed in detail, including the development procedure and skill of CAN device driver in the uClinux. The relevant important data structure and operating code is written which is combined the technological characteristic of CAN bus. Finally, the method of compiling and adding the driver into uClinux kernel is introduced, the normal work of CAN devices is realized.Key words:embedded system; CAN bus; uClinux; device driver; MCP25100引言CAN 总线技术是 现今流行 的一种先进 的现场总线 技术, 可 以有效的支 持分布式控 制和实时控 制的串行 通信网络。由 于 CAN 总线具有 通信速率高 ,可靠 性高,连接方便和 性能价 格比高等诸多优点,因此在嵌入式系统开发中有普遍的应用。 目 前,CAN 总线通信 控制芯片 众多,要 在 uClinux 平台 下开发 基 于 CAN 总线的 应用系统,就需要自 己开发 uClinux 下的驱 动 程序。本文 将基于一个 CAN 总线在汽 车电子中的 应用详 细 介绍在 uClinux 下 CAN 总线控 制器驱动 程序的设计 过程。1系 统 硬 件结 构本嵌入式 系统主要 的硬件组成 为:处 理器采用三 星公司 的 S3C44B0X,CAN 总 线控制器和 收发器分别 采用 MicroChip 公 司的 MCP2510 和 MCP2551。开发一 个 uClinux 的驱 动,在 熟悉 uClinux 内核结构之外 ,大量的工作 在于阅读相应 的控制 芯 片手册。硬 件信息决定 驱动的主要 结构。S3C44B0X 采用 的 是 ARM 公司 的 16/32 位 ARM7TDMI 内核 ,它是三星 公司为 一 般应用提供 的高性价比 和高性能的 微控制器 解决方案,特别适 合对成本 和功耗敏感 的应用场合 。MCP2510 是一款 带有符合 工业标准 的 SPI 接口的 CAN 总线控制芯 片,它支持 CAN 技术 规范 V2.0A/B,并 能够发送和 接收标准的 和扩展的 信息 帧,同时具有 接收滤波和 信息管理的 功能。MCP2510 在 目前 市场 上是体积 最小、最易于 使用也是最 节约成本的 独立 CAN 控制 器。MCP2551 是与 MCP2510 相 配的高速 CAN 总线 收发器,它担负着节 点和总线 之间接收和 发送电平转 换的任务 。MCP2510 通过 SPI 接口 与 S3C44B0X 进行 数据传输,最高 数据 传输数率 可达 5 Mb/s。MCP2510 再通过 CAN 收发器 连接 到 CAN 总线 上,CAN 总线上 可以挂接多 个节点,S3C44B0X 通 过 MCP2510 与 CAN 总 线 上 的 其 它 微 处 理 器 进 行 通 信 。 MCP2510 内 含 3 个发送缓 冲区和两 个接收缓冲 区,同时 具有灵活 的中断管 理能力,帧 屏蔽和过滤 、帧优先 级设定等特 性,这使 得微处理 器对 CAN 总线的操 作变得非常 简便。系 统原 理如 图 1 所示。2CAN 总 线应 用 系统 的 软 件设 计2.1 嵌 入式操 作系 统选 择 uClinuxuClinux 是 Linux2.0 版本得一 个分支,被设 计用在微 型控收稿日期:2 005-09-29。作者简介:陈祖爵 (1953 ),男,上海人,副教授,硕士生导师,研究方向为网络技术与嵌入式系统开发应用; 周明 (198 2),男,上海人, 硕士研究生,研究方向为嵌入式系统与计算机网络控制技术。 4097 用户 接口CA N 总线CAN 收发器 MCP2 510 节点控制器S3C44B0 XMCP2 510CAN 收发器外围 存储器CA N 收发器 MCP251 0 节点控制器unsigned char dlc;int IsExt;int rxRTR;CanData;其中 id 为 CAN 消息 ID 号;data 是要传 输的消息 数据,最 大是8 个字节 ;dlc 表 示实际传输 的数据长度 ,取值范 围为 0 到 8; IsExt 是判断 CAN 消息是否 使用扩展 ID;rxRTR 是判断该 消息 是数 据帧还是 远程帧。MCP2510 中有 3 个发送缓冲区,可以循环使用,也可以只 使用一个发送缓冲区,但是必 须保证在发送的时候,前一次的数据 已经发送 结束。两个 接收缓冲 区也是一样 。处理器 通过图 1 嵌入式应用系统结构制 应用领域。uClinux 具 备标准 Linux 系统的稳定 性,并 且支 持 Linux 内核约定的 全部特性 。uClinux 同标准 Linux 的 最大 的 区别就是在 于内存管理 。标准 Linux 是针对 有内存管 理单 元 (memory management unit,MMU) 的处理器设 计的。在 这种 处理 器上,虚拟地址被送到 MMU,MMU 把虚拟地址映 射为物 理 地址。嵌入 式应用对成 本和实时性 敏感,其使用的 CPU 中 有 很多都没有 MMU,例 如本系统采 用的 S3C44B0X 就是 一款 不 带 MMU 的 微处理器 。标准 Linux 无法适用 于这部分 嵌入 式 应用。uClinux 通过对 标准 Linux 中 内存管理的 改写,去掉 了 对 MMU 的依 赖,保存了 Linux 内 核的大多数 优点,因 此它 在 嵌入式应用 中有很好的 前景。uClinux 的应用 主要体现 在驱 动 程序的编写 和上层应用 软件的编写 。所以 ,针对 CAN 总线 控 制器 MCP2510 的 驱动程序 需要我们自 己编写。2.2 CAN 总线 控制 器驱动 程序 编写驱动程序 是应用程 序与硬件之 间的一个中 间软件层。它使 某个特定的 硬件响应一 个定义良好 的内部编 程接口,同时 完 全隐蔽了设 备的工作细 节。用户 通过一组标 准化的调 用来 完成相关操作,这些标准化 的调用是和具体设备驱动无关的, 而驱动程 序的任务就是把这些调用映射到具体设 备对于实际 硬 件的特定操 作上。驱 动程序应该 为应用程序 展现硬件 的所 有功能,不应该强加其它的 约束,对于硬件使用的权限和限制应 该由应用 程序层控 制。驱 动程序设 计主要需 要考虑下 面 3个方面:提供尽量多的选项 给用户;提高驱动程序的速度和效 率 ;尽量使驱 动程序简单 ,使之易于 维护。uClinux 支持的设 备驱动可分 为 3 种:字符 设备,块设 备, 网络接口设备。MCP2510 就属于字符设备。字符设备是 uClinux中 最简单的设 备,所谓 字符设备就 是以字节为 单位逐个 进行I/O 操作的 设备。在 uClinux 中它们 被映射为文 件系统的 一个 节点,这个设备就像是一个 普通文件,应用程序使用标准系统调 用对它进行 打开 (open) 、读取 (read)、写入 (write) 和关闭 (re- lease)等操作。2.2.1 驱 动程 序中定 义的 主要 数据结 构驱动程序 中读写函 数需要传输 多个 CAN 消息,我们 根据CAN 通信 协议和系统 应用的需要 ,设计一 个称为 CanData 的 结 构体来定义 所传输的数 据struct unsigned int id;unsigned char data 8;SPI 接口对 缓存区进行 读取和写入 。MCP2510 对 CAN 总 线的 数据 发送没有 限制,只要 用处理器通 过 SPI 接 口将待发 送的 数据写入 MCP2510 的发送缓存区,然后再调用 RTS(发送请求) 命令 即可将数 据发送到 CAN 总线上。而对 CAN 总线上 的数 据接 收是通过 两个接收缓 冲区,两个接 收屏蔽器 ,6 个接 收过 滤器 的组合来 实现的。CAN 总线上 的帧只有同 时满足至 少任 意一个接 收屏蔽器和一个接收过滤器的条件才可 以进入接收 缓冲 区。这里定义 了一个 MCP2510_REV 的数 据结构,用 于记 录接 收缓冲区 运行的各种 状态struct CanData MCP2510_Candata 128;int nCanRevpos; int nCanReadpos; int loopbackmode;wait_queue_head_t wq;spinlock_t lock; MCP2510_REV;该 结构 中 首 先 定义 了 一 个 接 收缓 冲 区 ,nCanRevpos 和 nCanReadpos 分别 表示接 收缓冲 区和用户 读取缓 冲区数据 的 状态 ;loopbackmode 表示 支持回环模 式,该模式 可使器件 内部 发送 缓冲器和 接受缓冲器 之间进行报 文自发自 收;wq 定 义的是一个等待队列,包含一个锁 变量和一个正在睡眠进程链表,作用 是当有好 几个进程都 在等待某件 事时,uClinux 会把 这些 进程 记录到这 个等待队列 ;lock 定义 的是自旋 锁,自旋锁 是基 于共 享变量来 工作的,函数可以通 过给某个变 量设置一 个特 殊值 来获得锁 。而其它 需要锁的函 数则会循环 查询锁是 否可 用,作用是实现 互斥访问 。2.2.2 驱 动程 序的接 口驱动程序的接口主要分为 3 部分:与设备的接口,完成对 设备的读写等操作;与内核通信的接口,由 file_operations 数据结构完成;与系统启动代码的接口,完成对设备的初始化。uClinux 继承了 Linux 操作系统下用户对设备的访问方式。 设备 驱动与内 核通信时使 用的是设备 类型,主 次设备号 等参数,但是对于应用程序的用户 来说比较难于理解和记忆,所以uClinux 使用 了设 备文 件的 概念。 它抽 象了 对硬 件文 件的 管 理,为用户程 序提供了一 个统一的、抽象的虚 拟文件系统 (vir- tual file system,VFS)界面 。如图 2 所示 ,VFS 主 要由一组 标准的,抽象的 文件操作构 成,以 系统调用 的形式提供 给用户,如open()、release()、read()、write()、ioctl()等。 4098 owner:THIS_MODULE, write:mcp2510_write, read: mcp2510_read, ioctl:mcp2510_ioctl, open: mcp2510_open, release: mcp2510_release,;用户程序VFS设备文件设备驱动物理设备图 2 文件层次结构内核是通过主设备号这个变量将设备驱动程序和设备文 件相连的,而构成驱动程序的一个重要数据结构就是 file_ope- rations,内核就是通 过这个结构 来访问驱动 程序的。file_ope- rations 结构 定义于 linux/fs.h 文件中,它包含指 向驱动程 序内 部 大多数函数 指针,它 的每一个成 员名称对应 着一个系 统调 用 。系统引导 时,内核调 用每一个驱 动程序的 初始化函数 ,将 驱动程序 的主设备号以及程序内部的函数地址结 构的指针传 输 给内核。这 样,内核 就能通过设 备驱动程序 的主设备 号索 引 访问驱动程 序内部的子 程序,完成 打开,读写 等操作。下面 给 出了 file_operations 结构体中 的一些主要 成员struct file_operations struct module *owner;/ module 的 拥有者loff_t (*llseek) (struct file *, loff_t, int);/移动 文件指针 的位 置 ,只能用于 可以随机存 取的设备ssize_t (*write) (struct file *, const char *, size_t, loff_t *);/向 字 符设备中写 入数据ssize_t (*read) (struct file *, char *, size_t, loff_t *);/从 设备 中 读取数据,与 write 类似unsigned int (*poll) (struct file *, struct poll_table_struct *);/用 于查询设 备是否可读 写或处于某 种状态int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);/控制设备 ,除读写操 作外的其它 控制命令int (*mmap) (struct file *, struct vm_area_struct *);/用于 把设 备 的内容映射 到地址空间int (*lock) (struct file *, int, struct file_lock *);/文件锁定 ,用 于 文件共享时 的互斥访问int (*open) (struct inode *, struct file *); /打开设备 进行I/O 操 作int (*release) (struct inode *, struct file *); /关闭设 备并 释 放资源;/file_operations 结构中 的成员全部 是函数指针 ,所 以实 质 上就是函数 跳转表由于在 file_operations 结构 中,每个字段都 必须指向 驱动 程序中实现特定操作 的函数,可以想象,随着内核新功能不断的 增加,file_operations 结构 也就会变 得越开越庞 大。所以 ,现 在 通常采用“标记化”的方法 来为该结 构初始化,即对驱 动中用到的函数记录到相 应字段中,没用到的就不管,这样代码就 精 简了许多。 代码片断如 下static struct file_operations s3c44b0x_fops = 要注意的 是这种表示 方法不是 标准 C 语法,而是 uClinux 下 GNU 编译 器的一种 特殊扩展。 它使用函数 名对各结 构字 段初 始化,好处是结构 清晰,易于理解 ,并且避 免了结构 发生 变 化带来的许 多问题。 上面代码 中,owner 声 明模块的拥 有 者,mcp2510_write 和 mcp_2510_read 负责对缓 冲区读写数 据, mcp2510_open 负责 打开 CAN 总线 控制器,并 清空 3 个发 送缓 冲区 ,mcp2510_release 负责关闭 CAN 总线控制 器,mcp2510_ ioctl 负责 向 CAN 总 线控制器发 送各种控 制命令。mcp2510_ write()代码片段编 写如下static ssize_t mcp2510_write(struct file *file, const char *buf- fer, size_t count, loff_t *ppos)/*filp 为打 开的文件,*buffer 为数据缓存 ,count 为请 求传送数 据长度,*ppos 为用 户在文件 中进行存储 操作的位置char sendbuffersizeof(CanData);if(count=sizeof(CanData)/根据发送数据的长度,以 两种 模式发送 数据copy_from_user(sendbuffer, buffer, sizeof(CanData);/将 数据从应用 数据空间 拷贝到内核MCP2510_canWrite(PCanData)sendbuffer); if(count8) return 0;copy_from_user(sendbuffer, buffer, count);MCP2510_canWriteData(sendbuffer, count);2.2.3 驱 动程 序的初 始化 与设 备注册定义并初 始化完成 file_operations 结构 后,下面必须 定义 一个 初始化函 数,这里我 们定义了一 个名为 mcp2510_init () 的 函数 。在 uClinux 初始 化的时候要 调用该初始 化函数。 初始化函 数要完成 的任务很多 ,主要有以 下几点:(1)初始化 设备相关的 参数。对 MCP2510 来说,这里 主要 完成 CAN 总线波 特率的设置 ,ID 过滤器 的设置,清空接 收和发送 缓冲区,开 启中断等 工作。(2)注册设 备。注册设 备所使用 的函数原型 是int register_chrdev (unsigned int major, const char *name, struct file_operations *fops)其中 major 是主设 备号,name 是设备名 称,fops 就是内核 访问设备 的接口。 前面提到 uClinux 内 核是通过主 设备号将 设备 驱动 程序和设 备文件相连 。uClinux 支持 的主设备 号有限,2.0 以前 版本的内核支持 128 个主设备号 ,在 2.4 版内核中已 经增 加到 256 个。为了 不造成使 用上的混乱 ,对主 设备号的 分配 4099 常 常采用动态 分配的方法 ,即在 用 register_chrdev () 注册 模块 时 ,给 major 参数赋值 为 0,这样系 统就会在所 有未被使 用的 设备号中为我们选定 一个,作为函数的返回值返回给我们。注 册 设备代码片 断编写如下#define DEVICE_NAMEs3c44b0x-mcp2510ret = register_chrdev(0, DEVICE_NAME, &s3c44b0x_fops); (3)注册设 备使用的中 断。因为 中断信号往 往是通过 特定 的 中断信号线 传输的,任何一款芯 片留给中断 信号的接 口都 是有限的,所以内核会维护 一个中断信号线注册表,模块要使 用 中断就得向 它申请一个 中断通道,当它使用 完该通道 之后要 释放该通道 。这里使用 的就是函数request_irq(IRQ_MCP2510, s3c44b0x_isr_mcp2510, SA_IN- TERRUPT, DEVICE_NAME, isr_mcp2510);其中 IRQ_MCP2510 是请求的中断号;s3c44b0x_isr_mcp2510 是中 断处理函数 的指针;SA_INTERRUPT 是一个 与中断管 理有 关的位掩码选项;DEVICE_NAME 是设备名,它被用来在/proc/ interrupts 中显示中断 拥有者;isr_mcp2510 是一 个惟一的 标志符,通过该指针多个设备可 共享信号线,驱动程序也可用它指向 自己的私有 数据区,用 来识别哪个 设备产生了 中断。3设 备 驱 动程 序 的编 译 和 添加在 uClinux 下 ,对驱动程 序的编译添 加一般有 两种方式。 可以静态编译进内核 ,再运 行新的内核来测试;也可以编译成 模 块在运行时 加载。第 1 种 方法效率 较低,但 在某些场 合是 惟 一的方法。 模块方式调 试效率很高 ,它 使用 insmod 工 具将 编译的 模块直接插入内核,如果出现故障 ,可以使用 rmmod 从 内 核中卸载模 块。不需要 重新启动内 核,这使 驱动调试 效率 大 大提高。但 嵌入式系统 是针对具体 应用的,所以一般 采用 将 设备驱动程 序以静态的 方法编译进 内核。具 体步骤如下 : (1) 将驱动 mcp2510.c 添加到/uclinux_dist/linux/drivers/char目 录之下;(2) 修改该目录 下的 mem.c 文件;在 int chr_dev_init() 函数 中 增加如下代 码:#ifdef CONFIG_S3C44B0X_MCP2510 mcp2510_init ();#endif(3)修改该 目录下的 Makefile 文件;增加如下代 码: ifeq ($(CONFIG_S3C44B0X_MCP2510),y) L_OBJS+=mcp2510.oendif(4) 修改 /uclinux_dist/linux/arch/armnommu 目录下 config.in文件 ;在 commentCharacter devices语句下 面加上:boolAdd CAN Controller MCP2510CONFIG_S3C44B0X_MCP2510 (5)编译内核。我们在配置字符设备时就会有选项 Add CAN Controller MCP2510,当选中这个选项的时候,设备驱动就加到 内核中去了。编译成功后,就可以像使用普通文件一样对设备进行操作,在编写的应用程序中先打开设备再读写数据。4结 束 语本文详细 介绍了在嵌 入式操作 系统 uClinux 下 CAN 总线 控制 器 MCP2510 驱动程 序的设计开 发过程。该 驱动程序 根据 CAN 总线的通 讯协议和总 线控制器 MCP2510 的工作特点 ,合 理的 设计了数 据结构和缓 存区控制方 法,并结合 uClinux 下驱 动程序编写的一般规则 ,编写 了相关的操作代码,实践证明该 驱动 程序正确 可行。CAN 总线是一 种广泛应用 的优秀现 场总 线技 术,再借助 源码开放 的 uClinux 在嵌入式开 发中的特 点与 优势 ,开发工作 者就可以 灵活快捷的 开发各类相 关产品。参 考 文献 :1 MicroChip. MCP2510

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论