⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsp.c

📁 量子编程源代码 量子编程源代码
💻 C
字号:
/****************************************************************************** Product: QDPP example, QK, Large model, Turbo C++ 1.01* Last Updated for Version: 3.3.00* Date of the Last Update:  Jan 22, 2007**                    Q u a n t u m     L e a P s*                    ---------------------------*                    innovating embedded systems** Copyright (c) 2002-2006 Quantum Leaps, LLC. All rights reserved.** Internet: www.quantum-leaps.com     Licensing: sales@quantum-leaps.com** This Software is protected by the United States copyright laws and* international treaties. Distribution of products containing this Software* or based upon this Software (Derivative Works) requires a valid Quantum* Leaps Distribution License. Any other distribution, in source or binary* format is illegal.*****************************************************************************/#include "qf_port.h"#include "qs_port.h"#include "qdpp.h"#include "video.h"#include "qassert.h"#include <stdlib.h>                                          /* for _exit() */Q_DEFINE_THIS_FILE/* Local-scope objects -----------------------------------------------------*/static void interrupt (*l_dosTmrISR)();static void interrupt (*l_dosKbdISR)();#define TMR_VECTOR      0x08#define KBD_VECTOR      0x09#define TMR_ISR_PRIO    (0xFF)#define KBD_ISR_PRIO    (0xFF - 1)/*--------------------------------------------------------------------------*/#ifdef Q_SPYenum QSDppRecords {    QS_PHILO_DISPLAY = QS_USER};static uint16_t l_base;                 /* QS data uplink UART base address */QSTimeCtr QS_tickTime;                           /* keeps timetsamp at tick *//*..........................................................................*/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_base = (uint16_t)0x03F8; break;                 /* COM1 */        case '2': l_base = (uint16_t)0x02F8; break;                 /* COM2 */        case '3': l_base = (uint16_t)0x03E8; break;                 /* COM3 */        case '4': l_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_base + 3, (1 << 7));        /* Set divisor access bit (DLAB) */    outportb(l_base + 0, (uint8_t)baud);                    /* Load divisor */    outportb(l_base + 1, (uint8_t)(baud >> 8));    outportb(l_base + 3, (1 << 1) | (1 << 0));  /* LCR: 8-bits, no p, 1stop */    outportb(l_base + 4, (1 << 3) | (1 << 1) | (1 << 0)); /* DTR, RTS, Out2 */    outportb(l_base + 1, 0);         /* Put UART into the polling FIFO mode */    outportb(l_base + 2, (1 << 2) | (1 << 0));     /* FCR: enable, TX clear */    return (uint8_t)1;                                           /* success */}/*..........................................................................*/uint8_t QS_init(void const *arg) {    static uint8_t qsBuf[1*1024];                 /* buffer for Quantum Spy */    QS_initBuf(qsBuf, sizeof(qsBuf));    return UART_config((char const *)arg, 115200UL);}/*..........................................................................*/void QS_exit(void) {}/*..........................................................................*/QSTimeCtr QS_getTime(void) {              /* invoked with interrupts locked */    static uint32_t l_lastTime;    uint32_t now;    uint16_t count16;                         /* 16-bit count from the 8254 */    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 = QS_tickTime + (0x10000 - count16);    if (l_lastTime > now) {                 /* are we going "back" in time? */        now += 0x10000;               /* assume that there was one rollover */    }    l_lastTime = now;    return (QSTimeCtr)now;}/*..........................................................................*/#define QS_DUMP() \    if ((inportb(l_base + 5) & (1 << 5)) != 0) { \        uint8_t fifo = 16; \        uint16_t b; \        QF_INT_LOCK(igonre); \        while ((fifo != 0) && ((b = QS_getByte()) != QS_EOD)) { \            QF_INT_UNLOCK(igonre); \            outportb(l_base + 0, (uint8_t)b); \            --fifo; \            QF_INT_LOCK(igonre); \        } \        QF_INT_UNLOCK(igonre); \    } else ((void)0)/*..........................................................................*/void QS_flush(void) {    uint16_t b;    while ((b = QS_getByte()) != QS_EOD) { /* next QS trace byte available? */        while ((inportb(l_base + 5) & (1 << 5)) == 0) {/*TX FIFO not empty? */        }        outportb(l_base + 0, (uint8_t)b);  /* stick the byte to the TX FIFO */    }}#endif                                                             /* Q_SPY *//*--------------------------------------------------------------------------*/static void interrupt tmrISR() {    uint8_t pin;    displayPreemptions(QK_currPrio_, TMR_ISR_PRIO);  /* for testing, NOTE01 */    QK_ISR_ENTRY(pin, TMR_ISR_PRIO);#ifdef Q_SPY    QS_tickTime += 0x10000;#endif    QF_tick();                                      /* process armed timers */    QK_ISR_EXIT(pin);}/*..........................................................................*/static void interrupt kbdISR() {    uint8_t pin;    uint8_t key = inport(0x60);/*get scan code from the 8042 kbd controller */    KbdEvt *ke;    displayPreemptions(QK_currPrio_, KBD_ISR_PRIO);  /* for testing, NOTE01 */    QK_ISR_ENTRY(pin, KBD_ISR_PRIO);    ke = Q_NEW(KbdEvt, KBD_SIG);                     /* allocate new KbdEvt */    ke->key = key;                            /* fill the ke->key parameter */    QF_publish((QEvent *)ke);         /* publish the event to the framework */    QK_ISR_EXIT(pin);}/*..........................................................................*/void QF_init(void) {}/*..........................................................................*/void QF_start(void) {                                      /* save the origingal DOS vectors ... */    l_dosTmrISR   = getvect(TMR_VECTOR);    l_dosKbdISR   = getvect(KBD_VECTOR);    QF_INT_LOCK(ignore);                             /* lock the interrupts */    setvect(TMR_VECTOR, &tmrISR);    setvect(KBD_VECTOR, &kbdISR);    QF_INT_UNLOCK(ignore);                         /* unlock the interrupts */}/*..........................................................................*/void QK_onIdle(void) {    QS_DUMP();}/*..........................................................................*/void QF_exit(void) {    QS_EXIT();                                            /* cleanup the QS */    QF_INT_LOCK(ignore);                             /* lock the interrupts */                                    /* restore the original DOS vectors ... */    setvect(TMR_VECTOR, l_dosTmrISR);    setvect(KBD_VECTOR, l_dosKbdISR);    QF_INT_UNLOCK(ignore);                         /* unlock the interrupts */    _exit(0);                                                /* exit to DOS */}/*--------------------------------------------------------------------------*/void Q_assert_handler(char const Q_ROM * const Q_ROM_VAR file, int line) {    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_exit();                                       /* exit and cleanup QF */}/*..........................................................................*/void displyPhilStat(uint8_t n, char const *stat) {    Video_printStrAt(17, 12 + n, VIDEO_FGND_YELLOW, stat);    QS_BEGIN(QS_PHILO_DISPLAY, QS_apObj_); /*application-specific QS record */        QS_U8(1, n);                                  /* philosopher number */        QS_STR(stat);                                 /* philosopher status */    QS_END();}/*..........................................................................*/void displayKey(uint8_t key) {    Video_printNumAt(60, 12 + 0, VIDEO_FGND_YELLOW, key);}/*..........................................................................*/void displayPreemptions(uint8_t pprev, uint8_t pnext) {    if (pnext == TMR_ISR_PRIO) {        static uint32_t tmrIsrCtr;               /* timer interrupt counter */        Video_printNumAt(51, 12 + 1, VIDEO_FGND_YELLOW, ++tmrIsrCtr);    }    else if (pnext == 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 */    }                                              /* is this a task preemption? */    if (((uint8_t)1 <= pprev) && (pprev <= (uint8_t)QF_MAX_ACTIVE)) {        static uint32_t preCtr[QF_MAX_ACTIVE + 1];        Video_printNumAt(30, 12 + (pprev - 1)/10, VIDEO_FGND_YELLOW,                         ++preCtr[pprev]);    }    else if (pprev == (uint8_t)(QF_MAX_ACTIVE + 1)) { /* locked preemption? */        static uint32_t lockPreCtr;  /* locked scheduler preemption counter */        Video_printNumAt(30, 12 + N + 3, VIDEO_FGND_YELLOW, ++lockPreCtr);    }    else if (pprev == KBD_ISR_PRIO) {        /* is this kbg ISR preemption? */        static uint32_t kbdPreCtr;            /* kbd ISR preemption counter */        Video_printNumAt(71, 12 + 0, VIDEO_FGND_YELLOW, ++kbdPreCtr);    }    else if (pprev == TMR_ISR_PRIO) {        /* is this TMR ISR preemption? */        static uint32_t tmrPreCtr;            /* tmr ISR preemption counter */        Video_printNumAt(71, 12 + 1, VIDEO_FGND_YELLOW, ++tmrPreCtr);    }    else {                         /* this must be the idle task preemption */        Q_ASSERT(pprev == (uint8_t)0);    }}/****************************************************************************** NOTE01:* The function call to displayPreemptions() is added only to monitor the* "asynchronous" preemptions within the QK (see Section 4.1 in the "QK/C* Programmer's Manual".** 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 + -