基于WinCE环境的CAN适配卡驱动程序的设计与实现

2024-05-08 21:18

本文主要是介绍基于WinCE环境的CAN适配卡驱动程序的设计与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.引言

  WinCE是一种为多种嵌入式系统和产品设计的紧凑、高效、可升级的操作系统,WinCE 采用标准模式,其最主要的特征:为有限的硬件资源提供了多线程、多任务和完全优先级的计算环境。

  WinCE操作系统支持两种类型的驱动程序:[1]本地驱动程序(Build-In),是把设备驱动程序作为独立任务实现,直接在顶层任务中实现硬件操作,完成特有专用的驱动程序;流接口驱动程序,WinCE的I/O系统将设备程序作为内核过程实现,这种方式便于实现I/O子系统的层次模型,便于文件系统一起把设备作为特殊文件处理,提供统一的管理、统一的界面和统一的使用方法,并把设备、文件及网络通信组织成为一致的更高层次的抽象,为用户提供统一的系统服务和用户接口。驱动程序封装了将这些命令转换为它所控制的设备上的适当操作所需的全部信息。流接口驱动程序有在启动时加载和动态加载两种方式。本文实现的在WinCE环境下流结构的PC/104-CAN驱动程序是在系统启动时加载的。

  2. CAN总线技术简介

  CAN总线是德国Bosch公司开发的一种串行数据通信协议,CAN总线属于总线式串行通讯网络,具有总线为多主方式工作且无需站地址节点信息、CAN网络上的节点信息分成不同的优先级、总线冲突仲裁时间低和总线的通信介质选择灵活等优点[2]。

  CAN适配卡的核心工作单元是它的控制器,控制器SJA1000的组织结构如图1所示。

SJA1000的内部结构方框图

图1 SJA1000的内部结构方框图

  其中,接口管理逻辑(IML):[3]它接收来自微控制器的命令,控制CAN寄存器的寻址,并向微控制器提供中断和状态信息;发送缓存器:存贮发送到CAN网络上的完整信息;位流处理器(BSP):是一个控制发送缓存器和接收缓存器与CAN总线之间控制数据流的程序装置,同时具有执行错误检测、仲裁、总线填充和错误处理的能力;位定时逻辑(BTL)单元:主要监视串口的CAN总线,并处理与总线有关的位时序,使SJA1000同步于CAN总线上的位流;错误管理逻辑(EML):主要完成接收BSP的出错报告,并按照CAN协议完成错误界定, 从而使BSP和IML进行错误统计。

  CAN适配卡的硬件网络工作环境示意图如图2所示。

CAN适配卡应用系统的总体结构图

图2 CAN适配卡应用系统的总体结构图

  图2 中,通用微机的操作系统是WinCE,上位通用微机通过PC/104总线与CAN接口适配卡相连,CAN接口适配卡与具有CAN接口的串行芯片通过CAN总线进行数据交换,所采用的协议是CAN协议。在CAN协议中,报文的表示、传送和控制主要由4种类型的帧来完成[4]:数据帧,携带数据信息,由发送器发送到接收器;远程帧,主要用于请求发送具有相同标识符的数据帧,是通过总线发送的;出错帧标识总线错误,由检测出总线错误的任何总线单元产生;超载帧主要为当前的和后续的数据帧提供附加延迟。

  3 CAN适配卡驱动程序的设计与实现

  从引言部分可知,流接口可以为各种设备提供统一的访问接口,可以是字符设备、块设备、虚拟设备和网络设备等。CAN适配卡驱动程序的主要流程为[5]:应用程序调用函数CreateFile获取CAN设备句柄,文件系统将会调用CAN驱动例程中的CAN_Open来响应应用程序的请求。当应用程序调用ReadFile函数读取CAN设备上的字符时,文件系统将会调用CAN驱动例程中的CAN_Read函数来读取CAN设备上的字符。

  对于本文流接口的驱动程序而言,是通过实现如下几个模块来实现驱动的:CAN_Open、CAN _Close、CAN _Read、CAN _Write、CAN _IoControl和CAN _Init等模块。其中CAN _Init模块是系统启动时由文件系统自动调用的,主要完成设备的初始化工作。另外,对于流接口驱动程序可选函数CAN _PowerUp和CAN _PowerDown,主要实现电源管理的功能。

  限于篇幅,本文仅对主要的CAN_Write模块、CAN_Read模块和中断服务线程模块的实现作如下详细详细讨论。

  3.1 CAN_Write模

