如何在DOS/C中访问非标准COM端口(USB->;串行、COM5+;)?

如何在DOS/C中访问非标准COM端口(USB->;串行、COM5+;)?,c,usb,serial-port,dos,turbo-c,C,Usb,Serial Port,Dos,Turbo C,我正在使用一个内部软件工具,它显示并记录从我开发嵌入式软件的产品的串行调试端口收集的格式化诊断数据。它是C语言的,非常古老。它使用Borland Turbo-C v1.01(版权所有1990!)构建。如果可能的话,我宁愿修改而不是重写工具以适应现代环境 我想一次从多个设备收集调试数据。我设想了几个设备通过USB->串行适配器连接到集线器,连接到PC(运行Windows XP)。针对每个设备(同样,在Windows中)运行一个诊断工具实例,并指向相应的COM端口。简单,对吗 不完全是。观察我正在使

我正在使用一个内部软件工具,它显示并记录从我开发嵌入式软件的产品的串行调试端口收集的格式化诊断数据。它是C语言的,非常古老。它使用Borland Turbo-C v1.01(版权所有1990!)构建。如果可能的话,我宁愿修改而不是重写工具以适应现代环境

我想一次从多个设备收集调试数据。我设想了几个设备通过USB->串行适配器连接到集线器,连接到PC(运行Windows XP)。针对每个设备(同样,在Windows中)运行一个诊断工具实例,并指向相应的COM端口。简单,对吗

不完全是。观察我正在使用的串行端口初始化功能:

void serinit(int baudrate, char paristat, char adaptnum) {
  int hibcon, lobcon, paricon;
  if(adaptnum == '3') {
    sioreg = lowbaud = 0x3E8;     // SIO (Serial I/O Reg.)
    intenreg = highbaud = 0x3E9;  // IER (Interrupt Enable Reg.)
    intidreg = 0x3EA;             // IIR (Interrupt Ident. Reg.)
    linecon = 0x3EB;              // LCR (Line Control Reg.)
    modemcon = 0x3EC;             // MCR (Modem Control Reg.)
    linestat = 0x3ED;             // LSR (Line Status Reg.)
    modemstat = 0x3EE;            // MSR (Modem Status Reg.)
    sintvect = 0x0C;
    sintmask = 0x10;
  } else if(adaptnum == '2') {
    //omitted for brevity, similar to above w/ different magic numbers
  } else {
    //ditto
  }

  outportb(linecon, 0x80);        // LCR - set up to set baud rate

  switch(baudrate) {
    case 9600:  hibcon = 0x00;  lobcon = 0x0C; break;
    //more magic numbers for other baud rates
  }

  outportb(lowbaud, lobcon);            // Baud Rate Divisor LSB
  outportb(highbaud, hibcon);           // Baud Rate Divisor MSB

  switch(paristat) {
    case 'o': //odd parity, 2 stop, 7 data
    case 'O': paricon = 0x0E; break;
    //more magic numbers for other parity settings
  }

  outportb(linecon, paricon);  //Line Control Register
  outportb(intenreg, 0x01);    //IER - receive enabled
  outportb(modemcon, 0x09);    //x x x x +out2 x -rts +dtr

  imodemcon = 0x09;     //update image
  inportb(sioreg);      //Just in case there's anything lurking in the register
  intvsave = getvect(sintvect);
  setvect(sintvect, serint);   //Set up interrupt vector.
  outportb(0x21, inportb(0x21) & !sintmask); //OCW 1 - enable serial interrupts
}

当USB->串行适配器显示为时,我可以选择哪些选项来调整COM端口5+的这种配置?我可以通过DOS
模式
命令(以及像普通人一样在Windows设备管理器中)看到它们,但我不确定如何从诊断程序访问它们。

如果您运行的是纯DOS,您将仅限于系统上可用的COM端口。请参阅串行端口扩展器的用户手册。它允许您选择最多7个com端口


如果您正在Windows中运行此DOS应用程序,请查看设备管理器中的设备资源。它告诉您的I/O范围将是程序的寄存器地址范围。此网页演示如何查找信息。

直接寻址I/O寄存器需要模拟传统COM端口行为的设备驱动程序。标准的Microsoft设备驱动程序可以做到这一点。但是你没有使用那个驱动程序,你有一个特定于供应商的USB驱动程序

这些驱动程序通过将自身连接到串行端口的标准winapi函数来模拟串行端口。像CreateFile()、SetCommConfig()等等。这需要编写32位代码才能使用这些函数。他们没有做的是模拟寄存器,这样DOS应用程序仍然可以工作,这就结束了。一般来说,DOS只支持4个COM端口,所以在使用过的地方只有4组寄存器。COM5及以上没有标准寄存器地址


也许你可以找到一个USB仿真器,它的驱动程序仍然可以做到这一点。但我认为几率很低。相反,将90年代的软件与90年代的硬件结合起来。买一个老式的PCI卡,把它拧进总线。这样标准的Microsoft驱动程序就可以工作了。虽然挑选的卡片越来越少,但我上次(一年前)看起来很胖的时候,这些卡片仍然可用。或者从旧机器中挖出一个。

超级终端Hilgraeve/Microsoft虚拟化COM1。接着是油灰。DOSBox下一个是serial1/realport。示例::)

此外,许多USB串行适配器并没有实现所有的状态控制行(或正确地实现它们),欢迎使用堆栈溢出!虽然这可以从理论上回答这个问题,但这里要包括答案的基本部分,并提供链接供参考。哇,一些巫术。我只想评论一下,看一下<代码> ChgPuth<代码>命令,将传统COM1映射到COM4到其他编译器。