📄 qf_port.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 + -