קורס:"תכנות בזמן אמת בשפת ++C"
מודם אלחוטי הוא סוג של מערכת תקשורת אלחוטית. דוגמאות נוספות למערכות תקשורת אלחוטיות משובצות מחשב: טלפון סלולרי, מכשירי קשר ניידים, משדרי ומקלטי רדיו, טלפון אלחוטי. לדוגמא, מודם אלחוטי יכול להיות קופסת קשר לוויני המיועדת להעברת מידע בין מחשבים, טלפונים, פקסימיליות וטלוויזיות ע"י תקשורת לווינים:
המודם שבתרשים (Comm. System) מקבל מידע לשידור ממכשיר מסוים להעברה ומשדר אותו למערכת אחרת דרך הלוויין. בערוץ הקליטה המודם מעביר את המידע הנקלט למכשיר המתאים. מבנה לוגי של המודםמודם אלחוטי כלל שתי תת-מערכות עיקריות - משדר ומקלט. כל אחת מתת המערכות מכילה סדרת פעולות המבוצעות על המידע החל מקבלתו ועד לשידורו - במסלול השידור - ובמסלול ההפוך מקליטתו ועד למסירתו ליעד הפלט:
משדר - תת-מערכת הכוללת את המרכיבים הבסיסיים הבאים:
מקלט - תת-מערכת הכוללת את המרכיבים ההפוכים למשדר:
מבנה פיזי של המודםהתרשים הבא מתאר באופן סכמתי את המבנה הפיזי של המערכת:
קווי הבקרה והתזמון מיחידת הבקרה לכל רכיבי המערכת הושמטו בכדי לפשט את השרטוט. הזיכרון (memory) מכיל שני חלקים עיקריים: ה- ROM (Read Only Memory) הוא מקום האחסון של תוכנת המערכת, כלומר של קובץ הביצוע. בהפעלת המכשיר, התוכנה מתחילה להתבצע מכתובת מסוימת ב- ROM. ה- RAM (Raw Access Memory) הוא זיכרון המיועד לפעולות חישוב ולאחסון תוצאות הביניים. המעבד (CPU) היא יחידת החישוב של המערכת. בכל רגע נתון מתבצעת במעבד הוראה אחת מתוך קוד התכנית לביצוע. המעבד קורא את ההוראה הבאה מקטע הקוד (Code segment) ומבצע אותה. יחידת הבקרה והתזמון (Timing & Control unit) היא מרכיב ראשי בתכנון המערכת: היא מספקת את אותות הבקרה והתזמון לרכיבי המערכת השונים. בין היתר היא גם מכניסה פסיקות למעבד עפ"י דרישות התוכנה. יחידה זו ממומשת בדרך כלל ע"י רכיב חומרה מתוכנת.
שאלה: עפ"י התרשים, כיצד ממומש המאפנן (modulator) - בתוכנה או בחומרה? וכיצד ממומש מקודד המקור (source encoder) שבתרשים הלוגי?
חלוקת משימות בין התוכנה והחומרה במערכתמשימות המערכת הנ"ל מבוצעות במתואם ע"י התוכנה והחומרה במערכת. ההחלטה מי מבצע מה תלויה במספר פרמטרים:
הפעלת החומרה ע"י התוכנהמערכת משובצת מחשב מופעלת במשולב ע"י התוכנה והחומרה. התוכנה היא השולטת ומפעילה את כלל המערכת. פעולות עיקריות שמבצעת התוכנה במסגרת זו:
כיצד התוכנה והחומרה "מדברות" ביניהן? קיימים מספר רכיבים המשמשים בהעברת מידע ובקרה בין התוכנה והחומרה:
תוכנת המודםנראה כעת את התוכנה המפעילה את המערכת. תרשים המחלקות:
הסבר: תרשים זה כולל מספר מצומצם וחיוני של מחלקות בתוכנת המודם.
קוד המחלקותקוד המחלקה Register:
class Register
{
public:
enum Mode { // mode of work
NORMAL=0, // normal work: transmit and receive
DEBUG=1, // debug mode
LOOP_BACK=2, // loop-back mode
BIT=3 // Built-In Test mode
};
};
קוד המחלקות ControlReg ו- StatusReg:
class ControlReg : public Register
{
public:
void setInit() { m_init = true; }
void setMode(Mode mode) { m_mode = mode; }
private:
unsigned char m_mode:2;
unsigned char m_init:1; // hardware initialize, atuo-reset
};
class StatusReg : public Register
{
public:
enum BITResult { // Built-In Test (BIT) result
BIT_OK=0, // BIT result OK
RADIO_ERROR=1, // radio unit test error
MEM_ERROR=2, // memory unit test error
FIFO_ERROR=3 // FIFO unit test error
};
int getMode() const { return m_mode; }
int getBITResult() const { return m_BITResult; }
bool isOverflow() const { return m_fifoOverflow; }
bool isUnderflow() const { return m_fifoUnderflow; }
private:
volatile unsigned char m_mode:2;
volatile unsigned char m_BITResult:3;
volatile bool m_fifoOverflow:1;
volatile bool m_fifoUnderflow:1;
};
קוד המחלקה FifoReg:
class FifoReg
{
volatile unsigned char m_data:8;
public:
void setData(int data) { m_data = data; }
int getData() const { return m_data; }
};
וקוד המחלקה הראשית, Modem:
class Modem
{
StatusReg *m_pStatus; ControlReg *m_pControl; FifoReg *m_pTxFifo; FifoReg *m_pRxFifo;
Modem()
{
// set addresses of registers
m_pStatus = reinterpret_cast<StatusReg*> (0xff210980);
m_pControl = reinterpret_cast<ControlReg*> (0xff210984);
m_pTxFifo = reinterpret_cast<FifoReg*> (0xff210988);
m_pRxFifo = reinterpret_cast<FifoReg*> (0xff21098c);
// allocate with placement new
m_pStatus = new (m_pStatus) StatusReg;
m_pControl = new (m_pControl) ControlReg;
m_pTxFifo = new (m_pTxFifo) FifoReg;
m_pRxFifo = new (m_pRxFifo) FifoReg;
m_pControl->setInit(); // init hardware, auto-reset
}
public:
static Modem& instance() // singleton access method
{ static Modem theModem; return theModem; }
int do_BIT() // Built In Test
{
m_pControl->setMode(ControlReg::BIT); // start Built In Test
// wait for BIT end (Polling)
while(m_pStatus->getMode() == StatusReg::BIT)
;
// return BIT result
return m_pStatus->getBITResult();
}
void encode(const char *msg) const {/*...*/}
void decode(const char *msg) const {/*...*/}
void write_to_FIFO(const char *msg, int length)
{
encode(msg);
for(int i=0; i<length; i++) // write to Tx FIFO register
m_pTxFifo->setData(msg[i]);
if(m_pStatus->isOverflow()) // check for overflow
cerr << "Error: Overflow in Tx FIFO" << endl;
}
void read_from_FIFO(const char *msg, int length) const
{
for(int i=0; i<length; i++) // read from Rx FIFO register
msg[i] = (char) m_pRxFifo->getData();
if(m_pStatus->isUnderflow()) // check for underflow
cerr << "Error: Underflow in Rx FIFO" << endl;
else
decode(msg);
}
};
מחלקת היישום, ModemApp:
class ModemApp
{
enum { MSG_SIZE=64, MSGS_NUM=4};
unsigned char m_txBuffer[MSGS_NUM][MSG_SIZE];
unsigned char m_rxBuffer[MSGS_NUM][MSG_SIZE];
ModemApp() {}
public:
static ModemApp& instance()
{ static ModemApp theModemApp; return theModemApp; }
void start_input() { /*...*/ }
void start_output() { /*...*/ }
// main() - demo uses of the Modem application
int main()
{
// do Built In Test
if(Modem::instance().do_BIT() != StatusReg::BIT_OK)
{
cerr << "Error: Hardware BIT error" << endl;
return -1;
}
start_input(); // this process writes the tx buffer
start_output(); // this process reads the rx buffer
// main loop
for(int i=0 ; ; i++) // forever
{
int index = i % MSGS_NUM;
// write tx buffer to tx FIFO
Modem::instance().write_to_FIFO(m_txBuffer[index], MSG_SIZE);
// read rx buffer from rx FIFO
Modem::instance().read_from_FIFO(m_rxBuffer[index], MSG_SIZE);
}
}
};
והפונקציה הראשית, main(), פשוט קוראת ל- ModemApp::main():
int main()
{
return ModemApp::instance().main();
}
|