/* * Send a byte to the UART transmitter, with interrupts disabled. */ void debug_putchar (void *arg, short c) { int x = 0; int in_exception = mips_read_c0_register (C0_STATUS) & (ST_EXL | ST_ERL); if (! in_exception) mips_intr_disable (&x); /* Wait for transmitter holding register empty. */ while (! (UART_LSR & LSR_TX_HOLD_EMPTY)) continue; again: /* Send byte. */ /* TODO: unicode to utf8 conversion. */ UART_THR = c; /* watchdog_alive ();*/ if (debug_onlcr && c == '\n') { /* Wait for transmitter holding register empty. */ while (! (UART_LSR & LSR_TX_HOLD_EMPTY)) continue; c = '\r'; goto again; } if (! in_exception) mips_intr_restore (x); }
/* * Send a byte to the UART transmitter, with interrupts disabled. */ void debug_putchar (void *arg, short c) { int x = 0; int in_exception = mips_read_c0_register (C0_STATUS) & (ST_EXL | ST_ERL); if (! in_exception) mips_intr_disable (&x); /* Wait for transmitter shift register empty. */ while (! (UxSTA & PIC32_USTA_TRMT)) continue; again: /* Send byte. */ /* TODO: unicode to utf8 conversion. */ UxTXREG = c; /* Wait for transmitter shift register empty. */ while (! (UxSTA & PIC32_USTA_TRMT)) continue; /* watchdog_alive ();*/ if (debug_onlcr && c == '\n') { c = '\r'; goto again; } if (! in_exception) mips_intr_restore (x); }
/* * Setup core timer for `hz' timer interrupts per second. */ void clkstart() { unsigned count = mips_read_c0_register (C0_COUNT, 0); mips_write_c0_register (C0_COMPARE, 0, count + (CPU_KHZ * 1000 / HZ + 1) / 2); IECSET(0) = 1 << PIC32_IRQ_CT; }
/* * Проверка прерывания UART. */ void uartx_test_irq () { unsigned cause, errors = 0; UARTX_IER (0) = 0; UARTX_IER (1) = 0; UARTX_IER (2) = 0; udelay (10); cause = mips_read_c0_register (C0_CAUSE); if (cause & CA_IP_IRQ2) { debug_printf ("uartx error: incorrect /IRQ2, cause=%08x\n", cause); ++errors; } UARTX_IER (0) = ~0; UARTX_IER (1) = ~0; UARTX_IER (2) = ~0; udelay (10); cause = mips_read_c0_register (C0_CAUSE); if (! (cause & CA_IP_IRQ2)) { debug_printf ("uartx error: no /IRQ2, cause=%08x\n", cause); ++errors; } UARTX_IER (0) = 0; UARTX_IER (1) = 0; UARTX_IER (2) = 0; udelay (10); cause = mips_read_c0_register (C0_CAUSE); if (cause & CA_IP_IRQ2) { debug_printf ("uartx error: unexpected /IRQ2, cause=%08x\n", cause); ++errors; } if (! errors) { debug_printf ("Testing UART interrupts: OK\n"); } }
/* * Задача выдачи статистики на консоль. */ void console (void *arg) { unsigned t0; for (;;) { t0 = mips_read_c0_register (C0_COUNT); mutex_signal (&mailbox, (void*) t0); debug_puts ("\33[H"); debug_puts ("Measuring task switch time.\n\n"); debug_printf ("Task switches: %u \n\n", nmessages); print_rational (" Latency, min: ", latency_min * 1000, KHZ); print_rational (" max: ", latency_max * 1000, KHZ); } }
/* * Задача приёма сообщений. */ void receiver (void *arg) { unsigned t0, t1, latency; for (;;) { t0 = (unsigned) mutex_wait (&mailbox); t1 = mips_read_c0_register (C0_COUNT); /* Вычисляем количество тактов, затраченных на вход в прерывание. */ latency = t1 - t0; /*debug_printf ("<%u> ", latency);*/ if (++nmessages > 10) { if (latency_min > latency) latency_min = latency; if (latency_max < latency) latency_max = latency; } } }