質問

I'm working with an in-house software tool that displays & logs formatted diagnostic data collected from the serial debug port of the product I develop embedded software for. It's in C and very old. It's built using Borland Turbo-C v1.01 (copyright 1990!). If possible I'd prefer to modify rather than rewrite the tool for a modern environment.

I want to collect debug data from several devices at once. I'd envisioned several devices connected via USB->Serial adapters to a hub, connected to a PC (running Windows XP). Run one instance of the diagnostic tool per device (again, in Windows), pointed at the appropriate COM port. Easy, right?

Not quite. Observe the serial port initialization function I'm working with:

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
}

What're my options for adapting this kind of configuration for COM ports 5+ as the USB->Serial adapters will show up as? I can see them as expected with the DOS mode command (and in the Windows device manager like a normal human being), but I'm unsure how to access them from the diagnostic program.

役に立ちましたか?

解決

Directly addressing the I/O registers requires a device driver that emulates the behavior of a traditional COM port. The standard Microsoft device driver does this. But you are not using that driver, you've got a vendor specific USB driver.

Those drivers emulate a serial port by wiring themselves into the standard winapi functions for serial ports. Like CreateFile(), SetCommConfig(), etcetera. Which requires writing 32-bit code to use those functions. What they don't do is emulate the registers so DOS apps can still work, that's over and done with. And cannot work in general, DOS only supported 4 COM ports so only 4 sets of registers where ever used. There are no standard register addresses for COM5 and up.

Maybe you can find a USB emulator with a driver that still does this. But I'd consider the odds very low. Instead, marry your '90s software to '90s hardware. Buy an old-fashioned PCI card that you screw into the bus. So that the standard Microsoft driver works. Those cards were still available last time I looked (fat year ago) although pickings were getting slim. Or dig one out of an old machine.

他のヒント

If you're running pure DOS, you'll be limited to the COM ports available on the system. Take a look at the user manual for this serial port expander. It lets you choose com ports up to 7.

If you're running this DOS application within Windows, take a look at the device's resources in Device Manager. The I/O Range it tells you will be the register address range for your program. This webpage demonstrates demonstrates finding the information.

HyperTerminal Hilgraeve/Microsoft virtualized COM1. PuTTY followed. DOSBox next with serial1/realport. Example: http://www.prosefights.org/irp2014/ganssle.htm#14510USB :)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top