| Index: embios/trunk/console.c | 
| — | — | @@ -41,11 +41,13 @@ | 
| 42 | 42 |  | 
| 43 | 43 |  | 
| 44 | 44 | struct mutex console_mutex; | 
|  | 45 | +struct mutex console_readmutex; | 
| 45 | 46 |  | 
| 46 | 47 |  | 
| 47 | 48 | void console_init() | 
| 48 | 49 | { | 
| 49 | 50 | mutex_init(&console_mutex); | 
|  | 51 | +    mutex_init(&console_readmutex); | 
| 50 | 52 | } | 
| 51 | 53 |  | 
| 52 | 54 | void cputc_internal(unsigned int consoles, char string) ICODE_ATTR; | 
| — | — | @@ -123,3 +125,34 @@ | 
| 124 | 126 | if (consoles & 1) lcdconsole_update(); | 
| 125 | 127 | mutex_unlock(&console_mutex); | 
| 126 | 128 | } | 
|  | 129 | + | 
|  | 130 | +int cgetc(unsigned int consoles, int timeout) | 
|  | 131 | +{ | 
|  | 132 | +    int result; | 
|  | 133 | +    mutex_lock(&console_readmutex, TIMEOUT_BLOCK); | 
|  | 134 | +    if ((consoles & 2) && (result = dbgconsole_getc(timeout)) != -1) return result; | 
|  | 135 | +    mutex_unlock(&console_mutex); | 
|  | 136 | +} | 
|  | 137 | + | 
|  | 138 | +int cread(unsigned int consoles, char* buffer, size_t length, int timeout) | 
|  | 139 | +{ | 
|  | 140 | +    int result; | 
|  | 141 | +    mutex_lock(&console_readmutex, TIMEOUT_BLOCK); | 
|  | 142 | +    if ((consoles & 2) && (result = dbgconsole_read(buffer, length, timeout))) return result; | 
|  | 143 | +    mutex_unlock(&console_mutex); | 
|  | 144 | +} | 
|  | 145 | + | 
|  | 146 | +void creada(unsigned int consoles, char* buffer, size_t length, int timeout) | 
|  | 147 | +{ | 
|  | 148 | +    int result; | 
|  | 149 | +    mutex_lock(&console_readmutex, TIMEOUT_BLOCK); | 
|  | 150 | +    while (length) | 
|  | 151 | +    { | 
|  | 152 | +        if (length && (consoles & 2) && (result = dbgconsole_read(buffer, length, timeout))) | 
|  | 153 | +        { | 
|  | 154 | +            buffer = &buffer[result]; | 
|  | 155 | +            length -= result; | 
|  | 156 | +        } | 
|  | 157 | +    } | 
|  | 158 | +    mutex_unlock(&console_mutex); | 
|  | 159 | +} | 
| Index: embios/trunk/console.h | 
| — | — | @@ -36,6 +36,9 @@ | 
| 37 | 37 | int cprintf(unsigned int consoles, const char* fmt, ...) ICODE_ATTR; | 
| 38 | 38 | int cvprintf(unsigned int consoles, const char* fmt, va_list ap) ICODE_ATTR; | 
| 39 | 39 | void cflush(unsigned int consoles) ICODE_ATTR; | 
|  | 40 | +int cgetc(unsigned int consoles, int timeout) ICODE_ATTR; | 
|  | 41 | +int cread(unsigned int consoles, char* buffer, size_t length, int timeout) ICODE_ATTR; | 
|  | 42 | +void creada(unsigned int consoles, char* buffer, size_t length, int timeout) ICODE_ATTR; | 
| 40 | 43 |  | 
| 41 | 44 |  | 
| 42 | 45 | #endif | 
| Index: embios/trunk/usb/usb.c | 
| — | — | @@ -354,7 +354,6 @@ | 
| 355 | 355 | break; | 
| 356 | 356 | case 10:  // READ CONSOLE | 
| 357 | 357 | dbgconsoleattached = true; | 
| 358 |  | -            wakeup_signal(&dbgconsendwakeup);
 | 
