📄 bsp.c
字号:
Video_printStrAt(42, 11, VIDEO_FGND_RED, "ISR Calls Data Preemptions"); for (n = 0; n < N_PHILO; ++n) { Video_printStrAt( 1, 12 + n, VIDEO_FGND_WHITE, "Philosopher"); Video_printNumAt(12, 12 + n, VIDEO_FGND_WHITE, n); } Video_printStrAt( 1, 12 + N_PHILO, VIDEO_FGND_WHITE, "Table"); Video_printStrAt(17, 12 + N_PHILO, VIDEO_FGND_YELLOW, "serving"); Video_printStrAt(42, 12 + 0, VIDEO_FGND_WHITE, "kbdISR"); Video_printStrAt(42, 12 + 1, VIDEO_FGND_WHITE, "tmrISR"); Video_printStrAt(10, 23, VIDEO_FGND_BLUE, "* Copyright (c) Quantum Leaps, LLC * www.quantum-leaps.com *"); Video_printStrAt(28, 24, VIDEO_FGND_LIGHT_RED, "<< Press Esc to quit >>");}/*..........................................................................*/void BSP_displyPhilStat(uint8_t n, char const *stat) { Video_printStrAt(17, 12 + n, VIDEO_FGND_YELLOW, stat); QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */ QS_U8(1, n); /* Philosopher number */ QS_STR(stat); /* Philosopher status */ QS_END()}/*..........................................................................*/void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) { QF_INT_LOCK(dummy); /* cut-off all interrupts */ Video_clearRect ( 0, 24, 80, 25, VIDEO_BGND_RED); Video_printStrAt( 0, 24, VIDEO_FGND_WHITE, "ASSERTION FAILED in file:"); Video_printStrAt(26, 24, VIDEO_FGND_YELLOW, file); Video_printStrAt(57, 24, VIDEO_FGND_WHITE, "line:"); Video_printNumAt(62, 24, VIDEO_FGND_YELLOW, line); QF_stop();}/*..........................................................................*/void BSP_busyDelay(void) { /* for testing */ uint32_t volatile i = l_delay << 4; while (i-- > 0UL) { /* busy-wait loop */ }}/*..........................................................................*/void dispPreemptions(uint8_t pisr) { /* for testing, see NOTE01 */ if (pisr == TMR_ISR_PRIO) { static uint32_t tmrIsrCtr; /* timer interrupt counter */ Video_printNumAt(51, 12 + 1, VIDEO_FGND_YELLOW, ++tmrIsrCtr); } else if (pisr == KBD_ISR_PRIO) { static uint32_t kbdIsrCtr; /* kbd interrupt counter */ Video_printNumAt(51, 12 + 0, VIDEO_FGND_YELLOW, ++kbdIsrCtr); } else { Q_ERROR(); /* unexpected interrupt priority */ } if (QK_intNest_ == (uint8_t)0) { /* is this a task preemption? */ if (QK_currPrio_ > (uint8_t)0) { static uint32_t preCtr[QF_MAX_ACTIVE + 1]; Video_printNumAt(30, 12 + QK_currPrio_ - 1, VIDEO_FGND_YELLOW, ++preCtr[QK_currPrio_]); } } else if (QK_intNest_ == (uint8_t)1) { /* this is an ISR preemption */ if (pisr == TMR_ISR_PRIO) { /* TMR_ISR preempting KBD_ISR? */ static uint32_t kbdPreCtr; /* kbd ISR preemption counter */ Video_printNumAt(71, 12 + 0, VIDEO_FGND_YELLOW, ++kbdPreCtr); } else { static uint32_t tmrPreCtr; /* tmr ISR preemption counter */ Video_printNumAt(71, 12 + 1, VIDEO_FGND_YELLOW, ++tmrPreCtr); } } else { Q_ERROR(); /* impossible ISR nesting level with just 2 ISRs */ }}/*--------------------------------------------------------------------------*/void lib1_reent_init(uint8_t prio) { impure_ptr1->x = (double)prio * (M_PI / 6.0);}/*..........................................................................*/void lib1_test(void) { uint32_t volatile i = l_delay; while (i-- > 0UL) { double volatile r = sin(impure_ptr1->x) * sin(impure_ptr1->x) + cos(impure_ptr1->x) * cos(impure_ptr1->x); Q_ASSERT(fabs(r - 1.0) < 1e-99); }}/*--------------------------------------------------------------------------*/void lib2_reent_init(uint8_t prio) { impure_ptr2->y = (double)prio * (M_PI / 6.0) + M_PI;}/*..........................................................................*/void lib2_test(void) { uint32_t volatile i = l_delay; while (i-- > 0UL) { double volatile r = sin(impure_ptr2->y) * sin(impure_ptr2->y) + cos(impure_ptr2->y) * cos(impure_ptr2->y); Q_ASSERT(fabs(r - 1.0) < 1e-99); }}/*--------------------------------------------------------------------------*/#ifdef Q_SPY /* define QS callbacks *//*..........................................................................*/static uint8_t UART_config(char const *comName, uint32_t baud) { switch (comName[3]) { /* Set the base address of the COMx port */ case '1': l_uart_base = (uint16_t)0x03F8; break; /* COM1 */ case '2': l_uart_base = (uint16_t)0x02F8; break; /* COM2 */ case '3': l_uart_base = (uint16_t)0x03E8; break; /* COM3 */ case '4': l_uart_base = (uint16_t)0x02E8; break; /* COM4 */ default: return (uint8_t)0; /* COM port out of range failure */ } baud = (uint16_t)(115200UL / baud); /* divisor for baud rate */ outportb(l_uart_base + 3, (1 << 7)); /* Set divisor access bit (DLAB) */ outportb(l_uart_base + 0, (uint8_t)baud); /* Load divisor */ outportb(l_uart_base + 1, (uint8_t)(baud >> 8)); outportb(l_uart_base + 3, (1 << 1) | (1 << 0));/* LCR:8-bits,no p,1stop */ outportb(l_uart_base + 4, (1 << 3) | (1 << 1) | (1 << 0));/*DTR,RTS,Out2*/ outportb(l_uart_base + 1, 0); /* Put UART into the polling FIFO mode */ outportb(l_uart_base + 2, (1 << 2) | (1 << 0));/* FCR: enable, TX clear */ return (uint8_t)1; /* success */}/*..........................................................................*/uint8_t QS_onStartup(void const *arg) { static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ QS_initBuf(qsBuf, sizeof(qsBuf)); return UART_config((char const *)arg, 115200UL);}/*..........................................................................*/void QS_onCleanup(void) {}/*..........................................................................*/QSTimeCtr QS_onGetTime(void) { /* invoked with interrupts locked */ uint32_t now; uint16_t count16; /* 16-bit count from the 8254 */ if (l_tickTime != 0) { /* time tick has started? */ outportb(0x43, 0); /* latch the 8254's counter-0 count */ count16 = (uint16_t)inportb(0x40);/* read the low byte of counter-0 */ count16 += ((uint16_t)inportb(0x40) << 8); /* add on the hi byte */ now = l_tickTime + (0x10000 - count16); if (l_lastTime > now) { /* are we going "back" in time? */ now += 0x10000; /* assume that there was one rollover */ } l_lastTime = now; } else { now = 0; } return (QSTimeCtr)now;}/*..........................................................................*/void QS_onFlush(void) { uint16_t fifo = UART_16550_TXFIFO_DEPTH; /* 16550 Tx FIFO depth */ uint8_t const *block; QF_INT_LOCK(dummy); while ((block = QS_getBlock(&fifo)) != (uint8_t *)0) { QF_INT_UNLOCK(dummy); /* busy-wait until TX FIFO empty */ while ((inportb(l_uart_base + 5) & (1 << 5)) == 0) { } while (fifo-- != 0) { /* any bytes in the block? */ outportb(l_uart_base + 0, *block++); } fifo = UART_16550_TXFIFO_DEPTH; /* re-load 16550 Tx FIFO depth */ QF_INT_LOCK(dummy); } QF_INT_UNLOCK(dummy);}#endif /* Q_SPY *//*--------------------------------------------------------------------------*//****************************************************************************** NOTE01:* The function call to displayPreemptions() is added only to monitor the* "asynchronous" preemptions within the QK.** NOTE02:* The call to busyDelay() (see main.c) is added only to extend the execution* time of the code to increase the chance of an "asynchronous" preemption.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -