Changeset 215 in xtideuniversalbios for trunk/Serial_Server


Ignore:
Timestamp:
Jan 19, 2012, 9:17:04 AM (12 years ago)
Author:
gregli@…
google:author:
gregli@hotmail.com
Message:

More minor improvements to the serial server, in particular improved timeout recovery.

Location:
trunk/Serial_Server
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Serial_Server/library/Library.h

    r209 r215  
    5353    unsigned char divisor;
    5454    char *display;
    55     char *altSelection;
    5655};
    5756struct baudRate *baudRateMatchString( char *str );
  • trunk/Serial_Server/library/Process.cpp

    r213 r215  
    4848#define SERIAL_COMMAND_HEADERMASK 0xe0
    4949
    50 #define SERIAL_INQUIRE_PORTANDBAUD_BAUD 3
    51 #define SERIAL_INQUIRE_PORTANDBAUD_PORT 0xfc
     50#define SERIAL_INQUIRE_PORTANDBAUD_BAUDMASK 3
     51#define SERIAL_INQUIRE_PORTANDBAUD_PORTMASK 0xfc
     52#define SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT 0x240
     53
     54#define SERIAL_INQUIRE_PORTANDBAUD_PORTTRANSLATE( a ) ( ((a) & SERIAL_INQUIRE_PORTANDBAUD_PORT) << 1 | SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT )
    5255
    5356void logBuff( char *message, unsigned long buffoffset, unsigned long readto, int verboseLevel )
     
    7780    int workOffset, workCount;
    7881
    79     int vtype = 0;
    80 
    8182    unsigned long mylba;
    8283    unsigned long readto;
    8384    unsigned long buffoffset;
    84     int timeout;
    8585    unsigned long lasttick;
    8686    unsigned short crc;
     
    9595    buffoffset = 0;
    9696    readto = 0;
    97     timeout = 0;
    9897    workCount = workOffset = workCommand = 0;
     98
    9999    lasttick = GetTime();
    100100
    101     while( timeout || (len = serial->readCharacters( &buff.b[buffoffset], (readto ? readto-buffoffset : 1) )) )
     101    while( (len = serial->readCharacters( &buff.b[buffoffset], (readto ? readto-buffoffset : 1) )) )
    102102    {
    103103        buffoffset += len;
     
    109109            logBuff( "    Received: ", buffoffset, readto, verboseLevel );
    110110
    111         timeout = 0;
    112 
    113         if( buffoffset != 1 && (timeoutEnabled && GetTime() > lasttick + GetTime_Timeout_Local) )
     111        if( timeoutEnabled && readto && GetTime() > lasttick + GetTime_Timeout_Local )
    114112        {
    115             timeout = 1;
    116             buff.b[0] = buff.b[buffoffset];
    117             buffoffset = 0;
    118             len = 1;
    119             workCount = 0;
    120             log( 1, "Timeout waiting on command" );
    121             continue;
     113            log( 1, "Timeout waiting on data from client, aborting previous command" );
     114
     115            workCount = workOffset = workCommand = 0;
     116            readto = 0;
     117
     118            if( len <= 8 && (buff.b[buffoffset-len] & SERIAL_COMMAND_HEADERMASK) == SERIAL_COMMAND_HEADER )
     119            {
     120                // assume that we are at the front of a new command
     121                //
     122                memcpy( &buff.b[0], &buff.b[buffoffset-len], len );
     123                buffoffset = len;
     124                readto = 8;
     125                // fall through to normal processing
     126            }
     127            else if( len == 1 )
     128            {
     129                // one new character, treat it like any other new character received, discarding the buffer
     130                //
     131                buff.b[0] = buff.b[buffoffset-1];
     132                buffoffset = 1;
     133                // fall through to normal processing
     134            }
     135            else
     136            {
     137                // discard even the newly received data and start listening anew
     138                //
     139                buffoffset = 0;
     140                continue;
     141            }
    122142        }
    123143
     
    127147        // No work currently to do, look at each character as they come in...
    128148        //
    129         if( buffoffset == 1 && !readto )
     149        if( !readto )
    130150        {
    131             if( workCount )
    132             {
    133                 readto = 1;
    134             }
    135             else if( (buff.b[0] & SERIAL_COMMAND_HEADERMASK) == SERIAL_COMMAND_HEADER )
     151            if( (buff.b[0] & SERIAL_COMMAND_HEADERMASK) == SERIAL_COMMAND_HEADER )
    136152            {
    137153                //
     
    193209            workOffset++;
    194210            workCount--;
     211
     212            if( workCount )
     213                readto = 1;           // looking for continuation ACK
    195214        }
    196215
     
    204223            if( workCount )
    205224            {
     225                if( verboseLevel > 1 )
     226                    log( 2, "    Continuation: Offset=%u, Checksum=%04x", workOffset-1, buff.w[256] );
     227
    206228                //
    207229                // Continuation...
     
    221243                if( (crc = checksum( &buff.w[0], 3 )) != buff.w[3] )
    222244                {
    223                     log( 0, "Bad Command Checksum: %02x %02x %02x %02x %02x %02x %02x %02x, Checksum=%02x",
     245                    log( 0, "Bad Command Checksum: %02x %02x %02x %02x %02x %02x %02x %02x, Checksum=%04x",
    224246                         buff.b[0], buff.b[1], buff.b[2], buff.b[3], buff.b[4], buff.b[5], buff.b[6], buff.b[7], crc);
    225247                    continue;
    226248                }
    227249
    228                 if( (buff.inquire.driveAndHead & ATA_DriveAndHead_Drive) )
    229                 {
    230                     if( !image1 )
    231                     {
    232                         log( 1, "Slave drive selected when not supplied" );
    233                         img = NULL;
    234                         continue;
    235                     }
    236                     else
    237                         img = image1;
    238                 }
    239                 else
    240                     img = image0;
     250                img = (buff.inquire.driveAndHead & ATA_DriveAndHead_Drive) ? image1 : image0;
    241251
    242252                workCommand = buff.chs.command & SERIAL_COMMAND_RWMASK;
     
    248258                        | (((unsigned long) buff.lba.bits08) << 8)
    249259                        | ((unsigned long) buff.lba.bits00);
    250                     vtype = 1;
    251260                }
    252261                else
     
    255264                    sect = buff.chs.sector;
    256265                    head = (buff.chs.driveAndHead & ATA_COMMAND_HEADMASK);
    257                     mylba = (((cyl*img->head + head)*img->sect) + sect-1);
    258                     vtype = 2;
    259                 }
    260 
    261                 if( (workCommand & SERIAL_COMMAND_WRITE) && img->readOnly )
    262                 {
    263                     log( 1, "Write attempt to Read Only disk" );
    264                     continue;
     266                    mylba = img ? (((cyl*img->head + head)*img->sect) + sect-1) : 0;
    265267                }
    266268
    267269                workOffset = 0;
    268270                workCount = buff.chs.count;
     271
     272                if( verboseLevel > 0 )
     273                {
     274                    char *comStr = (workCommand & SERIAL_COMMAND_WRITE ? "Write" : "Read");
     275
     276                    if( workCommand == SERIAL_COMMAND_INQUIRE )
     277                        log( 1, "Inquire %d: Client Port=0x%x, Client Baud=%s", img == image0 ? 0 : 1,
     278                             ((buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_PORTMASK) << 1)
     279                             + SERIAL_INQUIRE_PORTANDBAUD_STARTINGPORT,
     280                             baudRateMatchDivisor( buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_BAUDMASK )->display );
     281                    else if( buff.chs.command & ATA_COMMAND_LBA )
     282                        log( 1, "%s %d: LBA=%u, Count=%u", comStr, img == image0 ? 0 : 1,
     283                             mylba, workCount );
     284                    else
     285                        log( 1, "%s %d: Cylinder=%u, Sector=%u, Head=%u, Count=%u, LBA=%u", comStr, img == image0 ? 0 : 1,
     286                             cyl, sect, head, workCount, mylba );
     287                }
     288
     289                if( !img )
     290                {
     291                    log( 1, "    No slave drive provided" );
     292                    workCount = 0;
     293                    continue;
     294                }
     295
     296                if( (workCommand & SERIAL_COMMAND_WRITE) && img->readOnly )
     297                {
     298                    log( 1, "    Write attempt to Read Only disk" );
     299                    workCount = 0;
     300                    continue;
     301                }
     302
    269303                if( verboseLevel > 0 && workCount > 100 )
    270304                    perfTimer = GetTime();
     
    286320                {
    287321                    if( serial->speedEmulation &&
    288                         (buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_BAUD) != serial->baudRate->divisor )
     322                        (buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_BAUDMASK) != serial->baudRate->divisor )
    289323                    {
    290                         struct baudRate *br;
    291 
    292                         br = baudRateMatchDivisor( buff.inquire.portAndBaud & SERIAL_INQUIRE_PORTANDBAUD_BAUD );
    293 
    294                         if( br )
    295                             log( 1, "    Ignoring Inquire with Baud Rate=%d", br->rate );
    296                         else
    297                             log( 1, "    Ignoring Inquire with Unknown Baud Rate (portAndBaud=%d)", buff.inquire.portAndBaud );
     324                        log( 1, "    Ignoring Inquire with wrong baud rate" );
    298325                        workCount = 0;
    299326                        continue;
     
    316343                    log( 0, "Serial Port Write Error" );
    317344
     345                if( verboseLevel >= 3 )
     346                    logBuff( "    Sending: ", 514, 514, verboseLevel );
     347
    318348                workCount--;
    319349                workOffset++;
     350
     351                if( workCount )
     352                    readto = 1;           // looking for continuation ACK
    320353            }
    321354        }
    322355
    323         if( verboseLevel > 0 )
    324         {
    325             char *comStr = (workCommand & SERIAL_COMMAND_WRITE ? "Write" :
    326                             (workCommand & SERIAL_COMMAND_READWRITE ? "Read" : "Inquire"));
    327 
    328             if( vtype == 1 )
    329                 log( 1, "%s %d: LBA=%u, Count=%u", comStr, img == image0 ? 0 : 1,
    330                      mylba, workCount );
    331             else if( vtype == 2 )
    332                 log( 1, "%s %d: Cylinder=%u, Sector=%u, Head=%u, Count=%u, LBA=%u", comStr, img == image0 ? 0 : 1,
    333                      cyl, sect, head, workCount+1, mylba );
    334 
    335             vtype = 0;       
    336 
    337             if( workOffset > 1 )
    338                 log( 2, "    Continuation: Offset=%u, Checksum=%04x", workOffset-1, buff.w[256] );
    339 
    340             if( !(workCommand & SERIAL_COMMAND_WRITE) && verboseLevel >= 3 )
    341                 logBuff( "    Sending: ", 514, 514, verboseLevel );
    342 
    343             if( workCount == 0 && workOffset > 100 )
    344                 log( 1, "    Block Complete: %.2lf bytes per second", (512.0 * workOffset) / (GetTime() - perfTimer) * 1000.0 );
    345         }
     356        if( workCount == 0 && workOffset > 100 )
     357            log( 1, "    Performance: %.2lf bytes per second", (512.0 * workOffset) / (GetTime() - perfTimer) * 1000.0 );
    346358    }
    347359}
  • trunk/Serial_Server/library/Serial.cpp

    r210 r215  
    1212struct baudRate supportedBaudRates[] =
    1313{
    14     {   2400,  0x0,   "2400",   NULL },
    15     {   4800, 0xff,   "4800",   NULL },
    16     {   9600,  0x1,   "9600",   NULL },
    17     {  19200, 0xff,  "19.2K",  "19K" },
    18     {  38400,  0x2,  "38.4K",  "38K" },
    19     {  76800,  0x2,  "76.8K",  "77K" },
    20     { 115200,  0x3, "115.2K", "115K" },
    21     { 153600,  0x3, "153.6K", "154K" },
    22     { 230400, 0xff, "230.4K", "230K" },
    23     { 460800,  0x1, "460.8K", "460K" },
    24     {      0,    0,     NULL,   NULL }
     14    {   2400,  0x0,   "2400" },
     15    {   4800, 0xff,   "4800" },
     16    {   9600,  0x1,   "9600" },
     17    {  19200, 0xff,  "19.2K" },
     18    {  38400,  0x2,  "38.4K" },
     19    {  76800, 0xff,  "76.8K" },
     20    { 115200,  0x3, "115.2K" },
     21    { 153600, 0xff, "153.6K" },
     22    { 230400, 0xff, "230.4K" },
     23    { 460800, 0xff, "460.8K" },
     24    {      0,    0,     NULL }
    2525};
    2626
     
    3333    {
    3434        for( b = supportedBaudRates; b->rate; b++ )
    35             if( b->rate == a )
     35            if( b->rate == a || (b->rate / 1000) == a || ((b->rate + 500) / 1000) == a )
    3636                return( b );
    3737    }
    38 
    39     for( b = supportedBaudRates; b->rate; b++ )
    40         if( !stricmp( str, b->display ) || (b->altSelection && !stricmp( str, b->altSelection )) )
    41             return( b );
    4238
    4339    return( NULL );
  • trunk/Serial_Server/win32/Win32.cpp

    r213 r215  
    4040        "                    With a 4x rate multiplier: 9600, 38400, 153600, 460800",
    4141        "                    Abbreviations also accepted (ie, '460K', '38.4K', etc)",
    42         "                    (default is 9600, 115200 in named pipe mode)",
     42        "                    (default is 38400, 115200 in named pipe mode)",
    4343        "",
    4444        "  -t                Disable timeout, useful for long delays when debugging",
     
    4747        "",
    4848        "  -v [level]        Reporting level 1-6, with increasing information",
     49        "",
     50        "On the client computer, a serial port can be configured for use as a hard disk",
     51        "with xtidecfg.com.  Or one can hold down the ALT key at the end of the normal",
     52        "IDE hard disk scan and the XTIDE Universal BIOS will scan COM1-7, at each of",
     53        "the four speeds given above for BaudRate.  Note that hardware rate multipliers",
     54        "must be taken into account on the server end, but are invisible on the client.",
    4955        NULL };
    5056
     
    6874    Serial *serial;
    6975    Image *img;
    70     struct baudRate *baudRate;
     76    struct baudRate *baudRate = NULL;
    7177
    7278    int timeoutEnabled = 1;
     
    8187    int imagecount = 0;
    8288    Image *images[2] = { NULL, NULL };
    83 
    84     baudRate = baudRateMatchString( "9600" );
    8589
    8690    for( int t = 1; t < argc; t++ )
     
    114118            case 'p': case 'P':
    115119                ComPort = "PIPE";
    116                 baudRate = baudRateMatchString( "115200" );
     120                if( !baudRate )
     121                    baudRate = baudRateMatchString( "115200" );
    117122                break;           
    118123            case 'g': case 'G':
     
    141146                if( !(baudRate = baudRateMatchString( argv[++t] )) )
    142147                {
    143                         fprintf( stderr, "Unknown Baud Rate %s\n\n", argv[t] );
    144                         usage();
     148                    fprintf( stderr, "Unknown Baud Rate %s\n\n", argv[t] );
     149                    usage();
    145150                }
    146151                break;
     
    163168        usage();
    164169
     170    if( !baudRate )
     171        baudRate = baudRateMatchString( "38400" );
     172
    165173    do
    166174    {
  • trunk/Serial_Server/win32/Win32Serial.cpp

    r211 r215  
    5353        if( !ConnectNamedPipe( pipe, NULL ) )
    5454            log( -1, "Could not ConnectNamedPipe" );
     55
     56        if( baudRate->divisor > 3 )
     57            log( -1, "Cannot simulate baud rates with hardware multipliers" );
    5558
    5659        speedEmulation = 1;
Note: See TracChangeset for help on using the changeset viewer.