设置CANlib：事件驱动

Troy
Wed, 30 Sep 2015 16:20:35 +0000

http://v.youku.com/v_show/id_XMTUzNzMzOTIyMA==

这是CANlib开发3篇系列文章的最后一篇：

1. 在Visual Studio中设置CANlib

2. 基础API调用

3. 事件驱动应用程序

CANlib 简介

在我们的上一个视频中，我们演示了如何创建一个控制台应用程序，它可以使用CANlib SDK中提供的基本API调用来配置和读取CAN总线上的报文。 在本视频中，我们将重点介绍如何使循环事件驱动读取更高效。

示例

在前面的示例中，我们使用了Windows C�？刂铺ㄓτ贸绦�。由于我们想在多线程应用程序中显示事件驱动循环，本示例将使用Windows Presentation Foundation程序，其中主线程处理图形用户界面（GUI）以及后台线程从CAN总线读取数据。

我们有一个简单的图形用户界面，一个按钮启动后台线程和一个按钮停止后台线程。我们还添加了一个文本框以显示接收到的报文。我们使用XAML设计了这个GUI。

我们将使用.NET后台工作线程来执行所有的CAN总线操作。这意味着我们必须包括System ComponentModel命名空间，并在创建主窗口时创建后台工作程序。 GUI所要做的就是在按下总线开启按钮时启动后台工作，当按下总线关闭按钮时停止后台工作，并显示后台线程报告的字符串。

我们的后台工作程序将执行ReceiveMessageLoop函数来从CAN总线中检索数据。 像我们前面的例子，我们需要包括canlibCLSNET命名空间和设置云海游戏设备的句柄。我们在InitializeChannel函数中放置了句柄设置指令。 我们初始化库，获取句柄，设置比特率，并使总线上的通道有效。我们还添加了对canIoCtl的调用，以获取一个Windows事件句柄，当驱动程序中发生某些事件时，它将触发。这可能是接收到的报文，报文传输或CAN控制器状态的改变。无论事件触发的原因是什么，你必须清空接收缓冲区，否则不会再获得另一个事件触发器。你会注意到canIoCtl返回的指针必须放在从WaitHandle类派生的类中。要使用WaitHandle类，我们必须包括System.Threading命名空间。

我们现在有一个正确初始化的通道句柄和一个事件句柄，所以回到ReceiveMessageLoop循环，直到GUI请求后台工作程序停止。在循环内，我们使用WaitAny方法等待1秒钟直到事件发生。 如果没有事件发生，我们再次循环。 如果CAN事件触发，我们使用canRead调用循环读取报文，直到该函数指示接收缓冲区为空且具有canERR_NOMSG状态。对于每个报文的消息，我们使用BackgroundWorker类中内置的ReportProgress方法将报文信息传递回GUI。

如果GUI请求后台工作程序停止，我们将退出while循环，进入ReleaseChannel函数，通过使通道处于非活动状态并关闭句柄来执行我们的标准清理。

现在应用程序仍然响应，并且使用较少的CPU资源，因为我们只检查消息以及当CAN事件或用户事件发生时更新显示。请记�。�当使用多线程时，canOpenChannel调用返回的句柄不是线程安全的。因此每个线程必须使用canOpenChannel函数声明自己的物理通道句柄。

CANlib更多信息