Interrupt-Driven Serial Communication12-1Embedded SystemsSerial CommunicationLecture 12In these notes . . . Interrupt design guidelinesInterrupt-driven serial I/O device driver design– Interrupt map for system– Enabling interrupts– Queue concepts and implementationEmbedded Systems 12-2Interrupt Design Guidelines(Ganssle, p. 57)Create and Maintain an Interrupt Map– Make a spreadsheet showing interrupts for system, maximum rate, maximum latency allowed. Fill in with execution time measurements during development.– This provides a CPU time budget to follow, and lets us predict worst-case values:• CPU utilization from interrupts•Time interrupts are disabledEmbedded Systems 12-3•Time interrupts are disabledKeep ISRs short. Leave lengthy work to task code when possible. E.g. converting time ticks to H:M:SKeep ISRs so trivially simple that bugs are rare.Fill all unused interrupt vectors with a pointer to a debug routine which hangs and flashes a light. This way you’ll find out about unplanned interrupts immediately.Example Interrupt MapInterrupt Maximum LatencyMaximum FrequencyMaximumDurationActivity DescriptionUART 0 Receiveone character time = 1/1920 = 520.8 µµµµs19200 Hz/10 = 1920 Hzfill in as we develop codeEnqueue received characterUART 0 TransmitNone, but performance 19200 Hz/10 = 1920 Hzfill in as we develop codeDequeue and send outgoing Embedded Systems 12-4Transmitperformance degrades1920 Hzdevelop codesend outgoing characterTimer Overflow1 clock tick = 41 ns24 MHz/65536 = 366.2 Hzfill in as we develop codeIncrement timer extension tchiUART 1 Receiveone character timebaud rate/10UART 1 TransmitNone, but performance degradesbaud rate/10Interrupt Performance ExaminationMeasurement– Use scope to measure duration of tx_isr, rx_isr by examining output bits– Set scope to “infinite persistence” to capture all events– Could also use get_ticks to automate data capturePerformance Prediction– Max. CPU loading from interrupt = max. interrupt frequency * worst-case ISR duration– Min. period between interrupts = 1/max. frequency (if periodic, otherwise need to find minimum interarrival period)– Add up all ISRs which could be requested simultaneously Embedded Systems 12-5automate data captureAnalysis– How long do the ISRs last?– Is there any variation? If so, why?– How long is the delay between receiving a character and sending out the reply?requested simultaneously (critical instant). These delay system response.– Overrun risk: CPU doesn’t finish current ISR before another interrupt of the same typeoccurs– Deadline risk: CPU doesn’t start an ISR before reaching its deadline.If we use a spreadsheet…Serial Communications and InterruptsNow we have three separate threads of control in the program– main program (and subroutines it calls)– Transmit ISR – executes when UART is ready to send another character– Receive ISR – executes when UART receives a characterget_string send_stringMain Program orother threadsEmbedded Systems 12-6UART receives a characterNeed a way of buffering information between threads– Solution: circular queue with head and tail pointers– One for tx, one for rxUARTtx_isrrx_isrEnabling and Connecting Interrupts to ISRsNeed to enable UART’s interrupts: send and receivePage 49: lists many interrupt sources, but nothing says UART!Investigate sfr62p.h instead, search for UART– sxtic and sxric (x = 0, 1, 2) are the interrupt registers for serial communications (UART 0, 1 init_UART0() {init_UART0() {init_UART0() {init_UART0() {…………// code deleted for clarity// code deleted for clarity// code deleted for clarity// code deleted for claritys0ric = 5; // enable UART 0s0ric = 5; // enable UART 0s0ric = 5; // enable UART 0s0ric = 5; // enable UART 0// receive interrupt with// receive interrupt with// receive interrupt with// receive interrupt with// priority 5// priority 5// priority 5// priority 5s0tic = 4; // enable UART 0s0tic = 4; // enable UART 0s0tic = 4; // enable UART 0s0tic = 4; // enable UART 0// transmit interrupt with// transmit interrupt with// transmit interrupt with// transmit interrupt with// priority 4// priority 4// priority 4// priority 4…………}}}}Embedded Systems 12-7communications (UART 0, 1 and 2)Set their priorities to >0 to enable themCreate shells for ISRs, fill in laterDon’t forget to modify interrupt vectors 17 and 18 in sect30.inc to point to u0_tx_isr and u0_rx_isr}}}}#pragma INTERRUPT u0_tx_isr#pragma INTERRUPT u0_tx_isr#pragma INTERRUPT u0_tx_isr#pragma INTERRUPT u0_tx_isrvoid u0_tx_isr() {void u0_tx_isr() {void u0_tx_isr() {void u0_tx_isr() {// add code here!// add code here!// add code here!// add code here!}}}}#pragma INTERRUPT u0_rx_isr#pragma INTERRUPT u0_rx_isr#pragma INTERRUPT u0_rx_isr#pragma INTERRUPT u0_rx_isrvoid u0_rx_isr() {void u0_rx_isr() {void u0_rx_isr() {void u0_rx_isr() {// add code here!// add code here!// add code here!// add code here!}}}}Code to Implement QueuesEnqueue at tail (tail_ptr points to next free entry), dequeue from head (head_ptr points to item to remove)#define the queue size to make it easy to changeOne queue per direction– tx ISR unloads tx_q– rx ISR loads rx_qOther threads (e.g. main) load tx_q and tailheadolder datanewer dataEmbedded Systems 12-8Other threads (e.g. main) load tx_q and unload rx_qNeed to wrap pointer at end of buffer to make it circular, use % (modulus, remainder) operatorQueue is empty if size == 0Queue is full if size == Q_SIZEUARTtx_isrrx_isrget_stringsend_stringDefining the Queues#define Q_SIZE (32)#define Q_SIZE (32)#define Q_SIZE (32)#define Q_SIZE (32)typedef struct {typedef struct {typedef struct {typedef struct {unsigned char Data[Q_SIZE];unsigned char Data[Q_SIZE];unsigned char Data[Q_SIZE];unsigned char Data[Q_SIZE];unsigned int Head; // points to oldest data elementunsigned int Head; // points to oldest data elementunsigned int Head; // points to oldest data elementunsigned int Head; // points to oldest data elementunsigned int Tail; // points to next free space unsigned int Tail; // points to next free space unsigned int Tail; // points to next free space unsigned int Tail; // points to next free space unsigned int Size; // quantity of elements in queueunsigned int Size; // quantity of elements in queueunsigned int Size; // quantity of elements in queueunsigned int Size; // quantity of elements in queue} Q_T;} Q_T;} Q_T;} Q_T;Embedded Systems 12-9Q_T tx_q, rx_q;Q_T tx_q, rx_q;Q_T tx_q, rx_q;Q_T
View Full Document