在 MCA 8000A 中编写 Linux 驱动程序

Posted

技术标签:

【中文标题】在 MCA 8000A 中编写 Linux 驱动程序【英文标题】:To write Linux driver in MCA 8000A 【发布时间】:2015-06-29 06:59:00 【问题描述】:

该软件已经为 Windows 编写。我在想什么是在 Linux 中编写它的好方法。直接在 Linux 中或更改 Windows 代码。

案例示例是 National Instruments 的 MCA 8000A 驱动程序here,许多人尝试为 Linux 编写但未成功,例如 here,因为当时嵌入更好,应用程序所需的硬件更少,最终目标是 Raspberry Pi here。

我开始通过将 Windows 文件转换为 Linux 来编写它,但我不确定这是否是好方法。

作者在 MCA 8000A 中使用了一些 Linux 驱动程序变体

Certified Scientific Software 部分用户

适用于 Raspberry Pi 的 MCA 8000A Linux 驱动程序计划

以下代码来自 API 中记录的第一个链接。

他们的 Pmcatest.cpp

#include <windows.h>           // Change
#include <stdio.h>
#include "PmcaCom.h"
#include "PmcaErr.h"

static int g_port;
static int g_baudRate;
static int g_gain;
static int g_scale;
static PmcaDeviceType g_device;
static PmcaFlagsType g_flags;
static PmcaStatusType g_status;
static char chBuff[32];
static unsigned long buff[16384];
#define MAX_MEMORY 32768
#define printf0(format) printf(format); fflush(stdout)
#define printf1(format, item) printf(format, item); fflush(stdout)

// command line: test <com port> <baud rate> <device type> <start gain>
// device type 0 - AUTO DETECT, 1 - PMCA 8000, 2 - PMCA 8000A 
int main(int argc, char *argv[])
       
    ...

MicroTime.cpp

#if !defined(AFX_MICROTIME_H__495147C7_F0B7_11D1_B62F_9CFF0CC10000__INCLUDED_)
#define AFX_MICROTIME_H__495147C7_F0B7_11D1_B62F_9CFF0CC10000__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

class MicroTimeType  

    LARGE_INTEGER m_startTime;
    ...
public:
    MicroTimeType();
    LARGE_INTEGER GetCounter();
    ...
;

#endif // !defined(AFX_MICROTIME_H__495147C7_F0B7_11D1_B62F_9CFF0CC10000__INCLUDED_)

队列.cpp

#include "windows.h"
#include "Queue.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

QueueType::QueueType()

    ...


long QueueType::Put(QueueEntryType *entry)

    ...


QueueEntryType *QueueType::Get(void)

    ...


QueueEntryType *QueueType::LockedFind(long id)

   ...
       

QueueEntryType *QueueType::Remove(long id)

   ...

Windows 配置的其他代码

Pmcaex.cpp Request.cpp

如何?

【问题讨论】:

如果您相当熟悉 Windows API 并熟悉 Linux API,那么使用 Windows 应用程序作为 Linux 应用程序的基础是合理的。这完全取决于你的能力和经验。据我所知,该设备只是一个串行端口设备,因此生成一个可以工作的接口应该不难(不,我没有提供帮助!) 【参考方案1】:

打开源代码,我看到有一个名为 dataprot.pdfMCA8000A USB Adapter Protocol.pdf 的文件,它们都详细解释了(数量惊人)数据协议如何在串行 (RS-232) 和 USB 总线上工作作为数据结构 RX'd/TX'd 到 PC 和 MCA;来自dataprot.pdfThe PC acts always as a master while the MCA responds always as a slave. The PC port output signal RTS is used by the PC to indicate the direction of the data transfer. RTS = HIGH indicates data transfer from PC to MCA (mode SEND), while RTS = LOW sets the data transfer direction from MCA to the PC (mode RECEIVE). The MCA constantly monitors the PC RTS line and responds accordingly. The action of the PC depends on the selected mode: SEND or RECEIVE. The DTR and DSR signals are used to synchronize the data streams from/to MCA8000A.

查看源代码本身,我看不出有什么太疯狂而无法移植的东西; __declspec(dllimport/dllexport) 之类的东西可以忽略,WaitForSingleObject 可以替换为pthread_mutex_t(假设pthreads 和用户空间模块,而不是完整的内核驱动程序),使用@987654332 之类的类型可能会出现一些问题@ 和 BYTE 因为它们可能是特定于 Windows 平台的(32/64 位类型),您可能需要将它们替换为 uint64_tunsigned charQueryPerformanceFrequency 之类的东西可以替换为 clock_gettime(CLOCK_MONOTONIC...) ...尽管更深入地研究了源代码,但它似乎除了打开设备的 COM 端口并确保将数据打包在正确的结构中,以便代码用户执行“简单”的事情,例如 @987654338 @ 或 WaitForDsrToggle ..

老实说,您已经拥有了一个串行通信设备和它所规范的数据协议;你不需要去内核,甚至 C 或 C++,a shell scriptand pipe redirection(或任何serial program)将为你完成大量的数据读/写(请注意,如果你坚持文档中的规范)。不过,这确实取决于您的需求;我使用 shell 脚本/管道重定向方法来测试我编写的嵌入式设备驱动程序(编写 C 内核驱动程序,刷新设备,在连接我的 COM 端口的情况下启动它,并等待开始使用我的 shell 脚本对设备进行 bit-banging) .. 不过,我不会“发布”一个 shell 脚本作为驱动程序(如果您希望做的不仅仅是与设备通信)。

希望能有所帮助。

【讨论】:

优秀的答案!你能分享一下你做过的那些shell脚本吗? 我没有“那些”特定的脚本了(收缩..),但是有大量关于从命令行读取 COM 的信息;我已经编辑了我的答案,以包含一些帮助链接。我还添加了minicom 程序通过串行通信的链接,还有setserial 程序.. 真的你只需要插入设备并使用命令行来确保正确同步(波特/等.) 然后在脚本中“自动化”它.. 我的并没有那么复杂,因为它们只为 RX 做一个 while read -r line &lt; /dev/ttyX 和为 TX 做一些 echo "X" &gt; /dev/ttyX 你觉得如何更改Windows头文件windows.h适合Linux?我认为 Linux 没有单射头文件。关于如何更改此头文件的任何教程?【参考方案2】:

对于从 Windows 到 Linux 的数据类型转换,将以下内容添加到您的相应文件中,如 here 所述:

#include <stdint.h>

typedef uint8_t BYTE;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef int64_t LONGLONG;

typedef union _LARGE_INTEGER 
  struct 
    DWORD LowPart;
    LONG  HighPart;
  ;
  struct 
    DWORD LowPart;
    LONG  HighPart;
   u;
  LONGLONG QuadPart;
 LARGE_INTEGER, *PLARGE_INTEGER;

【讨论】:

以上是关于在 MCA 8000A 中编写 Linux 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

Android驱动开发第九章

linux内核,驱动,应用程三者的概念和之间的关系

linux内核,驱动,应用程三者的概念和之间的关系 - Avatarx

Linux 并发与竞争实验

编写Linux驱动与统计单词个数

第六章