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