块的实现

  当CAN适配卡控制器在发送报文时,发送缓冲区对写操作是锁定的,这样CPU必须检查状态寄存器的发送缓冲区状态标志TBS,以确定可以将一个新报文写入发送缓冲区中,当发送缓冲区被锁定(即标志TBS=0)时,CPU周期性地查询状态寄存器,等待发送缓冲区被释放;当发送缓冲区被释放(即标志TBS=1)时,CPU将新报文写入发送缓冲区中,并置命令寄存器的发送请求标志TR,该标志导致发送的启动。一旦发送成功中断产生,表明CAN报文已经发送成功。重复上面的工作就可以完成发送多个CAN报文的工作。CAN_Write模块的流程图如图3所示。

CAN

图3 CAN_Write函数的流程图

  如果CAN接收到一个报文,该报文通过验收滤波器验收并放入接收FIFO,则产生一个接收中断。中断服务程序接收到这个中断后,将这个接收到的报文传送到由驱动程序维护的报文存储区中,并置位命令寄存器的释放缓存区标志RRB。CAN_Read函数并不等待来自CAN控制器的接收报文成功中断,而是读取保存在由驱动程序维护的报文存储区中的报文。CAN_Read函数的流程图如图4所示。

CAN

图4 CAN_Read函数的流程图

  3.3中断服务线程模块的实现

  在CAN适配卡的SJA1000控制器中,报文的发送与接受是采用中断方式来完成的。以报文的中断发送为例,在向CAN数据寄存器中写入报文并且向命令寄存器写入发送命令后,系统通过调用WaitForSingleObject函数将当前的发送线程挂起在某个事件的任务队列中,触发该事件将会使系统调度挂起在该事件的任务队列中的任务继续执行,而该事件只有在CAN控制器产生发送成功中断后在中断服务线程中触发。中断服务线程程序流程图如图5所示。

中断服务线程程序流程图

图5 中断服务线程程序流程图

  驱动程序中的另外两个模块主要由CAN_Close 、CAN_IoControl函数来完成,前者主要负责在关闭CAN句柄时资源的回收任务,后者主要用于设置CAN的工作参数,如波特率,报文格式等,在此不作过多介绍。

  4 结束语

  本文的CAN适配卡驱动程序的开发环境:上位机是普通的PC机,下位机的操作系统是WinCE,硬件是深圳蓝天工控有限公司的嵌入式PC/104总线主板PCM3568。驱动程序已经过测试、验收。CAN适配卡驱动程序运行可靠、通信稳定。产品已经被多个产家应用于实际的工业控制领域。

 

这篇关于基于WinCE环境的CAN适配卡驱动程序的设计与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/971459

相关文章

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Java Lettuce 客户端入门到生产的实现步骤

《JavaLettuce客户端入门到生产的实现步骤》本文主要介绍了JavaLettuce客户端入门到生产的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录1 安装依赖MavenGradle2 最小化连接示例3 核心特性速览4 生产环境配置建议5 常见问题

linux ssh如何实现增加访问端口

《linuxssh如何实现增加访问端口》Linux中SSH默认使用22端口,为了增强安全性或满足特定需求,可以通过修改SSH配置来增加或更改SSH访问端口,具体步骤包括修改SSH配置文件、增加或修改... 目录1. 修改 SSH 配置文件2. 增加或修改端口3. 保存并退出编辑器4. 更新防火墙规则使用uf

Java 的ArrayList集合底层实现与最佳实践

《Java的ArrayList集合底层实现与最佳实践》本文主要介绍了Java的ArrayList集合类的核心概念、底层实现、关键成员变量、初始化机制、容量演变、扩容机制、性能分析、核心方法源码解析、... 目录1. 核心概念与底层实现1.1 ArrayList 的本质1.1.1 底层数据结构JDK 1.7

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关