| 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 | +}
|