| 359 | 358 | int bytes = dbgconsendwriteidx - dbgconsendreadidx; | 
| 360 | 359 | if (bytes >= sizeof(dbgconsendbuf)) bytes -= sizeof(dbgconsendbuf); | 
| 361 | 360 | if (bytes) | 
| — | — | @@ -373,6 +372,7 @@ | 
| 374 | 373 | } | 
| 375 | 374 | if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes); | 
| 376 | 375 | dbgconsendreadidx += readbytes; | 
|  | 376 | +                wakeup_signal(&dbgconsendwakeup); | 
| 377 | 377 | } | 
| 378 | 378 | dbgsendbuf[0] = 1; | 
| 379 | 379 | dbgsendbuf[1] = bytes; | 
| — | — | @@ -380,6 +380,32 @@ | 
| 381 | 381 | dbgsendbuf[3] = dbgconsendwriteidx - dbgconsendreadidx; | 
| 382 | 382 | size = 16 + dbgrecvbuf[1]; | 
| 383 | 383 | break; | 
|  | 384 | +        case 11:  // WRITE CONSOLE | 
|  | 385 | +            bytes = dbgconrecvreadidx - dbgconrecvwriteidx - 1; | 
|  | 386 | +            if (bytes < 0) bytes += sizeof(dbgconrecvbuf); | 
|  | 387 | +            if (bytes) | 
|  | 388 | +            { | 
|  | 389 | +                if (bytes > dbgrecvbuf[1]) bytes = dbgrecvbuf[1]; | 
|  | 390 | +                int writebytes = bytes; | 
|  | 391 | +                char* readptr = (char*)&dbgrecvbuf[4]; | 
|  | 392 | +                if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf)) | 
|  | 393 | +                { | 
|  | 394 | +                    writebytes = sizeof(dbgconrecvbuf) - dbgconrecvwriteidx; | 
|  | 395 | +                    memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes); | 
|  | 396 | +                    dbgconrecvwriteidx = 0; | 
|  | 397 | +                    readptr = &readptr[writebytes]; | 
|  | 398 | +                    writebytes = bytes - writebytes; | 
|  | 399 | +                } | 
|  | 400 | +                if (writebytes) memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes); | 
|  | 401 | +                dbgconrecvwriteidx += writebytes; | 
|  | 402 | +                wakeup_signal(&dbgconrecvwakeup); | 
|  | 403 | +            } | 
|  | 404 | +            dbgsendbuf[0] = 1; | 
|  | 405 | +            dbgsendbuf[1] = bytes; | 
|  | 406 | +            dbgsendbuf[2] = sizeof(dbgconrecvbuf); | 
|  | 407 | +            dbgsendbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1; | 
|  | 408 | +            size = 16; | 
|  | 409 | +            break; | 
| 384 | 410 | default: | 
| 385 | 411 | dbgsendbuf[0] = 2; | 
| 386 | 412 | size = 16; | 
| — | — | @@ -525,3 +551,58 @@ | 
| 526 | 552 | { | 
| 527 | 553 | dbgconsole_write(string, strlen(string)); | 
| 528 | 554 | } | 
|  | 555 | + | 
|  | 556 | +int dbgconsole_getavailable() ICODE_ATTR; | 
|  | 557 | +int dbgconsole_getavailable() | 
|  | 558 | +{ | 
|  | 559 | +    int available = dbgconrecvwriteidx - dbgconrecvreadidx; | 
|  | 560 | +    if (available < 0) available += sizeof(dbgconrecvbuf); | 
|  | 561 | +    return available; | 
|  | 562 | +} | 
|  | 563 | + | 
|  | 564 | +int dbgconsole_getc(int timeout) | 
|  | 565 | +{ | 
|  | 566 | +    if (!dbgconsole_getavailable()) | 
|  | 567 | +    { | 
|  | 568 | +        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE); | 
|  | 569 | +        if (!dbgconsole_getavailable()) | 
|  | 570 | +        { | 
|  | 571 | +            wakeup_wait(&dbgconrecvwakeup, timeout); | 
|  | 572 | +            if (!dbgconsole_getavailable()) return -1; | 
|  | 573 | +        } | 
|  | 574 | +    } | 
|  | 575 | +    int byte = dbgconrecvbuf[dbgconrecvreadidx++]; | 
|  | 576 | +    if (dbgconrecvreadidx >= sizeof(dbgconrecvbuf)) | 
|  | 577 | +        dbgconrecvreadidx -= sizeof(dbgconrecvbuf); | 
|  | 578 | +    return byte; | 
|  | 579 | +} | 
|  | 580 | + | 
|  | 581 | +int dbgconsole_read(char* buffer, size_t length, int timeout) | 
|  | 582 | +{ | 
|  | 583 | +    if (!length) return 0; | 
|  | 584 | +    int available = dbgconsole_getavailable(); | 
|  | 585 | +    if (!available) | 
|  | 586 | +    { | 
|  | 587 | +        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE); | 
|  | 588 | +        int available = dbgconsole_getavailable(); | 
|  | 589 | +        if (!available) | 
|  | 590 | +        { | 
|  | 591 | +            wakeup_wait(&dbgconrecvwakeup, timeout); | 
|  | 592 | +            int available = dbgconsole_getavailable(); | 
|  | 593 | +            if (!available) return 0; | 
|  | 594 | +        } | 
|  | 595 | +    } | 
|  | 596 | +    if (available > length) available = length; | 
|  | 597 | +    int left = available; | 
|  | 598 | +    if (dbgconrecvreadidx + available >= sizeof(dbgconrecvbuf)) | 
|  | 599 | +    { | 
|  | 600 | +        int bytes = sizeof(dbgconrecvbuf) - dbgconrecvreadidx; | 
|  | 601 | +        memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], bytes); | 
|  | 602 | +        dbgconrecvreadidx = 0; | 
|  | 603 | +        buffer = &buffer[bytes]; | 
|  | 604 | +        left -= bytes; | 
|  | 605 | +    } | 
|  | 606 | +    if (left) memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], left); | 
|  | 607 | +    dbgconrecvreadidx += left; | 
|  | 608 | +    return available; | 
|  | 609 | +} |