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

📄 qf_port.cpp

📁 Quantum Platform(QP) is a family of very lightweight, state machine-based frameworks for embedded sy
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////////////// Product: QF/C++ port to x86, uC/OS-II, Turbo C++ 1.01, Large model// Last Updated for Version: 3.2.05// Date of the Last Update:  Dec 08, 2006////                    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.//// This software may be distributed and modified under the terms of the GNU// General Public License version 2 (GPL) as published by the Free Software// Foundation and appearing in the file GPL.TXT included in the packaging of// this file. Please note that GPL Section 2[b] requires that all works based// on this software must also be made publicly available under the terms of// the GPL ("Copyleft").//// Alternatively, this software may be distributed and modified under the// terms of Quantum Leaps commercial licenses, which expressly supersede// the GPL and are specifically designed for licensees interested in// retaining the proprietary status of their code.//// Contact information:// Quantum Leaps Web site:  http://www.quantum-leaps.com// e-mail:                  sales@quantum-leaps.com//////////////////////////////////////////////////////////////////////////////#include "qf_pkg.h"#include "qassert.h"Q_DEFINE_THIS_MODULE(qf_port)// local objects -------------------------------------------------------------static void interrupt (*l_dosTickISR)(...);static void interrupt (*l_dosSpareISR)(...);#define TMR_VECTOR         0x08#define DOS_CHAIN_VECTOR   0x81//............................................................................//lint -e970 -e971               ignore MISRA rules 13 and 14 in this functionconst char *QF::getPortVersion(void) {    return "2.2.05";}//............................................................................void QF::init(void) {    OSInit();                                           // initialize uC/OS-II    l_dosTickISR  = getvect(TMR_VECTOR);    l_dosSpareISR = getvect(uCOS);}//............................................................................void QF::start(void) {                                         // divisor for the 8254 timer/counter    uint16_t count = (uint16_t)(((1193180 * 2) / OS_TICKS_PER_SEC + 1) >> 1);    QF_INT_LOCK_KEY_    QF_INT_LOCK_();                                     // install uC/OS-II context switch vector    setvect(uCOS, (void interrupt (*)(...))OSCtxSw);                // install the original DOS timer vector for uC/OS-II to chain    setvect(DOS_CHAIN_VECTOR, l_dosTickISR);                                           // install the uC/OS-II tick vector    setvect(TMR_VECTOR, (void interrupt (*)(...))OSTickISR);    outportb(0x43, 0x36);             /* use mode-3 for timer 0 in the 8254 */    outportb(0x40, count & 0xFF);              /* load low  byte of timer 0 */    outportb(0x40, (count >> 8) & 0xFF);       /* load high byte of timer 0 */    QF_INT_UNLOCK_();}//............................................................................void QF::run(void) {    OSStart();                               /* start uC/OS-II multitasking */}//............................................................................void QF::exit(void) {    QF_INT_LOCK_KEY_    QF_INT_LOCK_();    outportb(0x43, 0x36);                // use mode-3 for timer 0 in the 8254    outportb(0x40, 0);                            // load low  byte of timer 0    outportb(0x40, 0);                            // load high byte of timer 0    setvect(TMR_VECTOR, l_dosTickISR);      // restore the original DOS vector    setvect(uCOS, l_dosSpareISR);           // restore the original DOS vector    QF_INT_UNLOCK_();    _exit(0);                                                   // exit to DOS}//............................................................................static void run(void *me) {              // use exactly the expected signature    ((QActive *)me)->running_ = (uint8_t)1;    // allow the thread-loop to run    do {                                  // get the next event for this active object        QEvent const *e = ((QActive *)me)->get_();                                         // dispatch to the active object's SM        ((QActive *)me)->QF_ACTIVE_SUPER_::dispatch(e);        QF::gc(e);      // check if the event is garbage, and collect it if so    } while (((QActive *)me)->running_);    ((QActive *)me)->QActive::unsubscribeAll();// unsubscribe from all signals    QF::remove_((QActive *)me);   // remove this object from any subscriptions    OSTaskDel(OS_PRIO_SELF);}//............................................................................void QActive::start(uint8_t prio,                    QEvent const *qSto[], uint32_t qLen,                    void *stkSto, uint32_t stkSize,                    QEvent const *ie){    Q_REQUIRE((qSto != (QEvent *)0) && (stkSto != (void *)0));    int ucosPrio;    eQueue_ = OSQCreate((void **)qSto, qLen);    Q_ASSERT(eQueue_ != (void *)0);                  // uC/OS-II queue created    prio_ = prio;                                       // set the QF priority    QF::add_(this);                     // make QF aware of this active object    ucosPrio = QF_MAX_ACTIVE - prio_;           // map QF priority to uC/OS-II    init(ie);                                // execute the initial transition    Q_ALLEGE(OSTaskCreate(&::run,                     this,                     &(((OS_STK *)stkSto)[(stkSize / sizeof(OS_STK)) - 1]),                     ucosPrio) == OS_NO_ERR);                           // uC/OS task is represented by its unique priority    thread_ = (uint8_t)ucosPrio;}//............................................................................void QActive::postFIFO(QEvent const *e) {    QF_INT_LOCK_KEY_    QF_INT_LOCK_();    if (e->attrQF__ != (uint8_t)0) {        ++((QEvent *)e)->attrQF__;    }    QF_INT_UNLOCK_();    Q_ALLEGE(OSQPost((OS_EVENT *)eQueue_, (void *)e) == OS_NO_ERR);}//............................................................................void QActive::postLIFO(QEvent const *e) {    QF_INT_LOCK_KEY_    QF_INT_LOCK_();    if (e->attrQF__ != (uint8_t)0) {        ++((QEvent *)e)->attrQF__;    }    QF_INT_UNLOCK_();    Q_ALLEGE(OSQPostFront((OS_EVENT *)eQueue_, (void *)e) == OS_NO_ERR);}//............................................................................QEvent const *QActive::get_(void) {    INT8U err;    return (QEvent *)OSQPend((OS_EVENT *)eQueue_, 0, &err);}//............................................................................void QActive::stop(void) {    running_ = (uint8_t)0;   // clear the loop variable used in QActive::run()    INT8U err;    OSQDel(eQueue_, OS_DEL_ALWAYS, &err);        // cleanup the uC/OS-II queue       // make sure posting events to the event queue raises assertion, NOTE01    eQueue_ = (OS_EVENT *)0;}//////////////////////////////////////////////////////////////////////////////// NOTE01:// The qf_port.h file for the uC/OS-II port asserts the error-free posing// of events in the macros QACTIVE_POST_FIFO_(me_) and QACTIVE_POST_LIFO_()// The uC/OS-II message queue functions OSQPost() and OSQPostFront() return// error OS_ERR_PEVENT_NULL when the queue pointer is NULL.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -