📄 chap4.c
字号:
// Chapter 4 6811 C programs// Jonathan W. Valvano// This software accompanies the book,// Embedded Microcomputer Systems: Real Time Interfacing// published by Brooks Cole, 1999// Program 4.3. This C function is nonreentrant because of the read-modify-write access to a global. unsigned int Money; /* bank balance implemented as a global *//* add 100 dollars */void more(void){ Money += 100;}// Program 4.5. This C function is nonreentrant because of the write-read access to a global. int temp; /* global temporary *//* calculate x+2*d */int mac(int x, int d){ temp = x+2*d; /* write to a global variable */ return (temp);} /* read from global */// Program 4.7. This C function is nonreentrant because of the multi-step write access to a global. int info[2]; /* 32-bit global */void set(int x, int y){ info[0]=x; info[1]=y;}// Program 4.11. This C function is reentrant because it disables interrupts during the critical section. int Empty; /* -1 means empty, 0 means it contains something */int Message; /* data to be communicated */int SEND(int data){ int OK;char SaveSP; asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */ OK=0; /* Assume it is not OK */ if(Empty){ Message=data; Empty=0; /* signify it is now contains a message*/ OK=-1;} /* Successfull */ asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(OK);}// Program 4.14. Two pointer implementation of a FIFO. #define FifoSize 10 /* Number of 8 bit data in the Fifo less one */char *PutPt; /* Pointer of where to put next */char *GetPt; /* Pointer of where to get next /* FIFO is empty if PutPt=GetPt */ /* FIFO is full if PutPt+1=GetPt (with wrap) */char Fifo[FifoSize]; /* The statically allocated fifo data */void InitFifo(void) { char SaveSP; asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */ PutPt=GetPt=&Fifo[0]; /* Empty when PutPt=GetPt */ asm(" ldaa %SaveSP\n tap"); /* end critical section */}int PutFifo (char data) { char *Ppt; /* Temporary put pointer */char SaveSP; asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */ Ppt=PutPt; /* Copy of put pointer */ *(Ppt++)=data; /* Try to put data into fifo */ if (Ppt == &Fifo[FifoSize]) Ppt = &Fifo[0]; /* Wrap */ if (Ppt == GetPt ) { asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(0);} /* Failed, fifo was full */ else{ PutPt=Ppt; asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(-1); /* Successful */ }}int GetFifo (char *datapt) { char SaveSP; if (PutPt == GetPt ) { return(0);} /* Empty if PutPt=GetPt */ else{ asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */ *datapt=*(GetPt++); if (GetPt == &Fifo[FifoSize]) GetPt = &Fifo[0]; asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(-1); }}// Program 4.18. C language routines to implement a two pointer with counter FIFO. /* Pointer,counter implementation of the FIFO */#define FifoSize 10 /* Number of 8 bit data in the Fifo */char *PutPt; /* Pointer of where to put next */char *GetPt; /* Pointer of where to get next */unsigned char Size; /* Number of elements currently in the FIFO */ /* FIFO is empty if Size=0 */ /* FIFO is full if Size=FifoSize */char Fifo[FifoSize]; /* The statically allocated fifo data */void InitFifo(void) { char SaveSP; asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/ PutPt=GetPt=&Fifo[0]; /* Empty when Size==0 */ Size=0; asm(" ldaa %SaveSP\n tap"); /* end critical section */}int PutFifo (char data) { char SaveSP; if (Size == FifoSize ) { return(0);} /* Failed, fifo was full */ else{ asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/ Size++; *(PutPt++)=data; /* put data into fifo */ if (PutPt == &Fifo[FifoSize]) PutPt = &Fifo[0]; /* Wrap */ asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(-1); /* Successful */ }}int GetFifo (char *datapt) { char SaveSP; if (Size == 0 ){ return(0);} /* Empty if Size=0 */ else{ asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/ *datapt=*(GetPt++); Size--; if (GetPt == &Fifo[FifoSize]) GetPt = &Fifo[0]; asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(-1); }}// Program 4.22. C implementation of a two index with counter FIFO. /* Index,counter implementation of the FIFO */#define FifoSize 10 /* Number of 8 bit data in the Fifo */unsigned char PutI; /* Index of where to put next */unsigned char GetI; /* Index of where to get next */unsigned char Size; /* Number of elements currently in the FIFO */ /* FIFO is empty if Size=0 */ /* FIFO is full if Size=FifoSize */char Fifo[FifoSize]; /* The statically allocated fifo data */void InitFifo(void) {char SaveSP; asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/ PutI=GetI=Size=0; /* Empty when Size==0 */ asm(" ldaa %SaveSP\n tap"); /* end critical section */}int PutFifo (char data) { char SaveSP; if (Size == FifoSize ) return(0); /* Failed, fifo was full */ else{ asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/ Size++; Fifo[PutI++]=data; /* put data into fifo */ if (PutI == FifoSize) PutI = 0; /* Wrap */ asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(-1); /* Successful */ }}int GetFifo (char *datapt) { char SaveSP; if (Size == 0 ) return(0); /* Empty if Size=0 */ else{ asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/ *datapt=Fifo[GetI++]; Size--; if (GetI == FifoSize) GetI = 0; asm(" ldaa %SaveSP\n tap"); /* end critical section */ return(-1); }}// Program 4.30. Interrupting keyboard software. // MC68HC11A8// PC6-PC0 inputs = keyboard DATA// STRA=STROBE interrupt on risevoid Init(void){ unsigned char dummy;asm(" sei"); PIOC=0x42; // EGA=1, STAI DDRC=0x80; // STRA=STROBE PORTC=0x00; // PC7=0 dummy=PIOC; dummy=PORTCL; InitFifo();asm(" cli");}#pragma interrupt_handler ExtHan()void ExtHan(void){ if((PIOC & STAF)==0)asm(" swi"); PutFifo(PORTCL);} // ack// Program 4.34. C language software interrupt for the printer. // MC68HC11A8// PC6-PC0 outputs = printer DATA// STRA=READY interrupt on rise// STRB=START pulse outunsigned char OK; // 0=busy, 1=doneunsigned char Line[20]; //ASCII dataunsigned char *Pt; // pointer to linevoid Fill(unsigned char *p){ Pt=&Line[0]; while((*Pt++)=(*p++)); // copy Pt=&Line[0]; // initialize pointer OK=0;}unsigned char Get(void){ return(*Pt++);}void Init(unsigned char *thePt){asm(" sei"); // make atomic Fill(thePt); // copy data into global DDRC=0xFF; // Port C outputs PIOC=0x5E; // arm out handshake PORTCL=Get(); // start first asm(" cli");}#pragma interrupt_handler ExtHan()void ExtHan(void){ unsigned char data; if((PIOC & STAF)==0)asm(" swi"); if(data=Get()) PORTCL=data; // start next else{ PIOC=0x1E; // disarm OK=1;}} // line complete // Program 4.36. C language software for the XIRQ interrupt. /* Power System interface XIRQ requested on a rise of TooLow PB0, negative logic pulse, will acknowledge XIRQ PB1=1 will activate backup power */#pragma interrupt_handler PowerLow()void PowerLow(void){ PORTB=2; PORTB=3; } /* Ack, turn on backup power */void Ritual(void){// Port B outputs PORTB=0; PORTB=1; // Make XIRQ=1 asm(" ldaa #0x10\n" " tap");}// Program 4.39. C language implementation of interrupt polling on the 6811 using linked lists. const struct Node{ unsigned char *StatusPt; /* Pointer to status register */ unsigned char Amask; /* And Mask */ unsigned char Cmask; /* Compare Mask */ void (*Handler)(void); /* Handler for this task */ const struct Node *NextPt; /* Link to Next Node */};unsigned char CLdata,PIAAdata,PIABdata;void STRAHan(void){ // regular functions that return (rts) when done CLdata=PORTCL;}void PIAHanA(void){ PIAAdata=ADATA;} void PIAHanB(void){ PIABdata=BDATA;}typedef const struct Node NodeType;typedef NodeType * NodePtr;NodeType sys[3]={ {&PIOC, 0xFF, 0xC0, STRAHan, &sys[1]}, {&ACNT, 0x87, 0x85, PIAHanA, &sys[2]}, {&BCNT, 0x7C, 0x4C, PIAHanB, 0} };#pragma interrupt_handler IRQHan()void IRQHan(void){ NodePtr Pt; unsigned char Status; Pt=&sys[0]; while(Pt){ // executes device handlers for all requests Status=*(Pt->StatusPt); if((Status&(Pt->Amask))==(Pt->Cmask)){ (*Pt->Handler)();} /* Execute handler */ Pt=Pt->NextPt; } } // returns after all devices have been polledvoid main(void){ while(1);} // Program 4.43. C language implementation of round robin polling on the 6811. NodeType sys[3]={ {&PIOC, 0xFF, 0xC0, STRAHan, &sys[1]}, {&ACNT, 0x87, 0x85, PIAHanA, &sys[2]}, {&BCNT, 0x7C, 0x4C, PIAHanB, &sys[0]} };NodePtr Pt=&sys[0]; // points to the one that got polled first at last interrupt#pragma interrupt_handler IRQHan()void IRQHan(void){ unsigned char Counter,Status; Counter=3; // quit after three devices checked Pt=Pt->NextPt; // rotates ABC BCA CAB polling orders while(Counter--){ Status=*(Pt->StatusPt); if((Status&(Pt->Amask))==(Pt->Cmask)){ (*Pt->Handler)();} /* Execute handler */ Pt=Pt->NextPt; } }// Program 4.47. 6811 C language implementation of a periodic interrupt using real time interrupt. unsigned int Time;#pragma interrupt_handler RTIHan()void RTIHan(void){ if((TFLG2&0x4F)!=0x40)asm(" swi"); /* Illegal interrupt */ TFLG2=RTIF; /* Acknowledge by clearing RTIF */ Time++; }void Ritual(void){ asm(" sei"); /* Make ritual atomic */ PACTL=(0xFC&TMSK2)|2; /* Set RTR to 2, 61.035Hz */ TMSK2|=RTII; /* Arm RTI */ Time=0; /* Initialize global data structures */ asm(" cli");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -