diff --git a/libs/core/linux.cpp b/libs/core/linux.cpp index f1af78d2..b7322584 100644 --- a/libs/core/linux.cpp +++ b/libs/core/linux.cpp @@ -139,11 +139,24 @@ void sendSerial(const char *data, int len) { sendUsb(USB_SERIAL, data, len); } +volatile bool paniced; +extern "C" void drawPanic(int code); + extern "C" void target_panic(int error_code) { char buf[50]; + paniced = true; + pthread_mutex_trylock(&execMutex); + snprintf(buf, sizeof(buf), "\nPANIC %d\n", error_code); - sendSerial(buf, strlen(buf)); + + drawPanic(error_code); DMESG("PANIC %d", error_code); + + for (int i = 0; i < 10; ++i) { + sendSerial(buf, strlen(buf)); + sleep_core_us(500 * 1000); + } + target_reset(); } @@ -284,12 +297,16 @@ static void *evtDispatcher(void *dummy) { while (true) { pthread_cond_wait(&newEventBroadcast, &eventMutex); while (eventHead != NULL) { + if (paniced) + return 0; Event *ev = eventHead; eventHead = ev->next; if (eventHead == NULL) eventTail = NULL; for (auto thr = allThreads; thr; thr = thr->next) { + if (paniced) + return 0; if (thr->waitSource == 0) continue; if (thr->waitValue != ev->value && thr->waitValue != DEVICE_EVT_ANY) @@ -346,11 +363,15 @@ static void runPoller(Thread *thr) { while (true) { sleep_core_us(us); + if (paniced) + break; TValue curr = pxt::runAction0(query); if (curr != prev) { startUser(); pxt::runAction2(thr->act, prev, curr); stopUser(); + if (paniced) + break; decr(prev); prev = curr; } diff --git a/libs/core/pxt.h b/libs/core/pxt.h index 5d19b6f5..cc218ce0 100644 --- a/libs/core/pxt.h +++ b/libs/core/pxt.h @@ -25,6 +25,7 @@ class MMap : public RefObject { void print(); }; +extern volatile bool paniced; } diff --git a/libs/core/screen.cpp b/libs/core/screen.cpp index e9acdfac..7400a0b1 100644 --- a/libs/core/screen.cpp +++ b/libs/core/screen.cpp @@ -9,7 +9,6 @@ #include #include - /** * Drawing modes */ @@ -265,6 +264,56 @@ void init() { pthread_create(&pid, NULL, screenRefresh, NULL); pthread_detach(pid); } + +static const uint8_t numbers[] = { + 0x06, 0x09, 0x09, 0x09, 0x06, 0x04, 0x06, 0x04, 0x04, 0x0e, 0x07, 0x08, 0x06, 0x01, 0x0f, 0x0f, + 0x08, 0x04, 0x09, 0x06, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x1f, 0x01, 0x0f, 0x10, 0x0f, 0x08, 0x04, + 0x0e, 0x11, 0x0e, 0x1f, 0x08, 0x04, 0x02, 0x01, 0x0e, 0x11, 0x0e, 0x11, 0x0e, 0x0e, 0x11, 0x0e, + 0x04, 0x02, + // face + 0b11011, 0b11011, 0b00000, 0b11111, 0b11011, +}; + +static void drawNumber(int off, int idx) { + const uint8_t *src = &numbers[idx * 5]; + uint8_t *dst = &bitBuffer[off]; + for (int i = 0; i < 5; i++) { + uint8_t ch = *src++; + for (int jj = 0; jj < 8; ++jj) { + for (int j = 0; j < 5; j++) { + if (ch & (1 << j)) + *dst = 0xff; + dst++; + } + dst += ROW_SIZE - 5; + } + } +} + +extern "C" void drawPanic(int code) { + clear(); + + int ptr = ROW_SIZE * 16 + 3 + 6; + drawNumber(ptr, 10); + ptr += 6; + + ptr = ROW_SIZE * 70 + 3; + + drawNumber(ptr, (code / 100) % 10); + ptr += 6; + drawNumber(ptr, (code / 10) % 10); + ptr += 6; + drawNumber(ptr, (code / 1) % 10); + ptr += 6; + + updateLCD(); + + int fd = open("/dev/lms_ui", O_RDWR); + uint8_t cmd[] = { 48 + 5, 0 }; + write(fd, cmd, 2); + close(fd); +} + } namespace pxt {